webpack中的html-webpack-plugin


本文作者: jsweibo

本文链接: https://jsweibo.github.io/2019/07/06/webpack%E4%B8%AD%E7%9A%84html-webpack-plugin/

摘要

本文主要讲述了:

  1. 如何让浏览器执行 JavaScript 文件
  2. webpack 中的 JavaScript 文件
  3. html-webpack-plugin

正文

如何让浏览器执行 JavaScript 文件

把 JavaScript 文件上传到服务器,然后再通过 URL 访问 JavaScript 文件,此时浏览器只会显示文本,但并不会执行它。

要想让浏览器执行 JavaScript 文件,必须通过<script>将 JavaScript 注入 HTML 文件。

然后通过 URL 访问 HTML 文件的地址,此时浏览器才会执行 JavaScript 文件。

示例:

learn_js/index.html

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script src="index.js"></script>
</body>
</html>

learn_js/index.js

1
console.log('hello, world');

webpack 中的 JavaScript 文件

明确上述概念之后,我们来看webpack中的 JavaScript 文件。

webpack是 JavaScript 的打包器。记住:虽然 JavaScript 打包了,但本质仍旧是 JavaScript 文件。

如果要执行打包后的 JavaScript 文件,同样必须通过<script>将其注入 HTML 文件。

示例:

learn_webapck/webpack.config.js

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

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

learn_webpack/src/index.js

1
console.log('hello, world');

运行npx webpack会在learn_webpack/dist/生成一个名为bundle.js的文件。

除此之外我们还要在learn_webpack/dist/里放入一个 HTML。

learn_webpack/dist/index.html

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="bundle.js"></script>
</head>
<body></body>
</html>

打包完成之后把dist/上传到服务器,通过 URL 访问 HTML 文件即可执行打包后的 JavaScript 文件。

但这种方式有许多缺点:

  1. 需要在dist/中创建一个 HTML 文件。dist/作为出口,是不适合加入版本管理的。
  2. 如果修改了output.filename或者output.filename以文件的 hash 值为文件名,每次打包后都要手动修改 HTML 文件。

能不能自动生成这个 HTML 文件呢?现在是html-webpack-plugin出场的时候了。

html-webpack-plugin

安装

1
2
3
#!/usr/bin/env bash

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

作用

简化 HTML 文件的创建。

注意:

如果使用mini-css-extract-plugin将 JavaScript 中的 CSS 剥离成独立的文件,此时html-webpack-plugin也会在 HTML 中使用<link>引入剥离出来的 CSS 文件。

这和style-loader/url不同,html-webpack-plugin直接在静态 HTML 文件中通过<link>注入 CSS 文件。而style-loader/url则是通过 JavaScript 生成<link>而后注入 CSS 文件。

示例:使用默认模板

learn_webapck/webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
plugins: [new HtmlWebpackPlugin()],
};

示例:使用underscore模板

learn_webapck/webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
plugins: [
new HtmlWebpackPlugin({
title: 'learn_webpack',
template: 'public/index.html',
}),
],
};

learn_webpack/public/index.html

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body></body>
</html>

注意:

  • 若要使用其他模板,例如:handlebars,则必须自行配置相应的 loader
  • 若模板已被其他 loader 处理过,则html-webpack-plugin将不再处理它

示例:

html-webpack-plugin将参数交给了handlebars-loaderhandlebars-loader支持变量注入,故仍能正常解析。由于模板已被handlebars-loader处理过,故html-webpack-plugin将不再处理模板。

learn_webapck/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
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.hbs$/,
use: [
{
loader: 'handlebars-loader',
},
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
title: 'learn_webpack',
template: 'public/index.hbs',
}),
],
};

learn_webpack/public/index.hbs

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ htmlWebpackPlugin.options.title }}</title>
</head>
<body></body>
</html>

示例:

html-webpack-plugin将参数交给了html-loaderhtml-loader不支持变量注入,故<%= htmlWebpackPlugin.options.title %>将不会被解析。由于模板已被html-loader处理过,故html-webpack-plugin将不再处理模板。

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
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
mode: 'development',
entry: {
main: './src/main.js',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
},
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
title: 'learn_webpack',
template: 'public/index.html',
}),
],
};

learn_webpack/public/index.html

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body></body>
</html>

参数

title

<title>的值

favicon

图片路径

html-webpack-plugin会将图片复制到输出目录。

示例:

1
2
3
4
new HtmlWebpackPlugin({
title: 'index',
favicon: 'public/favicon.png',
});

filename

保存文件名

默认值为index.html

template

模板路径

chunks

块列表

在 webpack 打包多页面应用时,供 HTML 文件分配各自需要引入的 JavaScript 代码块列表

excludeChunks

排除块列表

scriptLoading

脚本加载策略

取值范围:

  • blocking 阻塞
  • defer 异步加载不阻塞,延迟顺序执行

默认值为blocking

参考资料

本文作者: jsweibo

本文链接: https://jsweibo.github.io/2019/07/06/webpack%E4%B8%AD%E7%9A%84html-webpack-plugin/


本文对你有帮助?请支持我


支付宝
微信