如何让Rollup打包npm包的node导出而非browser导出?
问题描述
正在使用Rollup为Node.js应用打包TypeScript代码,引入了clipboardy这个npm包,它的package.json中定义了两个导出:
"type": "module", "exports": { "node": "./index.js", "default": "./browser.js" }
希望导入其中的index.js,但打包后发现Rollup使用了browser.js的代码,这在Node.js环境中无法运行。
现有配置
Rollup配置
import { nodeResolve } from '@rollup/plugin-node-resolve'; import json from '@rollup/plugin-json'; import commonjs from '@rollup/plugin-commonjs'; import typescript from '@rollup/plugin-typescript'; export default { input: 'src/main.ts', output: { dir: 'dist', format: 'cjs' }, external: ["robotjs", "onnxruntime-node"], plugins: [typescript(), nodeResolve({preferBuiltins: true}), json(), commonjs()] };
tsconfig.json配置
{ "compilerOptions": { "target": "ESNext", "module": "ESNext", "esModuleInterop": true, "moduleResolution": "node", "sourceMap": true, "outDir": "dist", "strict": true } }
项目根目录的package.json已设置"type": "module",需要解决如何让Rollup使用clipboardy包的node导出的问题。
解决方案
配置nodeResolve插件的导出条件
修改Rollup配置中的nodeResolve插件选项,添加exportConditions: ['node'],让Rollup优先匹配针对Node.js环境的导出分支:nodeResolve({ preferBuiltins: true, exportConditions: ['node'] // 新增该行 })这个配置会明确告诉Rollup解析包时优先选用
package.json里exports字段下的node导出。同步TypeScript的模块解析配置
调整tsconfig.json的module和moduleResolution为NodeNext,让TypeScript的模块解析逻辑和Node.js/Rollup保持一致,避免编译和打包阶段的导出选择冲突:{ "compilerOptions": { "target": "ESNext", "module": "NodeNext", "moduleResolution": "NodeNext", "esModuleInterop": true, "sourceMap": true, "outDir": "dist", "strict": true } }直接指定导入路径(临时 workaround)
如果上述配置仍不生效,可以在代码里直接导入clipboardy的node版本文件:import clipboard from 'clipboardy/index.js';这种方式绕过导出条件匹配逻辑,直接引入目标文件,但需要注意如果包的内部结构发生变化,代码需要同步调整。
内容的提问来源于stack exchange,提问作者Abdallah Youssef
相关产品推荐
相关产品推荐

