作用
- 为html文件中引入的外部资源如 script, link 动态添加每次 compile 后的 hash,防止引用缓存的外部文件问题
- 可以生成创建 html 入口文件,比如单页面可以生成一个 html 文件入口,配置N个html-webpack-plugin可以生成N个页面入口
原理
将 webpack 中 entry 配置相关入口 chunk 和 extract-text-webpack-plugin 抽取 css 样式插入到该插件提供的 template 或 templateContent 配置项指定的内容基础上生成一个 html 文件,具体插入方式是将样式 link 插入到 head 元素中,script 插入到 head 或 body 中。
实例
基础用法
不配置任何参数
const HtmlWebpackPlugin = require('html-webpack-plugin')module.export = {...plugins: [new HtmlWebpackPlugin()]...}
不配置任何选项的 html-webpack-plugin 插件,它会默认将 webpack 中的 entry 配置所有的入口 chunk 和extract-text-webpack-plugin 抽取的 css 样式都插入到文件指定的位置。例如上面生成的 html 文件内容如下:
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Webpack App</title><link href="index-af150e90583a89775c77.css" rel="stylesheet"></head><body><script type="text/javascript" src="common-26a14e7d42a7c7bbc4c2.js"></script><script type="text/javascript" src="index-af150e90583a89775c77.js"></script></body></html>
配置项
插件提供的配置项比较多,通过源码可以看出具体的配置项如下:
this.options = _.extend({
template: path.join(__dirname, 'default_index.ejs'),
filename: 'index.html',
hash: false,
inject: true,
compile: true,
favicon: false,
minify: false,
cache: true,
showErrors: true,
chunks: 'all',
excludeChunks: [],
title: 'Webpack App',
xhtml: false
}, options);
title
生成的html文档的标题。配置该项,它并不会替换指定模板文件中的title元素的内容,除非html模板文件中使用了模板引擎语法来获取该配置项值,如下ejs模板语法形式:
<title>{%= o.htmlWebpackPlugin.options.title %}</title>
filename
输出文件的文件名称,默认为index.html,不配置就是该文件名;此外,还可以为输出文件指定目录位置(例如’html/index.html’)
补充:
- filename配置的 html 文件目录是相对于 webpackConfig.output.path 路径而言的,不是相对于当前项目目录结构的
- 指定生成的 html 文件内容中的 link 和 script 路径是相对于生成目录下的
template
本地模板文件的位置, 支持加载器(如handlebars、ejs、undersore、html等),eg: handlebars!src/index.hbs。
- template 配置项在 html 文件中使用 file-loader 时,其所指定的位置找不到,导致生成的 html 文件内容不是期望的内容
- 为 template 指定的模板文件没有指定任何 loader 的话,默认使用 ejs-loader。 eg: template: ‘./index.html’, 若没有为 .html 指定任何 loader 就使用 ejs-loader
tempateContent
string | function,可以指定模板内容,不能与 template 共存。配置值为function时,可以直接返回html字符串,也可以异步调用返回html字符串。inject
向 template 或 templateContent 中注入所有静态资源,不同的配置值注入的位置不径相同。
- true: 默认值,所有 js 资源插入到 body 元素底部
- body:所有 js 资源插入到 body 元素底部
- head:所有 js 资源插入到 head 元素中
- false:所有 js 和 css 资源都不会注入到模板文件中
favicon
添加特定 favicon 路径到输出的 html 文档中,这个同 title 配置项,需要在模板中动态获取其路径值hash
true | false , 是否为所有注入的静态资源添加webpack每次编译产生的唯一 hash 值chunks
主要用于多入口文件,当你有多个入口文件,那就会编译后生成多个打包后的文件,那么 chunks 就能选择你要使用的哪些 js 文件,不配置此项默认会将entry中所有的chunk注入到模板中,每个页面注入的chunk应该是不相同的,需要通过该配置为不同页面注入不同的chunk
entry: {
index: path.resolve(__dirname, './src/index.js'),
devor: path.resolve(__dirname, './src/devor.js'),
main: path.resolve(__dirname, './src/main.js')
}
plugins: [
new httpWebpackPlugin({
chunks: ['index','main']
})
]
编译后:
<script type=text/javascript src="index.js"></script>
<script type=text/javascript src="main.js"></script>
excludeChunks
这个与chunks配置项正好相反,用来配置不允许注入的chunk
entry: {
index: path.resolve(__dirname, './src/index.js'),
devor: path.resolve(__dirname, './src/devor.js'),
main: path.resolve(__dirname, './src/main.js')
}
plugins: [
new httpWebpackPlugin({
excludeChunks: ['devor.js']// 和上面的等效
})
]
编译后:
<script type=text/javascript src="index.js"></script>
<script type=text/javascript src="main.js"></script>
chunksSortMode
none | auto| function,默认auto; 允许指定的chunk在插入到html文档前进行排序。
function值可以指定具体排序规则;auto基于chunk的id进行排序; none就是不排序
xhtml
true|fasle, 默认false;是否渲染link为自闭合的标签,true则为自闭合标签
cache
true|fasle, 默认true; 内容变化时生成一个新的文件
showErrors
true|false,默认true;是否将错误信息输出到html页面中。这个很有用,在生成html文件的过程中有错误信息,输出到页面就能看到错误相关信息便于调试。
minify
{….}|false;传递 html-minifier 选项给 minify 输出,false就是不使用html压缩,minify具体配置参数请点击html-minifier
plugins:[
new HtmlWebpackPlugin({
//部分省略,具体看minify的配置
minify: {
caseSensitive: true, // 是否对大小写敏感,默认false
collapseBooleanAttributes: true, // 是否简写boolean格式的属性如:disabled="disabled" 简写为disabled 默认false
collapseWhitespace: true, // 是否去除空格,默认false
minifyCSS: true, // 是否压缩html里的css(使用clean-css进行的压缩) 默认值false;
minifyJS: true, //是否压缩html里的js(使用uglify-js进行的压缩)
preventAttributesEscaping: true, //Prevents the escaping of the values of attributes
removeAttributeQuotes: true, //是否移除属性的引号 默认false
removeComments: true, //是否移除注释 默认false
removeCommentsFromCDATA: true, //从脚本和样式删除的注释 默认false
removeEmptyAttributes: true, // 是否删除空属性,默认false
removeOptionalTags: false, // 若开启此项,生成的html中没有 body 和 head,html也未闭合
removeRedundantAttributes: true, // 删除多余的属性
removeScriptTypeAttributes: true, // 删除script的类型属性,在h5下面script的type默认值:text/javascript 默认值false
removeStyleLinkTypeAttributes: true, // 删除style的类型属性, type="text/css" 同上
useShortDoctype: true, //使用短的文档类型,默认false
}
}),
]
配置多个 html 页面
html-webpack-plugin的一个实例生成一个html文件,如果单页应用中需要多个页面入口,或者多页应用时配置多个html时,那么就需要实例化该插件多次
entry: {
index: path.resolve(__dirname, './src/index.js'),
list: path.resolve(__dirname, './src/list.js'),
detail: path.resolve(__dirname, './src/detail.js')
}
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html',
excludeChunks: ['list', 'detail']
}),
new HtmlWebpackPlugin({
filename: 'list.html',
template: 'src/list.html',
chunks: ['index', 'list']
}),
new HtmlWebpackPlugin({
filename: 'detail.html',
template: 'src/detail.html',
chunks: ['index', 'detail']
})
]
编译后:
/*index.html*/
<script type=text/javascript src="index.js"></script>
/*list.html*/
<script type=text/javascript src="index.js"></script>
<script type=text/javascript src="list.js"></script>
/*detail.html*/
<script type=text/javascript src="index.js"></script>
<script type=text/javascript src="detail.js"></script>
配置自定义模板
在项目中,可能所有页面的模板文件可以共用一个,因为html-webpack-plugin插件支持不同的模板loader,所以结合模板引擎来共用一个模板文件有了可能。
所以,配置自定义模板就派上用场了。具体的做法,借助于模板引擎来实现,例如插件没有配置loader时默认支持的ejs模板引擎,下面就以ejs模板引擎为例来说明;
例如项目中有2个入口html页面,它们可以共用一个模板文件,利用ejs模板的语法来动态插入各自页面的thunk和css样式,代码可以这样:
<!DOCTYPE html>
<html style="font-size:20px">
<head>
<meta charset="utf-8">
<title><%= HtmlWebpackPlugin.options.title %></title>
<% for (var css in HtmlWebpackPlugin.files.css) { %>
<link href="<%=htmlWebpackPlugin.files.css[css] %>" rel="stylesheet">
<% } %>
</head>
<body>
<div id="app"></div>
<% for (var chunk in HtmlWebpackPlugin.files.chunks) { %>
<script type="text/javascript" src="<%=HtmlWebpackPlugin.files.chunks[chunk].entry %>"></script>
<% } %>
</body>
</html>
