作用
直接為項目生成一個或多個HTML文件(HTML文件個數(shù)由插件實例的個數(shù)決定),并將webpack打包后輸出的所有腳本文件自動添加到插件生成的HTML文件中。通過配置,可以將根目錄下用戶自定義的HTML文件作為插件生成HTML文件的模板。另外,還可以通過向插件傳遞參數(shù),控制HTML文件的輸出。
用法:
- 第一步:在項目根目錄下安裝插件:
cnpm install html-webpack-plugin --save-dev
- 第二步:在webpack配置文件頭部require html-webpack-plugin模塊,并保存引用至htmlWebpackPlugin變量。
var htmlWebpackPlugin = require('html-webpack-plugin');
- 第三步:為webpack配置文件暴露的對象添加一個plugins屬性,屬性值為一個數(shù)組,將新建的html-webpack-plugin對象實例添加到數(shù)組中。若不傳入任何參數(shù),那么插件將生成默認的html文件。
module.exports = {
entry: {
main:'./src/script/main.js'
},
output: {
path: './dist',
filename: 'js/[name].bundle.js'
},
plugins:[
new htmlWebpackPlugin()
]
}
- 第四步:配置參數(shù)。為新建的對象實例傳入一個對象字面量參數(shù),初始化對象實例的屬性。
module.exports = {
... ,
plugins:[
new htmlWebpackPlugin({
filename:'index.html',
template:'template.html',
inject:false,
title:'webpack is good',
chunks:['main']
})
]
}
htmlWebpackPlugin對象
htmlWebpackPlugin對象有兩個屬性,一個是files,一個是options。files和options的屬性值都是對象。通過EJS語法,可以在HTML模板文件(template.html)中遍歷這兩個屬性,查看其詳情:
<% for(var key in htmlWebpackPlugin.files) { %>
<%= key %> : <%= JSON.stringify(htmlWebpackPlugin.files[key]) %> //將對象或數(shù)組轉(zhuǎn)換為JSON字符串。
<% } %>
<% for(var key in htmlWebpackPlugin.options) { %>
<%= key %> : <%= JSON.stringify(htmlWebpackPlugin.options[key]) %>
<% } %>
遍歷后的結(jié)果如下:
"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
}
}
參數(shù)說明:
- title: title值用于生成的HTML文檔。
- filename: 將生成的HTML寫入到該文件中。默認寫入到index.html中。你也可以在這兒指定子目錄 (eg: assets/admin.html)。
- template: Webpack require path 到 template中。 詳情查閱 docs
-
inject:
true | 'head' | 'body' | false添加所有的靜態(tài)資源(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(發(fā)表)文件。 -
showErrors:
true | false如果為true (默認),詳細的錯誤信息將被寫入到HTML頁面。 - chunks:允許你只添加某些chunks (e.g. only the unit-test chunk)
-
chunksSortMode: 在chunks被include到html文件中以前,允許你控制chunks 應(yīng)當如何被排序。允許的值:
'none' | 'auto' | 'dependency' | {function}- 默認值:'auto'。 - excludeChunks: 允許你跳過某些chunks (e.g. don't add the unit-test chunk)
-
xhtml:
true | false如果為true, 將 link 標簽渲染為自閉合標簽, XHTML compliant。 默認是 false。
template參數(shù)
由于html-webpack-plugin直接生成的HTML文件十分簡單,不能滿足項目需求,因此我們通常會配置template參數(shù),將該參數(shù)值設(shè)置為我們已創(chuàng)建好的HMTL模板文件相對于根目錄的相對路徑。
template:'template.html'
由于html-webpack-plugin支持EJS模板語法,因此在模板文件中,我們可以使用EJS模板語法來獲取htmlWebpackPlugin對象中的數(shù)據(jù),以此來控制html的輸出。
chunks或excludeChunks參數(shù)
chunks或excludeChunks參數(shù)限定了HTML模板文件中能夠包含的打包后的腳本文件。該參數(shù)對腳本的自動注入或手動注入都有限定作用。
inject參數(shù)
注意下面兩種情況:
- 若inject值為false,那么所有打包后的腳本文件都不會被自動添加到HTML模板文件中。此時你需要在模板文件中通過EJS語法,在需要的位置處,手動添加相應(yīng)的腳本文件,若不添加,打包后的腳本文件將不會出現(xiàn)在HTML模板文件相應(yīng)的位置上。
module.exports = {
...
plugins:[
new htmlWebpackPlugin({
filename:'c.html',
template:'index.html',
title:'this is c.html',
inject:false,
excludeChunks:['a','b']
})
]
}
- 若inject未設(shè)置,或設(shè)置了非false的值,那么所有打包后的腳本文件都會被自動添加到HTML模板文件中。在這種場景下,HTML模板文件中不能出現(xiàn)任何手動添加的打包后的腳本文件。因為后者會導(dǎo)致webpack報錯或是出現(xiàn)腳本重復(fù)注入的情況。
module.exports = {
...
plugins:[
new htmlWebpackPlugin({
filename:'admin.html',
template:'index.html',
inject:'head',
chunks:['a','b','c']
})
]
}
當inject未設(shè)置,或設(shè)置了非false的值時:若此時HTML模板文件中已有被手動添加的打包后的腳本文件,那么:
- 當該腳本文件所對應(yīng)的chunk與chunks或excludeChunks參數(shù)所限定的chunk不一致時,webpack會報錯;
- 當手動添加的位置與inject參數(shù)值所指示的位置不一致時,webpack也會報錯。
- 若都一致,那么手動添加的腳本文件也會被注入到HTML模板中,從而出現(xiàn)腳本重復(fù)注入的情況。
結(jié)論:在同一HTML模板文件中,自動添加已打包的腳本文件與手動添加已打包的腳本文件不能并存,這兩項操作只能選其一。
特殊情況:使用EJS語法向HTML模板文件手動添加打包后的腳本文件:
1.由于inject參數(shù)不能被同時設(shè)置為'head'和'body',因此,當有的打包后的腳本文件需要被添加到head標簽,而另外的需要被添加到body標簽中時,就需要手動向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>
2.為了網(wǎng)頁的加載性能,減少HTTP請求數(shù),當有的打包后的腳本文件需要被內(nèi)嵌到head標簽中,而其余的需要以引用外部資源的方式添加到HTML模板中時,也需要手動向HTML模板注入腳本。
<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文件
如果我們開發(fā)的是一個多頁面應(yīng)用程序,那么我們就需要為不同的頁面生成不同的HTML文件。通過向plugins數(shù)組添加多個插件實例就可以實現(xiàn):
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'
})
]
}