直接为项目生成一个或多个HTML文件(HTML文件个数由插件实例的个数决定),并将webpack打包后输出的所有脚本文件自动添加到插件生成的HTML文件中。通过配置,可以将根目录下用户自定义的HTML文件作为插件生成HTML文件的模板。另外,还可以通过向插件传递参数,控制HTML文件的输出。
cnpm install html-webpack-plugin --save-dev
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
main:'./src/script/main.js'
},
output: {
path: './dist',
filename: 'js/[name].bundle.js'
},
plugins:[
new htmlWebpackPlugin()
]
}
module.exports = {
... ,
plugins:[
new htmlWebpackPlugin({
filename:'index.html',
template:'template.html',
inject:false,
title:'webpack is good',
chunks:['main']
})
]
}
htmlWebpackPlugin对象有两个属性,一个是files,一个是options。files和options的属性值都是对象。通过EJS语法,可以在HTML模板文件(template.html)中遍历这两个属性,查看其详情:
<% for(var key in htmlWebpackPlugin.files) { %>
<%= key %> : <%= JSON.stringify(htmlWebpackPlugin.files[key]) %> //将对象或数组转换为JSON字符串。
<% } %>
<% for(var key in htmlWebpackPlugin.options) { %>
<%= key %> : <%= JSON.stringify(htmlWebpackPlugin.options[key]) %>
<% } %>
遍历后的结果如下:
"htmlWebpackPlugin": {
"files": {
publicPath : "",
"css": [],
"js": [ "js/main.ae8647e767cd76e54693.bundle.js"],
"chunks": {
"main": {
"size":23,
"entry": "js/main.ae8647e767cd76e54693.bundle.js",
"css": [],
"hash":"ae8647e767cd76e54693",
}
},
manifest : ""
},
"options":{
template : "C:\\dev\\webpack-demo\\node_modules\\.2.28.0@html-webpack-plugin\\lib\\loader.js!c:\\dev\\webpack-demo\\index.html",
filename : "index.html",
hash : false,
inject : false,
compile : true,
favicon : false,
minify : false,
cache : true,
showErrors : true,
chunks : ["main"],
excludeChunks : [],
title : "webpack is good",
xhtml : false
}
}
title: title值用于生成的HTML文档。
filename: 将生成的HTML写入到该文件中。默认写入到index.html中。你也可以在这儿指定子目录 (eg: assets/admin.html)。
template: Webpack require path 到 template中。 详情查阅 docs
inject: true | ‘head’ | ‘body’ | false添加所有的静态资源(assets)到模板文件或templateContent 。当传入true或’body’时,所有javascript资源将被放置到body 元素的底部。 当传入’head’时, 所有的脚本将被放置到head元素中。
favicon: 添加指定的favicon path到输出的html文件。
minify: {…} | false 传入一个html-minifier 对象选项来压缩输出的html文件。
hash: true | false 如果值为true,就添加一个唯一的webpack compilation hash给所有已included的 scripts 和 CSS 文件。这对缓存清除(cache busting)十分有用。
cache: true | false 如果为true (默认),只要文件被更改了就emit(发表)文件。
showErrors: true | false如果为true (默认),详细的错误信息将被写入到HTML页面。
chunks:允许你只添加某些chunks (e.g. only the unit-test chunk)
chunksSortMode: 在chunks被include到html文件中以前,允许你控制chunks 应当如何被排序。允许的值: ‘none’ | ‘auto’ | ‘dependency’ | {function} - 默认值: ‘auto’。
excludeChunks: 允许你跳过某些chunks (e.g. don’t add the unit-test chunk)
xhtml: true | false 如果为true, 将 link 标签渲染为自闭合标签, XHTML compliant。 默认是 false。
由于html-webpack-plugin直接生成的HTML文件十分简单,不能满足项目需求,因此我们通常会配置template参数,将该参数值设置为我们已创建好的HMTL模板文件相对于根目录的相对路径。
template:'template.html'
由于html-webpack-plugin支持EJS模板语法,因此在模板文件中,我们可以使用EJS模板语法来获取htmlWebpackPlugin对象中的数据,以此来控制html的输出。
chunks或excludeChunks参数限定了HTML模板文件中能够包含的打包后的脚本文件。该参数对脚本的自动注入或手动注入都有限定作用。
inject参数
module.exports = {
...
plugins:[
new htmlWebpackPlugin({
filename:'c.html',
template:'index.html',
title:'this is c.html',
inject:false,
excludeChunks:['a','b']
})
]
}
module.exports = {
...
plugins:[
new htmlWebpackPlugin({
filename:'admin.html',
template:'index.html',
inject:'head',
chunks:['a','b','c']
})
]
}
当inject未设置,或设置了非false的值时:若此时HTML模板文件中已有被手动添加的打包后的脚本文件,那么:
当该脚本文件所对应的chunk与chunks或excludeChunks参数所限定的chunk不一致时,webpack会报错;
当手动添加的位置与inject参数值所指示的位置不一致时,webpack也会报错。
若都一致,那么手动添加的脚本文件也会被注入到HTML模板中,从而出现脚本重复注入的情况。
结论:在同一HTML模板文件中,自动添加已打包的脚本文件与手动添加已打包的脚本文件不能并存,这两项操作只能选其一。
<head>
...
<script src="<%= htmlWebpackPlugin.files.chunks.main.entry %>"></script>
</head>
<body>
<% for(var k in htmlWebpackPlugin.files.chunks){ %>
<% if(k!=='main'){ %>
<script src="<%= htmlWebpackPlugin.files.chunks[k].entry %>"></script>
<% } %>
<% } %>
</body>
<head>
...
<script type="text/javascript" src="<%= compilation.assets[htmlWebpackPlugin.files.chunks.main.entry.substr(htmlWebpackPlugin.files.publicPath.length)].source() %>"></script>
</head>
<body>
<% for(var k in htmlWebpackPlugin.files.chunks){ %>
<% if(k!=='main'){ %>
<script src="<%= htmlWebpackPlugin.files.chunks[k].entry %>"></script>
<% } %>
<% } %>
</body>
如果我们开发的是一个多页面应用程序,那么我们就需要为不同的页面生成不同的HTML文件。通过向plugins数组添加多个插件实例就可以实现:
module.exports = {
entry: 'index.js',
output: {
path: 'dist',
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin(), // Generates default index.html
new HtmlWebpackPlugin({ // Also generate a test.html
filename: 'test.html',
template: 'src/assets/test.html'
})
]
}