首页 > 解决方案 > 如何让 webpack treeshake 我的 ES6 模块?

问题描述

我已经按照那里的每个指南在 webpack 4 中打开 tree shaking 了,但是 webpack 仍然捆绑了我设置为 treeshaken 的 NPM 模块中的代码。如何启用 treeshaking 并且不在我的 Web 应用程序中包含特定代码?

GitHub 存储库中的完整源代码

我有一个 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 包的默认导出确实导出了组件,但是我阅读了解释说即使默认导出和重新导出仍然可以在树抖动的情况下使用的教程,如果从不使用导出的内容。

怎么了?我究竟做错了什么?

GitHub 存储库中的完整源代码

标签: javascriptnode.jsreactjswebpack

解决方案


据我所知,webpack 三是通过静态分析导入来实现的,而不是通过阅读您的代码。你不能指望 webpack 意识到你只是在使用Avatarfrom TreeshakingTestModule

因此,您需要通过使用命名导入和导出来声明要在import级别使用的内容:

import {Avatar} from 'treeshaking-test-module'

function App() {
  return (
    <div className="App">
      <Avatar />
    </div>
  );
}

所以 webpack 知道你只是在使用Avatar导出。

这意味着Avatar需要在您的treeshaking-test-module模块中命名导出。


推荐阅读