webpack高级概念Tree Shaking (树摇)(系列三)

什么是 Tree-Shaking

用来在打包编译成 bundle 时消除 ES6 Module 语法中未使用到的代码和模块。

比如入口文件引入这个math.js模块,有add,min方法,只引入add方法,但是打包后的文件中还自动引入了min方法,多次一举,浪费性能,使用tree-shaking(树摇)去除未被导入的代码

import { add } from './math.js';

Tree Shaking 使用

Tree Shaking 可以用来剔除 JavaScript 中用不上的死代码。它依赖静态的 ES6 模块化语法,例如通过 import 和 export 导入导出。

需要注意的是要让 Tree Shaking 正常工作的前提是 JavaScript 代码必须采用 ES6 模块化语法,因为 ES6 模块化语法是静态的,这让 Webpack 可以简单的分析出哪些 export 的被 import 过了。不支持commonJs模块导入

接下来配置 Webpack 让 Tree Shaking 生效

webpack4 默认保留ES6模块化语句,并没有通过Babel将其转换

修改 .babelrc 文件为如下:

//.babelrc

{
   "presets": [["@babel/preset-env",{
      "useBuiltIns": "usage",
      "corejs": 2,
      "modules":false //关闭 Babel 的模块转换功能,保留原本的 ES6 模块化语法
      //默认是auto,取值还可以是 amd, umd, systemjs, commonjs,auto等
   }]]
}

 

修改 webapck.config.js , 开发环境默认没有树摇功能,需要加配置, 生产环境默认有树摇功能,可以去除optimization配置

 
module.exports={
 mode: 'development',
  optimization: {
  //开发坏境使用tree shaking时加usedExports: true
    usedExports: true 
  },
}

 

还需通过 package.json 的 "sideEffects" 属性来告诉webpack哪些模块是可以忽略掉,如果没有则设置为 false ,来告知webpack,它可以安全地删除未用到的 export 。

修改 package.json

{
  "name": "your-project",
  "sideEffects": false
}

 

有的模块没有导出模块(export default  XXX),在 Tree Shaking 模式下就会被忽略(比如import './style.css'),所以我们需要把这些模块做处理,不需要 Tree Shaking 对这些模块进行处理,可以改为一个数组:

 

{
  "name": "your-project",
  "sideEffects": ["*.css"]
}
"sideEffects": ["*.css"] 表示不对所以css模块使用 Tree Shaking 处理。

 

index.js

//tree shaking import export
import {cube} from './math.js'

let component = () => {
  let element = document.createElement('pre')
  element.innerHTML = [
    'Hello webpack!',
    '2 cubed is equal to ' + cube(2)
  ].join('\n\n');
  console.log(cube)
  
  return element;
}
document.body.appendChild(component());

 

main.js

export let square= (x) => {
  console.log(x)
  return x * x;
}

export let cube = (x) => {
  console.log(x)
  return x * x * x;
}

 

运行 npm run build ,然后打开打包后的js文件:main.js找到下面这段文字

/*!*********************!*\
   !*** ./src/math.js ***!
   \*********************/
 /*! exports provided: square, cube */
 /*! exports used: cube */
 /***/

从上面这段文字可以看出 Tree Shaking 生效了,但是在开发环境下,并没有把没有用的代码删掉,因为开发环境下还需要对代码进行调试。

我们已经找出需要删除的“未引用代码(dead code)”,然而,不仅仅是要找出,还要删除它们。生产环境中会删除没引入的代码,我们需要将 mode 配置选项设置为 production ,将optimization对象删掉,修改 devtool 配置选项

webpack.config.js

module.exports = {
  mode: 'production',
  devtool: 'cheap-module-source-map'
}

运行 npm run build ,查看打包结果就可以看到没有用的代码被删掉了。



 

上一篇:3D Cube计算引擎加速运算


下一篇:cube.js 上下文实践的一些说明