webpack2 vs webpack1

webpack2比1的优势,我觉得在于支持es2015和实现了tree shaking. 那我们就用两个简单的例子还比较一下webpack1和webpack2

工程一:webpack-demo

1
& mkdir webpack-demo & cd webpack-demo
& npm init -y
& npm install --save-dev webpack@1.13.0

说明,安装1版本的webpack

创建app文件夹,包括两个文件index.js和maths.js

app/maths.js

1
2
3
4
5
6
7
8
9
// This function isn't used anywhere
export function square(x) {
return x * x;
}

// This function gets included
export function cube(x) {
return x * x * x;
}

app/index.js

1
2
import {cube} from './maths.js';
console.log(cube(5)); // 125

创建一个index.html文件

1
2
3
4
5
6
7
8
9
<html>
<head>
<title>webpack 1 demo</title>

</head>
<body>
<script src="dist/bundle.js"></script>
</body>
</html>

我们可以在package.json文件中配置script脚本

1
2
3
4
"scripts": {
"dev": "webpack",
"build": "webpack -p"
},

package.json的配置情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack",
"build": "webpack -p"
}
,

"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.24.1",
"babel-loader": "^6.4.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-es2015-webpack": "^6.4.3",
"webpack": "1.13.0"
}
,

"dependencies": {
"babel-runtime": "^6.23.0"
}

}

创建一个web pack.config.js文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var path = require('path');

module.exports = {
entry: './app/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
plugins: ['transform-runtime'],
presets: ['es2015'],
}
}
]
}
};

运行

1
$ npm install
$ npm run dev

可以查看dist里面的bundle.js文件,可以看到:

1
2
3
4
5
6
7
8
9
10
11
exports.square = square;
exports.cube = cube;
// This function isn't used anywhere
function square(x) {
return x * x;
}

// This function gets included
function cube(x) {
return x * x * x;
}

这样的信息,square这个函数虽然没有被引用,最后打包的时候,还是会打包进bundle.js中

1
$ npm run build

dist里面的bundle.js文件中可见:

1
"use strict";function t(e){return e*e}function n(e){return e*e*e}

工程二: webpack2-demo

1
& mkdir webpack2-demo & cd webpack2-demo
& npm init -y
& npm install --save-dev webpack

与工程一一样创建app/index.js , app/maths.js, index.html, 不同的是package.json与webpack.config.js

package.json如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"name": "webpack2-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack",
"build": "webpack -p"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^2.4.1"
}
}

web pack.config.js的配置如下:

1
2
3
4
5
6
7
8
9
var path = require('path');

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

如上所示,package中少了很多babel包,webpack的config配置中也没有了关于解析es2015的配置。因为webpack2支持es2015的import/export , 所以减少了很多这样的配置。官方文档里面明确说明了除了import/export, webpack不会修改任何其他使用了 ES2015 特性的代码,如果有使用ES2015特性的代码,请还是要引用babel.

ok, 我们现在来看下webpack2 的另外一个特性tree tracking.

运行

1
$ npm install
$ npm run dev

查看dist/bundle.js

1
2
3
4
5
6
7
8
9
10
11
12
"use strict";
/* unused harmony export square */
/* harmony export (immutable) */ __webpack_exports__["a"] = cube;
// This function isn't used anywhere
function square(x) {
return x * x;
}

// This function gets included
function cube(x) {
return x * x * x;
}

上面关于的square的函数有一个说明,它在任何地方都没有使用,当打包环境是process.env.NODE_ENV = “production”的时候,我们看下bundle.js还会打包进这个square函数吗?

1
& npm run build

查看dist/bundle.js

1
"use strict";function r(e){return e*e*e}

只有cube函数打包进去了。square没有打包进去,tree shaking!! 题外话:关于这个tree shaking名字,据说是因为我们可以把application看成是一颗tree,application中的export看成是the branches of the tree,当你摇这颗树的时候,那些死的树枝就会掉落。所以当我们打包这个application的时候,那些没有用的export都不应该打包进去。


当然,webpack2在配置上还有很多写法也改了。没有module.loaders, 变成module.rules等。 所以?你现在会把webpack1升级到2吗?