要构建支持Tree-shaking的JavaScript工具库,需遵循以下核心原则:使用ES模块语法、避免副作用、配置package.json的module和exports字段,并通过Rollup等工具构建。 具体步骤如下:
一、使用ES模块语法Tree-shaking依赖静态导入/导出机制,必须使用import和export语法,禁止使用CommonJS(require/module.exports)。
- 错误示例:module.exports = { foo, bar }; // CommonJS语法,无法被Tree-shaking
- 正确做法:export const foo = () => { /* ... */ };export const bar = () => { /* ... */ }; // 每个函数单独导出
二、避免副作用副作用指模块导入时自动执行的逻辑(如修改全局对象、直接运行函数等),会导致打包工具放弃Tree-shaking优化。需确保入口文件仅做导出操作。
三、配置package.json通过字段明确模块类型,支持不同环境(Node.js和浏览器)的Tree-shaking。
- 关键字段:
main:指向CommonJS版本(兼容Node.js)。
module:指向ES模块版本(用于Tree-shaking)。
exports:条件导出,更精确控制模块解析(推荐使用)。
- 示例配置:{ "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "exports": { ".": { "import": "./dist/index.esm.js", "require": "./dist/index.cjs.js" } }, "sideEffects": false // 或指定副作用文件列表}
四、使用Rollup构建Rollup对库优化友好,天然支持Tree-shaking。配置要点如下:
- 输出格式设为es:output: { file: 'dist/index.esm.js', format: 'es' // 生成ES模块}
- 外部化依赖:通过external字段排除第三方库(如lodash),避免被打包进库中:external: ['lodash']
- 启用Tree-shaking:Rollup默认开启treeshake: true,无需额外配置。
- 完整rollup.config.js示例:export default { input: 'src/index.js', output: { file: 'dist/index.esm.js', format: 'es' }, external: ['lodash'], // 排除第三方依赖 treeshake: true // 显式声明(默认已开启)};
五、验证Tree-shaking效果- 构建测试项目:创建一个新项目,安装你的工具库作为依赖。
- 按需导入函数:import { foo } from 'your-library'; // 仅导入foo
- 检查打包结果:
使用Webpack或Rollup打包后,分析输出文件是否仅包含foo的代码。
若bar未被打包,说明Tree-shaking生效。
六、注意事项- 代码分割:若库包含复杂逻辑,可通过动态导入(import())实现按需加载,进一步优化体积。
- TypeScript支持:若使用TypeScript,需在tsconfig.json中设置"module": "ESNext",并确保编译后输出ES模块。
- 文档说明:在库的README中明确标注支持Tree-shaking,并提供按需导入的示例代码。
通过以上步骤,可确保工具库被下游项目有效Tree-shaking,减少最终打包体积。核心原则是静态导出、无副作用、正确配置模块字段,并借助现代工具链构建。