Webpack 3,Babel和Tree摇晃不起作用

Mil*_*zor 12 webpack babeljs tree-shaking webpack-3

我正试图找到一种方法来破坏我的模块并使用Babel和Webpack.

如果我从webpack文档(https://webpack.js.org/guides/tree-shaking/)获取示例代码并运行它,那么未使用的模块/函数/其他导出将被标记为未使用的和谐导出,这是预期的结果.在使用-p参数(生产)运行webpack之后,webpack使用UglifyJS删除死的和未使用的代码(到树抖动).

现在,如果我将babel-loader添加到我的webpack配置文件中,我的ES2015模块将被转换,但现在不再标记为未使用的导出.

例如:

math.js

export function square(x) {
  return x * x;
}

export function cube(x) {
  return x * x * x;
}
Run Code Online (Sandbox Code Playgroud)

app.js(我的条目文件)

import {square} from './math.js'
Run Code Online (Sandbox Code Playgroud)

通过webpack运行,没有 babel-loader,该cube函数将被标记为未使用并在编译生产后删除(-p).

通过带有 babel-loader的webpack运行,该cube函数将不会被标记为未使用,并将保留在已编译的包中.

我错过了什么?

编辑

这是一个可以重现这种情况的演示回购

https://github.com/Milanzor/babel-and-treeshaking-question

更新

如果我添加.babelrc:

{
  "presets": [
    ["@babel/preset-env", {
      "useBuiltIns": "entry",
      "debug": true,
      "targets": {
        "browsers": ["last 2 versions"]
      }
    }]
  ]
}
Run Code Online (Sandbox Code Playgroud)

我得到相同的结果,但如果我添加modules: false到preset-env选项,Babel不会将模块编译为ES5,Webpack会将模块再次标记为未使用.

结论

我需要找到一种方法来告诉Webpack我的模块是用Babel编译的,或者我需要找到一种方法告诉Babel自己扫描未使用的代码.

log*_*yth 30

Webpack的内置树抖动仅适用于ES6模块语法.如果您使用的是Babel的默认设置,Babel会将ES6模块编译为CommonJS模块,而Webpack则无需使用.

通常使用Webpack的人会想要传递modules: false给他们用于ES6的预设(可能是preset-env?),这样做

{
  presets: [
    ['env', { modules: false }],
  ],
}
Run Code Online (Sandbox Code Playgroud)

或者你可以考虑使用像https://github.com/indutny/webpack-common-shake这样的插件来为CommonJS模块启用树形抖动.

更新

如果您正在使用Babel 7(因此@babel/preset-env),则在Webpack中使用该modules选项时会自动false生成,因此不再需要此显式配置.

  • @Milanzor我从来没有在我的整个Stackoverflow生命中看到一个更好的例子,某人@我自己! (3认同)
  • @myself,“不会在主流浏览器中运行” =>否,我不需要使用Babel,Webpack编译器将模块转换为ES5,因此它们可以在浏览器中运行!这是缺少的链接,“ modules:false”,因此Babel将我的模块留给Webpack选择。谢谢! (2认同)