如何在Next.js中启用tree shaking以移除依赖中的未使用死代码
Next.js tree shaking未生效问题原因及解决方案
核心原因
- 导出代码的副作用判定问题:webpack的tree shaking分为两步:第一步识别未使用的导出(也就是你看到的
/* unused harmony exports bar */标记),第二步删除无用代码。第二步执行的前提是webpack确认未使用的导出对应的代码没有副作用。你示例中直接导出对象字面量的写法,webpack默认会判定对象创建操作可能存在副作用,因此不会主动删除这段代码。 - 模块格式问题:如果你的依赖库是CommonJS格式,webpack无法做静态导出分析,也会导致tree shaking失效,只有ESM格式的模块支持完整的tree shaking能力。
- 未声明模块副作用属性:如果你的library是独立的依赖包,没有在package.json中声明
sideEffects字段,webpack默认会假设整个包的代码都可能存在副作用,不会执行激进的死代码移除。
修复方案
- 声明模块无副作用
在library的package.json中添加配置,明确告知webpack该包无副作用,可以安全删除未使用代码:
{ "sideEffects": false }
如果包内存在确实有副作用的文件(比如全局样式引入、全局变量注册类文件),可以配置为数组形式,仅排除对应文件:
{ "sideEffects": ["*.css", "./src/global-*.js"] }
- 添加纯代码标记
对于确定无副作用的导出值,可以在定义前添加/*#__PURE__*/注释标记,强制告诉webpack该段代码无副作用,未引用可直接删除:
// library.js export const foo = /*#__PURE__*/ {foo:"foo"} export const bar = /*#__PURE__*/ {bar:"bar"}
- 调整Next.js构建配置(可选)
Next.js生产环境默认已经开启tree shaking,你也可以在next.config.js中手动加固相关配置,确保客户端构建生效:
/** @type {import('next').NextConfig} */ const nextConfig = { webpack: (config, { isServer }) => { // 仅针对客户端构建调整优化规则 if (!isServer) { // 开启导出使用分析 config.optimization.usedExports = true // 开启副作用分析 config.optimization.sideEffects = true } return config } } module.exports = nextConfig
- 确保模块为ESM格式
检查你的library输出格式为ESM,不要编译为CommonJS。可以在library的package.json中添加"type": "module"配置,确保输出产物为ES模块格式。
内容的提问来源于stack exchange,提问作者Jon Lauridsen
相关产品推荐
相关产品推荐

