webpack2 的 tree shaking

 tree shaking

  [ʃeɪk]

  • v.摇;发抖;震动;动摇
  • n.抖动;摇动;颤动

即 webpack 在打包的过程中会将没用的代码进行清除(dead code)。

一般 dead code 具有一下的特征:

  1. 代码不会被执行,不可到达
  2. 代码执行的结果不会被用到
  3. 代码只会影响死变量(只写不读)

使 tree shaking 生效:

首先,模块引入要基于 ES6 模块机制,不再使用 commonjs 规范,因为 es6 模块的依赖关系是确定的,和运行时的状态无关,可以进行可靠的静态分析,然后清除没用的代码。而 commonjs 的依赖关系是要到运行时候才能确定下来的

这就涉及到es6模块的知识了

commonJS 模块
commonJS的模块规范在Node中发扬光大,总的来说,它的特性有这几个:

1.动态加载模块
commonJS和es6的最大区别大概就在于此了吧,commonJS模块的动态加载能够很轻松的实现懒加载,优化用户体验。

2.加载整个模块
commonJS模块中,导出的是整个模块。

3.每个模块皆为对象
commonJS模块都被视作一个对象。

4.值拷贝
commonJS的模块输出和 函数的值传递相似,都是值的拷贝

es6 模块
1.静态解析
即在解析阶段就确定输出的模块,所以es6模块的import一般写在被引入文件的开头。

2.模块不是对象
在es6里,每个模块并不会当做一个对象看待

3.加载的不是整个模块
在es6模块中经常会看见一个模块中有好几个export 导出

4.模块的引用
es6模块中,导出的并不是模块的值拷贝,而是这个模块的引用

了解原理后开始测试

初始化项目

npm init 

安装webpack包

npm install webpack webpack-cli --save-dev

配置文件

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>起步</title>
  </head>
  <body>
    <script src="./dist/main.js"></script>
  </body>
</html>

index.js

import vue from './vue';
import test from './test';
vue.methods.fnA()
test.funcB()

test.js

export function funcA() {
  console.log('func A');
}

// src/es6/js/utilB.js
export function funcB() {
  console.log('func B');
}

vue.js

export default {
  data() {
  },
  methods: {
    fnA() {
      console.log(11)
    },
    fnB() {
      console.log(222)
    },
  },
}

package.json

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "build": "webpack"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^5.44.0",
    "webpack-cli": "^4.7.2"
  }
}

webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

 编译后的main.js文件

(()=>{"use strict";var e={};(e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),
Object.defineProperty(e,"__esModule",{value:!0})})(e),{data(){},methods:{fnA(){console.log(11)},fnB(){console.log(222)}}}.methods.fnA(),e.default.funcB()})();

可以看出test.js文件的funcB函数进行了清除

  

    

原文地址:https://www.cnblogs.com/wangxirui/p/15002406.html