如何让 webpack treeshake 我的 ES6 模块?
Posted
技术标签:
【中文标题】如何让 webpack treeshake 我的 ES6 模块?【英文标题】:How can I make webpack treeshake my ES6 module? 【发布时间】:2019-10-15 22:17:11 【问题描述】:我已按照那里的所有指南在 webpack 4 中启用 tree shaking,但 webpack 仍然捆绑来自我已设置为 treeshaken 的 NPM 模块的代码。如何启用 treeshaking 并且不在我的网络应用程序中包含特定代码?
Full source code in GitHub repo
我有一个 CRA(create-react-app),它导入我创建的 NPM 模块来测试它,如下所示:
package
index.mjs
dist
esm
components
image
index.js
index.js
index.js
package.json
像这样:
"main": "index",
"module": "index.jsm",
"sideEffects": false,
使用带有 babelrc 的 babel 进行编译,例如:
"presets": [
[
"@babel/preset-env",
"modules": false
],
"@babel/react",
"@babel/flow"
]
我有 3 个 React 组件:image
、avatar
(导入 image
)和 login-button
,它们有这个 es6 代码:
import React from 'react'
document.body.innerhtml = document.body.innerHTML + "<div>This is a side effect and should never have happened</div>"
export default () => <button>Login</button>
NPM es6 模块的索引文件:
import * as lib from './dist/esm'
export default lib
在 CRA 的 app.js
我有:
import TreeshakingTestModule from 'treeshaking-test-module'
function App()
return (
<div className="App">
<TreeshakingTestModule.Avatar />
</div>
);
当我npm start
时,它会构建并渲染头像,但我也看到了消息。
请注意,login-button
从未使用过,但是我的 NPM 包的默认导出确实导出了组件,但是我阅读了解释说即使默认导出和重新导出仍然可以使用摇树摇晃的教程,如果什么是从不使用导出的。
发生了什么?我做错了什么?
Full source code in GitHub repo
【问题讨论】:
【参考方案1】:据我所知,webpack 三是通过静态分析导入而不是通过阅读您的代码来实现的。你不能指望 webpack 意识到你只是在使用来自 TreeshakingTestModule
的 Avatar
。
所以你需要在import
级别声明你想要使用的东西,通过使用命名的导入和导出:
import Avatar from 'treeshaking-test-module'
function App()
return (
<div className="App">
<Avatar />
</div>
);
所以 webpack 知道你只使用了 Avatar
导出。
这意味着Avatar
需要是您的treeshaking-test-module
模块中的命名导出。
【讨论】:
感谢您的回答,但没有奏效。我重构为使用命名导入(index.mjs
从每个组件重新导出),但它仍然包含我的副作用。代码:github.com/jared-hexagon/treeshaking-test/compare/import-named
没关系-我在做npm start
。 Treeshaking 仅在为生产构建时启用 (npm run build
)。这行得通 - 当我使用命名导入时,我没有看到副作用。以上是关于如何让 webpack treeshake 我的 ES6 模块?的主要内容,如果未能解决你的问题,请参考以下文章
webpack高级概念(treeShaking按环境打包code SplittingSplitChunksPluginPreLoadingPrefetchingCSS分割shimmin)