如何让 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 组件:imageavatar(导入 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 意识到你只是在使用来自 TreeshakingTestModuleAvatar

所以你需要在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 模块?的主要内容,如果未能解决你的问题,请参考以下文章

webpack4x高级概念

webpack高级概念(treeShaking按环境打包code SplittingSplitChunksPluginPreLoadingPrefetchingCSS分割shimmin)

第1364期Webpack之treeShaking

webpack 4+正确配置purgecss css代码treeshaking

Webpack 的 Tree Shaking

webpack进阶用法你都get到了么?