浅析webpack 如何优雅的使用tree

1.什么是tree-shaking

webpack 2 的到来带来的最棒的新特性之一就是tree-shaking 。tree-shaking源自于rollup.js,先如今,webpack 2也有类似的做法。

webpack 里的tree-shaking的到来不得不归功于es6规范的模块。为什么这么说,如今的前端模块规范很多,比较出流行的比如commonJS , AMD , 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模块中,导出的并不是模块的值拷贝,而是这个模块的引用

在结合es6模块和commonJS模块的区别之后,我们知道es6的特点是静态解析,而commonJS模块的特点是动态解析的,因此,借于es6模块的静态解析,tree-shaking的实现才能成为可能。
在webpack中,tree-shaking指的就是按需加载,即没有被引用的模块不会被打包进来,减少我们的包大小,缩小应用的加载时间,呈现给用户更佳的体验。

2.怎么使用tree-shaking

说了这么多那到底如何使用tree-shaking呢?
webpack默认es6规范编写的模块都能使用tree-shaking。这是什么意思呢?下面来看个例子。

首先奉上我的demo目录如下:

├─dist
    └─index.html
├─node_modules
    └─...
├─src
    ├─scripts
    ├─assets
├─webpack.config.js
└─package.json

dist用来存放打包好的代码

src相反的用来存放源文件

src里的scripts目录用来存放js脚本文件,assets用来存放静态资源文件

以下几条命令过后开始我们的tree-shaking之旅

npm install --save-dev webpack webpack-dev-server webpack.config.js const webpack = require('webpack') const path = require('path') module.exports = { entry:'./src/scripts/main.js', output:{ path:path.resolve(__dirname,'dist/'), filename:'main.bundle.js' }, plugins:[ new webpack.HotModuleReplacementPlugin() ], devServer:{ port:4200, contentBase:path.resolve(__dirname,'dist/'), historyApiFallback:true, hot:true } }

接下来是main.js,直接引入了sayHello

import { sayHello } from './greeter.ts';

sayHello();

相应的main.js的依赖greeter.js

export function sayHello(){ alert('hello') }

export function sayWorld(){ alert('world') }

在dist目录下有个index.html 用来引入打包后的bundle

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript" src="https://www.jb51.net/article/main.bundle.js"></script> </body> </html>

以上就是整个demo的代码,接下来的事情我们直接webpack打包试试看

去掉打包后冗长的代码只看chunk传参的部分:

[
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__person__ = __webpack_require__(1);
Object(__WEBPACK_IMPORTED_MODULE_0__person__["a" /* sayHello */])();
/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return sayHello; });
/* unused harmony export sayWorld */
    function sayHello(){
        alert('hello');
    }
    function sayWorld(){
        alert('world');
    }
/***/ })
/******/ ]

我们关注这一行

/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return sayHello; });

实际上只return了一个sayHello。

因此我们现在只需要压缩一下整个Js代码,就能把没引用的sayWorld剔除。

键入以下命令进行压缩

webpack --optimize-minimize

由于压缩后的代码只有一行了,我们移步尾部:

function(e,n,r){"use strict";function t(){alert("hello")}r.d(n,"a",function(){return t})}]);

可以看到sayWorld函数已经被成功剔除。

我们启动webpack-dev-server

webpack-dev-server

在浏览器中输入

:4200

这里写图片描述

每次都需要在命令行里输入参数,岂不是很麻烦,还有没有其他更好的办法呢?

(1)我们可以把这串命令放入package.json的scripts字段,然后通过npm start来自动执行

(2)其实–optimize-minimize的底层实现是一个插件UglifyJsPlugin,因此,我们可以直接在webpack.config.js里配置它

在webpack.config.js里配置插件

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wydgdp.html