webpack中treeshaking如何配置,如何转换cjs等
- 引用 11 篇资料作为参考
- webpack5 配置 13(性能优化)Tree shaking Http压缩 html压缩, runtime压缩, 封装library-CSDN博客
- 使用webpack4配置tree-shaking - CSDN文库
- Webpack Tree Shaking 技术原理及应用实战,优化代码,精简产物
- Webpack5 系列(五):Tree Shaking
- Webpack 实现 Tree shaking 的前世今生
- 教你彻底搞懂ESM与CJS互相转换-CSDN博客
- 有没有库,可以在前端进行import(esm引入)的方式引入:cjs模块? - SegmentFault 思否
- 本想搞清楚ESM和CJS模块的互相转换问题,没想到写完我的问题更多了-腾讯云开发者社区-腾讯云
- Webpack Module Resolution 机制说明与配置技巧-CSDN博客
- webpack-Module Resolution(模块解析) - Sunsin - 博客园
- Webpack 2-解析node_module的问题 - 腾讯云开发者社区 - 腾讯云
以下是Webpack中Tree Shaking的配置方法及CommonJS(CJS)模块转换的详细指南,结合实践要点和原理说明:
🌲 一、Tree Shaking配置
Tree Shaking依赖ES模块(ESM)的静态分析,需满足两个条件:
- 使用ESM语法:代码中必须使用import/export,而非require/module.exports。
- 生产模式:在webpack.config.js中设置mode: ‘production’(默认启用Tree Shaking)。
核心配置步骤:
- 启用usedExports(标记未使用代码):
// webpack.config.js
module.exports = {mode: 'production',optimization: {usedExports: true, // 标记未使用的导出}
};
- 此步骤会标记未使用的导出,但不会删除代码,需配合压缩工具(如Terser)移除。
- 配置sideEffects(声明无副作用模块):
在package.json中声明哪些模块无副作用,可安全删除:
{"name": "my-project","sideEffects": false // 所有模块均无副作用
}
- 例外处理:对有副作用的文件(如CSS、全局JS)需显式声明:```json
{
“sideEffects”: [“.css", ".global.js”]
}
- 或在Webpack规则中标记:```javascript
module: {rules: [{test: /\.css$/,use: ["style-loader", "css-loader"],sideEffects: true // 防止CSS被删除}]
}
- CSS Tree Shaking:
使用purgecss-webpack-plugin删除未使用的CSS:
const PurgeCSSPlugin = require('purgecss-webpack-plugin');
const glob = require('glob');plugins: [new PurgeCSSPlugin({paths: glob.sync(`${path.join(__dirname, 'src')}/**/*`, { nodir: true }),safelist: ['body', 'safe-class'] // 保留特定选择器})
]
🔄 二、CommonJS(CJS)模块转换
Tree Shaking仅支持ESM,需将CJS转换为ESM:
转换方案:
- 使用插件转换CJS为ESM:
- Webpack:通过@rollup/plugin-commonjs(需配合babel-loader):
// webpack.config.js
const commonjs = require(‘@rollup/plugin-commonjs’);
module.exports = {
plugins: [commonjs()]
};
- Rollup:直接使用@rollup/plugin-commonjs。
2. 避免混用导出方式:- CJS的module.exports与ESM的export default混用会导致转换后出现.default访问问题。- 最佳实践:统一使用命名导出(Named Exports):```javascript
// CJS写法(推荐)
exports.funcA = () => {};
exports.funcB = () => {};// ESM引入
import { funcA } from './module';
- 动态导入限制:
Tree Shaking无法优化动态导入(如import()),因其依赖运行时分析。静态导入才能被有效优化。
⚠️ 三、注意事项
- 第三方库支持:
- 确保使用的库提供ESM版本(如Lodash ES版本)。
- 避免整体导入:
import _ from 'lodash'; // ❌ 无法Tree Shaking
import { debounce } from 'lodash'; // ✅ 按需引入
- Babel配置:
- 禁用ESM转CJS(保留ESM静态结构):
// .babelrc
{"presets": [["@babel/preset-env", { "modules": false }] // 保留ESM]
}
- 副作用检测:
- 避免在模块顶层执行全局副作用操作(如window.jQuery = …),否则会被错误保留。
💎 总结
⚙️ 实践口诀:
- ESM是基础:代码中强制使用import/export;
- 生产模式不能省:mode: 'production’自动启用优化;
- 副作用声明要谨慎:全局文件需豁免,避免误删;
- CJS转换靠工具:插件转换+命名导出规避路径问题。
通过合理配置,Tree Shaking可减少30%~50%的打包体积,显著提升应用性能。