tree shaking

Tree Shaking 可以用 来剔除 JavaScript 中用 不上的死代码。它依赖静态的 ES6 模块化 语 法,例如通过import和export导入、导出。 需要注意,要让 Tree Shaking 正常工作的前提是,提交给 Webpack的JavaScript代码必须采用了ES6 的模块化语法,因为 ES6模块化语法是静态的(在导入、导出语句中的路径 必须是静态的字符串,而且不能放入其他代码块中),这让 Webpack 可以简单地分析出哪些 export 的被 import 了。如果采用了 ES5 中的模块化,例如 module.export={ … }、 require (x+y)、 if (x) {require (’./util ’)},则 Webpack 无法分析出可以剔除哪些 代码。

配置Tree Shaking生效

首先,为了将采用 ES6 模块化的代码提交给 Webpack,需要配置 Babel 以让其保留 ES6 模块化语句。修改 .babelrc 文件如下: ”modules ”: false 的含义是关闭 Babel 的模块转换功能,保留原本的 ES6 模 块化语法。

{
    "presets": [
      [
        "@babel/preset-env",
        {
          "modules": false,      
        }
      ]
    ],
  }

若打开Webpack输出的bundle.js文件并查看, 则会发现用不上的代码还在里面, 要剔除用不上的代 码, 则还得经过 UglifyJS 处理一遍。

在项目中使用大量的第 三方库时,我们会发现 Tree Shaking 似乎不生效了,原因是大部 分 Npm 中的代码都采用了 CommonJS 语法,这导致 Tree Shaking 无法正常工作而降级处理。 但幸运的是,有些库考虑到了这一点,这些库在发布到 Npm 上时会同时提供两份代码,一份采 用 CommonJS 模块化语法,一份采用 ES6 模块化语法。并且在 package.json 文件中 分别指出这两份代码的入口。

{
  ”main”:”lib/index.j5”,//指明采用 CommonJS模块化的代码入口
  ”jsnext:main,,:”es/index.js” //指明采用 ES6模块化的代码入口
}

为了 让 Tree Shaking 对 redux 生效,需要配置 Webpack 的文件寻找规 则 如下 :

module.exports = {
  resolve: {
    //针对 Npm 中的第三方模块优先采用 jsnext:main 中指向的 ES6 模块化语法的文件
        mainFields: [’jsnext:main’,’browser’,’main’]
  }
}

以上配置的含义是优先使用 jsnext:main作为入口,如果不存在, jsnext:main就会采用 browser 或者 main 并将其作为入口 。 目前越来越多的 Npm 中的第三方模块都考虑到了 Tree Shaking, 并对其提供了支持。 采用jsnext:main 作为 ES6 模块化代码的入口是社区的一个约定.