manlili blog

webpack之plugins例子

webpack打包例子

源码地址https://github.com/manlili/webpack_learn里面的lesson03

第一步

在空白的文件夹正确的安装webpack,这一步webpack入门指南已经讲过了。
然后创建源文件夹src,在src下面创建script和style文件夹用来盛放我们的测试原文件,比如js和css,然后创建个目标文件夹dist,用来盛放打包生成的文件

第二步

在根目录下面创建index.html,内容是:

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script src="bundle.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>

接着在src/script文件创建main.js,内容是:

1
2
3
function helloWord () {
return {}
}

接着在src/script文件创建test.js,内容是:

1
2
3
function test () {
alert("123");
}

第三步

配置webpack的打包配置文件webpack.config.js,内容如下:

1
2
3
4
5
6
7
8
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
module.exports = {
entry: './src/script/main.js',
output: {
path: path.resolve(__dirname, './dist/js'),
filename: 'bundle.js'
}
}

上面的配置意思是将main.js打包到bundle.js
接下来来看下我们的文件夹组成
图

第四步

在根目录下打开命名行输入

1
webpack

上面的过程是在根目录下面寻找webpack.config.js,然后按照配置进行打包.
图
这时我们就会看到dist下面多了个js文件夹,并且js文件夹里面多了个bundle.js,我们来看下文件目录:
图
下面我们来看下bundle.js内容(以后都省略打包自动生成的webpack代码)

1
2
3
4
5
6
7
8
9
10
11
/******/ ([
/* 0 */
/***/ (function(module, exports) {
function helloWord () {
return {}
}
/***/ })
/******/ ]);

上面我们可以看出生成了一个chunk,0代表第一个chunk

第五步

将两个js文件打包成一个js,此时我们只需要修改webpack的打包配置文件webpack.config.js,内容如下:

1
2
3
4
5
6
7
8
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
module.exports = {
entry: ['./src/script/main.js', "./src/script/test.js"],
output: {
path: path.resolve(__dirname, './dist/js'),
filename: 'bundle.js'
}
}

在根目录下打开命名行输入

1
webpack

出现:
图
注意上面生成了3个chunks,每个chunks的详细内容都标的很清楚,接着我们发现打包生成的bundle.js内容改变了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/******/ ([
/* 0 */
/***/ (function(module, exports) {
function helloWord () {
return {}
}
/***/ }),
/* 1 */
/***/ (function(module, exports) {
function test () {
alert("123");
}
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
__webpack_require__(0);
module.exports = __webpack_require__(1);
/***/ })
/******/ ]);

从上面生成的代码看出正好对应着打包运行时生成的3个chunks,其中第三个chunk是将两个不相干的模块_webpack_require(0)与webpackrequire__(1)联系起来

第六步

假设我们需要将两个文件打包完分别输出各自的打包文件,webpack.config.js里面entry就不能用字符串或者数组的方式,就需要用对象的方式,我们修改webpack.config.js文件内容是:

1
2
3
4
5
6
7
8
9
10
11
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
module.exports = {
entry: {
mian: './src/script/main.js',
test: './src/script/test.js'
},
output: {
path: path.resolve(__dirname, './dist/js'),
filename: 'bundle.js'
}
}

在根目录下打开命名行输入

1
webpack

出现:
图
此时上面出现报错,把这个写出来主要是想说明,如果entry用对象的方式写出来,打包生成的是多个文件,我们上面将output写死输出一个bundle.js很明显是不正确的,这时生成的错误bundle.js文件内容是:

1
2
3
4
5
6
7
8
9
10
11
12
/******/ ([
/* 0 */,
/* 1 */
/***/ (function(module, exports) {
function test () {
alert("123");
}
/***/ })
/******/ ]);

咦?上面我们明明是将main.js和test.js两个打包,最后生成的bundle.js却只有test.js里面的内容,原因是因为覆盖,先打包main.js,然后test.js打包完将mian.js打包结果覆盖掉了,这时我们就需要用到动态命名
我们修改webpack.config.js文件内容是:

1
2
3
4
5
6
7
8
9
10
11
12
//将多个文件打包生成多个文件的配置
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
module.exports = {
entry: {
mian: './src/script/main.js',
test: './src/script/test.js'
},
output: {
path: path.resolve(__dirname, './dist/js'),
filename: '[name]-[hash].js' //区分文件有[name], [hash], [chunkhash]
}
}

其中hash是整个文件打包的hash,chunkhash是打包生成的文件hash,如果两次要打包的文件内容无任何修改,那么两个打包的hash,以及chunkhash是不变的,
但是如果我改了其中一个要打包的文件程序,比如修改了main.js内容,再次打包,整个文件的hash会变,打包生成的main.js的chunkhash就变了,但是打包生成的test.js的chunkhash不变,这样我们实际项目如果只发版修改的文件,只要比较chunkhash是就可以了。
在根目录下打开命名行输入

1
webpack

出现:
图
这个时候我们发现dist/js文件下面生成
mian-c60ca74dfdc7a4138dce.js和test-c60ca74dfdc7a4138dce.js,其中mian-c60ca74dfdc7a4138dce.js内容是

1
2
3
4
5
6
7
8
9
10
11
/******/ ([
/* 0 */
/***/ (function(module, exports) {
function helloWord () {
return {}
}
/***/ })
/******/ ]);

test-c60ca74dfdc7a4138dce.js内容是:

1
2
3
4
5
6
7
8
9
10
11
12
/******/ ([
/* 0 */,
/* 1 */
/***/ (function(module, exports) {
function test () {
alert("123");
}
/***/ })
/******/ ]);

第七步

源码地址https://github.com/manlili/webpack_learn里面的lesson04
紧接着上面的六个步骤,下面介绍下使用plugins,这里介绍html-webpack-plugin插件,在根目录下面打开命令行执行:

1
npm install html-webpack-plugin --save-dev

就会发现package.json多了

1
2
3
4
"devDependencies": {
"html-webpack-plugin": "^2.28.0",
"webpack": "^2.6.1"
}

然后在webpack.config.js里面配置下plugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
mian: './src/script/main.js',
test: './src/script/test.js'
},
output: {
path: path.resolve(__dirname, './dist/js'),
filename: '[name]-[hash].js' //区分文件有[name], [hash], [chunkhash]
},
plugins: [
new htmlWebpackPlugin()
]
}

在根目录下打开命名行输入

1
webpack

出现:
图
从图上的结果我们可以发现使用了html-webpack-plugin进行打包,这时发现dist/js下面多了
index.html, mian-31a798066f1ba8f0dc49.js,test-31a798066f1ba8f0dc49.js,细心的就会发现比前面的六步多了个index.html,
下面来看下index.html的代码:

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack App</title>
</head>
<body>
<script type="text/javascript" src="test-31a798066f1ba8f0dc49.js"></script><script type="text/javascript" src="mian-31a798066f1ba8f0dc49.js"></script></body>
</html>

竟然是自动引入打包后的test-hash名字.js和mian-hash名字.js,当然这都是html-webpack-plugin的功劳,但是实际项目中html并不是自动生成的,而是需要我们自定义html,然后打包生成固定的html,也就是以根目录下面的index.html为模板,生成dist下面的index.html.
下面来看下我们根目录的index.html文件内容:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>我是根目录的index.html</title>
</head>
<body>
<script src="bundle.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>

然后在webpack.config.js里面配置下plugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
mian: './src/script/main.js',
test: './src/script/test.js'
},
output: {
path: path.resolve(__dirname, './dist/js'),
filename: '[name]-[hash].js' //区分文件有[name], [hash], [chunkhash]
},
plugins: [
new htmlWebpackPlugin({
template: 'index.html'
})
]
}

在根目录下打开命名行输入

1
webpack

发现dist/js文件下index.html内容改变为:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>我是根目录的index.html</title>
</head>
<body>
<script src="bundle.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="test-a6e4cd93aae2ba8c9b3b.js"></script><script type="text/javascript" src="mian-a6e4cd93aae2ba8c9b3b.js"></script></body>
</html>

这时生成的index.html是根据根目录下面的index.html生成的。
但是此时生成的index.html在dist/js文件下,我们想根据js和html分类放置文件,可以修改webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
mian: './src/script/main.js',
test: './src/script/test.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name]-[hash].js' //区分文件有[name], [hash], [chunkhash]
},
plugins: [
new htmlWebpackPlugin({
template: 'index.html'
})
]
}

在根目录下打开命名行输入

1
webpack

发现dist下面打包生成的js和html已分类,如下图
图

下面再来介绍下html-webpack-plugin的其他options,直接就写在webpack.config.js注释里面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
mian: './src/script/main.js',
test: './src/script/test.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name]-[hash].js' //区分文件有[name], [hash], [chunkhash]
},
plugins: [
new htmlWebpackPlugin({
filename: 'index-[hash].html', //生成的文件名字
template: 'index.html', //生成文件的 模板
inject: 'body', //打包生成的js,css和其他东西插入的位置
title: 'i am girl',
minify: { //压缩代码
collapseWhitespace: true,
html5: true
}
})
]
}

关于minify参数可以看minify官网介绍
在根目录下打开命名行输入

1
webpack

会发现生成index-0c16345fd56a0ca2d11b.html,内容是:

1
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>我是根目录的index.html</title></head><body><script src="bundle.js" type="text/javascript" charset="utf-8"></script><script type="text/javascript" src="js/test-3f78db648c587041fa54.js"></script><script type="text/javascript" src="js/mian-3f78db648c587041fa54.js"></script></body></html>

第八步

有时候我们想让plugin与将要打包的模板产生交互,这个时候就需要用到EJS语言,这个不懂的就自己去百度,源代码在
源码地址https://github.com/manlili/webpack_learn里面的lesson05
下面我们来看一下怎么让他们产生交互,假设我们想让根目录index.html下面的模板调取webpack.config.js里面plugins的title,下面我们就需要在根目录index.html用EJS:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<script src="bundle.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>

在根目录下打开命名行输入

1
webpack

发现dist文件夹下面生成的index.html内容是:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>i am girl</title>
</head>
<body>
<script src="bundle.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="js/test-2d74c122198fd85be94e.js"></script><script type="text/javascript" src="js/mian-2d74c122198fd85be94e.js"></script></body>
</html>

从上面代码可以发现名字改变了,取得是webpack.config.js里面plugins的title。如果我们想进一步在根目录下面的index.html获取webpack.config.js里面plugins的全部options,这时候需要在根目录index.html用EJS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<script src="bundle.js" type="text/javascript" charset="utf-8"></script>
<% for (key in htmlWebpackPlugin.files) {%>
<%= key%> : <%= JSON.stringify(htmlWebpackPlugin.files[key]) %>
<% } %>
<% for (key in htmlWebpackPlugin.options) {%>
<%= key%> : <%= JSON.stringify(htmlWebpackPlugin.options[key]) %>
<% } %>
</body>
</html>

在根目录下打开命名行输入

1
webpack

发现dist文件夹下面生成的index.html内容是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>i am girl</title>
</head>
<body>
<script src="bundle.js" type="text/javascript" charset="utf-8"></script>
publicPath : ""
chunks : {"test":{"size":39,"entry":"js/test-29163aeea83bc2442a2e.js","hash":"f81274a02f5687ec6c31","css":[]},"mian":{"size":40,"entry":"js/mian-29163aeea83bc2442a2e.js","hash":"bf812322b142ae514e99","css":[]}}
js : ["js/test-29163aeea83bc2442a2e.js","js/mian-29163aeea83bc2442a2e.js"]
css : []
manifest :
template : "F:\\manlili\\github\\webpack_learn\\node_modules\\html-webpack-plugin\\lib\\loader.js!F:\\manlili\\github\\webpack_learn\\lesson05\\index.html"
filename : "index-[hash].html"
hash : false
inject : "body"
compile : true
favicon : false
minify : false
cache : true
showErrors : true
chunks : "all"
excludeChunks : []
title : "i am girl"
xhtml : false
<script type="text/javascript" src="js/test-29163aeea83bc2442a2e.js"></script><script type="text/javascript" src="js/mian-29163aeea83bc2442a2e.js"></script></body>
</html>

上面需要注意的是htmlWebpackPlugin.files.chunks.模块名.entry是打包生成的chunks路径,这个后面深入讲解的时候需要用到。
关于html-webpack-plugin插件各种参数,它的官网讲的很清楚,自己可以点开链接查看。
下面来讲下htmlWebpackPlugin.files.chunks.模块名.entry,我们知道了路径就可以直接使用,比如在根目录index.html用EJS:

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></title>
<script src="<%=htmlWebpackPlugin.files.chunks.mian.entry %>" type="text/javascript" charset="utf-8"></script>
<script src="<%=htmlWebpackPlugin.files.chunks.test.entry %>" type="text/javascript" charset="utf-8"></script>
</head>
<body>
</body>
</html>

此时为了看这个效果需要将webpack.config.js中inject关闭一下,这样就不用将生成的js文件插入到生成的index.html中,专门测我们用htmlWebpackPlugin.files.chunks.模块名.entry写进去的引入方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
mian: './src/script/main.js',
test: './src/script/test.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name]-[hash].js' //区分文件有[name], [hash], [chunkhash]
},
plugins: [
new htmlWebpackPlugin({
filename: 'index-[hash].html', //生成的文件名字
template: 'index.html', //生成文件的 模板
inject: false, //打包生成的js,css和其他东西插入的位置
title: 'i am girl'
})
]
}

在根目录下打开命名行输入

1
webpack

发现dist文件夹下面生成的index.html内容是:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>i am girl</title>
<script src="js/mian-dbf6e0fc56af854ef09d.js" type="text/javascript" charset="utf-8"></script>
<script src="js/test-dbf6e0fc56af854ef09d.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
</body>
</html>

果然像我们预测那样,直接将生成的js插入了head那里。

如果我们想将打包后的html引入的js换成线上的地址,这个时候需要给output配置publicPath,webpack.config.js内容修改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
mian: './src/script/main.js',
test: './src/script/test.js'
},
output: {
path: path.resolve(__dirname, './dist'),
publicPath: 'https://cdn.example.com/',
filename: 'js/[name]-[hash].js' //区分文件有[name], [hash], [chunkhash]
},
plugins: [
new htmlWebpackPlugin({
filename: 'index-[hash].html', //生成的文件名字
template: 'index.html', //生成文件的 模板
inject: false, //打包生成的js,css和其他东西插入的位置
title: 'i am girl'
})
]
}

在根目录下打开命名行输入

1
webpack

发现dist文件夹下面生成的index.html内容是:

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>i am girl</title>
<script src="https://cdn.example.com/js/mian-c1f69861024d42a0ffc6.js" type="text/javascript" charset="utf-8"></script>
<script src="https://cdn.example.com/js/test-c1f69861024d42a0ffc6.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
</body>
</html>

从上面我们可以看出引入的是我们配置的publicPath地址,即线上的地址。

第九步

源码地址https://github.com/manlili/webpack_learn里面的lesson06
前面讲的都是单页面打包,下面我们对多个页面生成多个页面的方法举例说明一下:下面需要在src/script/下面创建多个待打包的js,比如a.js,b.js,c.js,d.js,这些js里面随便写一点js脚本就行,下面来看下整个目录:
图
接着需要修改webpack.config.js内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
a: './src/script/a.js',
b: './src/script/a.js',
c: './src/script/a.js',
d: './src/script/a.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].js' //区分文件有[name], [hash], [chunkhash]
},
plugins: [
new htmlWebpackPlugin({
filename: 'a.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是a'
}),
new htmlWebpackPlugin({
filename: 'b.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是b'
}),
new htmlWebpackPlugin({
filename: 'c.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是c'
}),
new htmlWebpackPlugin({
filename: 'd.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是d'
})
]
}

在根目录下打开命名行输入

1
webpack

发现dist文件夹下面生成的目录如下:
图
这里就不贴出来每个文件的代码了,打包结果是正确的。但是这个时候发现a.html里面引入的是打包后的a.js,b.js,c.js,d.js, b.html,c.html,d.html也是,下面来看下打包后的a.html内容如下:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>我是a</title>
</head>
<body>
<script src="bundle.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="js/a.js"></script><script type="text/javascript" src="js/b.js"></script><script type="text/javascript" src="js/c.js"></script><script type="text/javascript" src="js/d.js"></script></body>
</html>

这与我们预期在打包后的a.html只引入a.js,b.html只引入b.js,c.html只引入c.js,d.html只引入d.js,这个时候就要去看html-webpack-plugin里面的chunks和excludeChunks:
(1) chunks: 指定载入哪些chunk到打包生成的html页面
(2) excludeChunks: 指定排除哪些页面将剩下的chunks载入到打包生成的html页面
接着需要修改webpack.config.js内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
a: './src/script/a.js',
b: './src/script/a.js',
c: './src/script/a.js',
d: './src/script/a.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].js' //区分文件有[name], [hash], [chunkhash]
},
plugins: [
new htmlWebpackPlugin({
filename: 'a.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是a',
chunks: ['a'] //注意是数组
}),
new htmlWebpackPlugin({
filename: 'b.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是b',
chunks: ['b']
}),
new htmlWebpackPlugin({
filename: 'c.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是c',
chunks: ['c']
}),
new htmlWebpackPlugin({
filename: 'd.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是d',
chunks: ['d']
})
]
}

或者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
a: './src/script/a.js',
b: './src/script/a.js',
c: './src/script/a.js',
d: './src/script/a.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].js' //区分文件有[name], [hash], [chunkhash]
},
plugins: [
new htmlWebpackPlugin({
filename: 'a.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是a',
excludeChunks: ['b', 'c', 'd'] //注意是数组
}),
new htmlWebpackPlugin({
filename: 'b.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是b',
excludeChunks: ['a', 'c', 'd'] //注意是数组
}),
new htmlWebpackPlugin({
filename: 'c.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是c',
excludeChunks: ['a', 'b', 'd'] //注意是数组
}),
new htmlWebpackPlugin({
filename: 'd.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是d',
excludeChunks: ['a', 'b', 'c'] //注意是数组
})
]
}

在根目录下打开命名行输入

1
webpack

发现dist文件夹下a.html只引入a.js,b.html只引入b.js,c.html只引入c.js,d.html只引入d.js,达到我们的预期。

第十步

源码地址https://github.com/manlili/webpack_learn里面的lesson07
我们都知道当html页面引入多个js的时候就需要多次向服务器发送请求,这样会增加带宽消耗和时间消耗,如果我们追求极致的话,其实是可以将共用的js源码直接写在html,不共用js再外链引入,这样可以节约一点时间和带宽,下面来重点讲解一下:
之前插件html-webpack-plugin并没有考虑这种内联情况,但是庆幸的是插件的作者给出了在webpack里面打包的解决方法,传送门,首先根据官网给的例子改写我们的模板index.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></title>
<script type="text/javascript">
<%= compilation.assets[htmlWebpackPlugin.files.chunks.test.entry.substr(htmlWebpackPlugin.files.publicPath.length)].source() %> //内联化引入js
</script>
</head>
<body>
<script src="<%= htmlWebpackPlugin.files.chunks.d.entry %>" type="text/javascript" charset="utf-8"></script>
</body>
</html>

上面是将test.js作为内联js嵌入每个打包生成的html里面,紧接着为了跟外链js作比较,可以在打包生成的a.html只引入a.js,b.html只引入b.js,c.html只引入c.js,d.html只引入d.js,
然后修改webpack.config.js内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//将共用的js源码直接写在html,不共用js再外链引入,外链对应的js
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
a: './src/script/a.js',
b: './src/script/b.js',
c: './src/script/c.js',
d: './src/script/d.js',
test: './src/script/test.js'
},
output: {
path: path.resolve(__dirname, './dist'),
publicPath: 'https://cdn.example.com/',
filename: 'js/[name].js' //区分文件有[name], [hash], [chunkhash]
},
plugins: [
new htmlWebpackPlugin({
filename: 'a.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是a',
inject: false,
excludeChunks: ['b', 'c', 'd'] //注意是数组
}),
new htmlWebpackPlugin({
filename: 'b.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是b',
inject: false,
excludeChunks: ['a', 'c', 'd'] //注意是数组
}),
new htmlWebpackPlugin({
filename: 'c.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是c',
inject: false,
excludeChunks: ['a', 'b', 'd'] //注意是数组
}),
new htmlWebpackPlugin({
filename: 'd.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
title: '我是d',
inject: false,
excludeChunks: ['a', 'b', 'c'] //注意是数组
})
]
}

在根目录下打开命名行输入

1
webpack

发现dist文件夹下面生成a.html内容是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>我是a</title>
<script type="text/javascript">
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "https://cdn.example.com/";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 4);
/******/ })
/************************************************************************/
/******/ ({
/***/ 4:
/***/ (function(module, exports) {
function test () {
alert("test");
}
/***/ })
/******/ }); //内联化引入js
</script>
</head>
<body>
<script src="https://cdn.example.com/js/a.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>

通过上面的代码我们可以看出,test.js内嵌在了a.html,并且通过引入了a.js,到此为止也算是将plugin大部分讲透彻了。

请我喝杯果汁吧!