Rollup客户端打包文件混入不必要Node内置模块代码问题咨询
问题描述
我的Rollup打包后的浏览器bundle顶部自动加入了一堆Node内置模块的import语句,但这些模块并没有在入口文件src/client.tsx中直接使用,想知道这是不是Rollup的默认引入行为?
生成的冗余代码如下:
import require$$0$b from 'events'; import require$$0$6 from 'url'; import require$$1$3 from 'util'; import require$$1$2 from 'fs'; import require$$0$8 from 'http'; import require$$1$1 from 'https'; import require$$3$1 from 'zlib'; import require$$0$7 from 'stream'; import require$$4$1 from 'dns'; import require$$2$2 from 'net'; import require$$6$1 from 'os'; import require$$0$9 from 'path'; import require$$0$a from 'crypto'; import 'tls'; import require$$0$c from 'child_process'; import require$$0$d from 'buffer'; import require$$1$4 from 'string_decoder'; import require$$8 from 'querystring';
我的Rollup配置文件:
import typescript from '@rollup/plugin-typescript' import { nodeResolve } from '@rollup/plugin-node-resolve' import commonjs from '@rollup/plugin-commonjs' import json from "@rollup/plugin-json" export default { input: 'src/client.tsx', output: { dir: 'dist/public', format: 'esm', }, preserveEntrySignatures: false, context: "window", plugins: [ nodeResolve({ browser: true }), commonjs(), json(), typescript({ target: "ES2017", module: "esnext", outDir: "dist/public", }) ] }
原因分析
这些Node内置模块不是Rollup默认引入的,核心原因是你项目中某个第三方依赖(或依赖的子依赖)在代码里引用了这些Node模块。虽然你配置了nodeResolve({ browser: true }),这个选项会尝试加载模块的浏览器兼容版本,但如果某个依赖没有提供对应的浏览器适配代码,Rollup就会引入这些Node模块的空shim或者基础实现,最终出现在bundle里。
解决方案
1. 定位引入根源
安装rollup-plugin-visualizer分析依赖树,找出哪个包触发了这些Node模块的引入:
npm install rollup-plugin-visualizer --save-dev
在Rollup配置的plugins中添加:
import { visualizer } from 'rollup-plugin-visualizer'; // ... 其他plugins visualizer({ open: true })
运行打包后会自动打开可视化报告,在报告里可以追踪到这些Node模块被哪个依赖引用。
2. 优化nodeResolve配置
修改nodeResolve的配置,添加preferBuiltins: false,让Rollup优先选择浏览器端的替代实现,而不是默认使用Node内置模块:
nodeResolve({ browser: true, preferBuiltins: false })
3. 剔除冗余模块(按需)
如果确认某些Node模块完全不需要,可以使用rollup-plugin-terser配合严格的tree-shaking来移除未被实际使用的代码:
- 安装依赖:
npm install rollup-plugin-terser --save-dev
- 添加到plugins:
import { terser } from 'rollup-plugin-terser'; // ... 其他plugins terser()
4. 按需引入polyfill(如果必须)
如果依赖确实需要某些Node模块的浏览器兼容版,可以使用rollup-plugin-node-polyfills提供对应的polyfill,但注意不要盲目引入,避免增加bundle体积:
npm install rollup-plugin-node-polyfills --save-dev
添加到plugins:
import nodePolyfills from 'rollup-plugin-node-polyfills'; // ... 其他plugins nodePolyfills()
内容的提问来源于stack exchange,提问作者prmph

