天介紹 webpack 的一個最常用的插件:HTML Webpack Plugin。
說它是使用 webpack 開發(fā)前端項目必不可少的插件也不為過,因為它可以自動幫我們將 webpack 打包生成的文件(比如 js 文件、css 文件)嵌入到 html 文件中。
這在生成的文件帶有哈希串時尤為有用。
在 webpack 配置文件引入 HtmlWebpackPlugin 插件,然后在 plugins 數(shù)組中通過 new HtmlWebpackPlugin() 加入 HtmlWebpackPlugin 實例對象即可。
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'app.[contenthash:8].js',
},
mode: 'production',
plugins: [
new HtmlWebpackPlugin()
],
}
我們執(zhí)行 npx webpack 命令后,webpack 額外給我們生成了一個 dist/index.html 文件。該 html 文件格式化后得到的內(nèi)容為:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack App</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<script defer="defer" src="app.c8b961ec13a790ae7d15.js"></script>
</head>
<body></body>
</html>
可以看到將打包好的 app.js 文件被自動嵌入到 head 元素下最后一個子元素位置。
這里打包文件名尾部被添加了內(nèi)容哈希串,這意味著每次項目的內(nèi)容發(fā)生變化,哈希串的值都不同。
試想下,如果你自己管理 html 文件,每次都要改這個 js 文件名,是要多累,還好有 HtmlWebpackPlugin 幫忙。
當(dāng)然前面這種只是 HtmlWebpackPlugin 插件的默認(rèn)用法,我們可以做更具體的定制化。
我們需要傳入一個配置對象來進(jìn)行模板渲染定制化。
HtmlWebpackPlugin 的配置非常豐富,不過常用的就幾個。
plugins: [
new HtmlWebpackPlugin({
title: '前端西瓜哥的博客',
favicon: 'static/favicon.ico',
}),
],
在實際開發(fā)中,通常是創(chuàng)建一個 index.html 提供給 HtmlWebpackPlugin 插件作為模板。
這樣的話,title 等配置和一些更細(xì)碎的內(nèi)容就可以直接寫到 html 上。相比配置,直接在 html 上編輯要更直觀些。
我們在根目錄創(chuàng)建一個 index.html 作為模板:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>前端西瓜哥</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body></body>
</html>
這樣就可以直接在 html 模板上添加 title,以及一些 cdn 形式的第三方庫。
webpack.config.js 配置改為:
plugins: [
new HtmlWebpackPlugin({
template: 'index.html'
}),
],
生成的 html 為:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>前端西瓜哥</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script defer src="app.d02c9155f73c92f51bf5.js"></script>
</head>
<body></body>
</html>
第三方庫建議使用自己本地項目的,會更穩(wěn)定和安全些,比如上面就建議改為 <script src="static/jquery-3.6.0.min.js"></script>。
這里會用到一個 copy-webpack-plugin 插件將一些文件或文件夾拷貝到打包目錄下。關(guān)于這個插件我會另外專門寫一篇文章講解,這里不展開。
webpack 支持通過使用 lodash.template() 的方式注入變量。
我們將模板 html 改為下面這樣:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<%= htmlWebpackPlugin.options.saySomething %>
</body>
</html>
配置改為:
plugins: [
new HtmlWebpackPlugin({
template: 'index.html',
title: '前端西瓜哥的博客',
// 下面這個是自定義屬性
saySomething: 'Stay hungry, stay foolish'
}),
],
將傳入給 HtmlWebpackPlugin 的配置屬性會成為 htmlWebpackPlugin.options 對象下的屬性,嵌入到模板 html 下。
所以這里的生成結(jié)果是:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>前端西瓜哥的博客</title>
<script defer src="app.d02c9155f73c92f51bf5.js"></script></head>
<body>
Stay hungry, stay foolish
</body>
</html>
因為使用了 lodash.template 模板渲染豐富,除了可以嵌入變量的值,還支持判斷條件、循環(huán)等特性,基本上可以滿足我們的絕大多數(shù)場景。
HTML Webpack Plugin 是被廣泛使用的 webpack 插件,用來將我們打包出來的文件自動嵌入到一個模板 HTML 中。
實際開發(fā)中,通常我們會使用自己編寫的 html 模板。
我是前端西瓜哥,熱衷于分享前端知識,歡迎關(guān)注我。
HTML Webpack Plugin這是一個webpack插件,它簡化了HTML文件的創(chuàng)建,以服務(wù)于你的webpack bundle。這對于在文件名中包含哈希的webpack包特別有用,因為文件名會改變每次編譯。您可以讓插件為您生成一個HTML文件,或者使用lodash模板提供您自己的模板,或者使用您自己的加載器。
針對webpack的版本,需要安裝對應(yīng)不同的版本。
webpack4
npm i --save-dev html-webpack-plugin@4
webpack5
npm i --save-dev html-webpack-plugin
這個插件會為你生成一個HTML5文件,其中包含了使用script標(biāo)簽的所有webpack的bundle。
只需將插件添加到webpack配置中,如下所示:
const path = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
entry: "./src/index.js",
output: {
filename:"index_bundle.js",
path: path.resolve(__dirname,"dist")
},
plugins: [
new HtmlWebpackPlugin()
]
}
這將生成一個包含以下內(nèi)容的文件dist/index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack App</title>
</head>
<body>
<script src="index_bundle.js"></script>
</body>
</html>
如果您有多個webpack入口點,它們都將與script標(biāo)簽一起包含在生成的HTML中。
如果你在webpack的輸出中有任何CSS資產(chǎn)(例如,用mini-css-extract-plugin提取的CSS),那么這些將包含在HTML頭部的標(biāo)簽中。
如果你有使用它的插件,html-webpack-plugin應(yīng)該在任何集成插件之前。
你可以傳遞一個配置選項到html-webpack-plugin。允許的值如下:
類型:String
默認(rèn)值:Webpack App
描述:要用于生成的HTML文檔的標(biāo)題。
類型:String或Function
默認(rèn)值:index.html
描述:要寫入HTML的文件的文件名。默認(rèn)為index.html。您也可以在這里指定一個子目錄(例如:assets/admin.html)。占位符[name]將被條目名稱替換。也可以是一個函數(shù),例如(entryName) => entryName + '.html'。
類型:String
默認(rèn)值:空
描述:默認(rèn)情況下,它將使用src/index.ejs(如果存在的話)。
類型:string|Function|false
默認(rèn)值:false
描述:可以用來代替模板提供一個內(nèi)聯(lián)模板。
類型:Boolean|Object|Function
默認(rèn)值:false
描述:允許覆蓋模板中使用的參數(shù)。
類型:Boolean|String
默認(rèn)值:true
描述:true || 'head' || 'body' || false將所有資產(chǎn)注入到給定的模板或templateContent中。當(dāng)傳遞'body'時,所有javascript資源將被放置在body元素的底部。'head'將把腳本放置在head元素中。設(shè)置為true時,將根據(jù)scriptLoading選項,決定是把腳本添加到head還是body中。使用false禁用自動注入。
類型:String|'auto'
默認(rèn)值:auto
描述:publicPath屬性值用于script和link 標(biāo)簽。
類型:blocking|defer
默認(rèn)值:defer
描述:現(xiàn)代瀏覽器支持非阻塞javascript加載(“defer”),以提高頁面啟動性能。
類型:String
默認(rèn)值:空
描述:將給定的圖標(biāo)路徑添加到輸出的HTML中。
類型:Object
默認(rèn)值:{}
描述:允許注入meta標(biāo)簽。例如:meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}。
類型:Object|String|false
默認(rèn)值:false
描述:注入一個base標(biāo)簽。如base:“https://example.com/path/page.html
類型:Boolean|Object
默認(rèn)值:如果mode為'production'則為true,否則為false
描述:控制是否以及以何種方式壓縮輸出。
類型:Boolean
默認(rèn)值:false
描述:如果為true,則附加一個唯一的webpack編譯哈希到所有包含的腳本和CSS文件。這對于緩存銷毀是很有用的
類型:Boolean
默認(rèn)值:true
描述:只有當(dāng)文件被更改時,才會刪除它。
類型:Boolean
默認(rèn)值:true
描述:錯誤的詳細(xì)信息將寫入HTML頁面。
類型:?
默認(rèn)值:?
描述:只允許添加一些chunk(例如:只添加unit-test 的chunk)
類型:String|Function
默認(rèn)值:auto
描述:允許控制塊在包含到HTML之前應(yīng)該如何排序。允許的值是'none' | 'auto' | 'manual' | {Function}。
類型:Array.<string>
默認(rèn)值:空
描述:允許你跳過一些chunk(例如不添加unit-test 的chunk)。
類型:Boolean
默認(rèn)值:false
描述:如果為true,則將link標(biāo)簽呈現(xiàn)為自動關(guān)閉(XHTML兼容)
下面是一個webpack配置示例,演示了如何使用這些選項:
{
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
title: 'My App',
filename: 'assets/admin.html'
})
]
}
要生成多個HTML文件,請在插件數(shù)組中多次聲明插件。
配置示例:
{
entry: 'index.js',
output: {
path: __dirname + '/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'
})
]
}
如果默認(rèn)生成的HTML不能滿足您的需要,您可以提供自己的模板。最簡單的方法是使用template選項并傳遞一個定制的HTML文件。html-webpack-plugin會自動將所有必需的CSS, JS, manifest和favicon文件注入到標(biāo)記中。
配置文件的部分內(nèi)容:
plugins: [
new HtmlWebpackPlugin({
title: 'Custom template',
// Load a custom template (lodash by default)
template: 'index.html'
})
]
模板文件index.html的內(nèi)容:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
</body>
</html>
如果您已經(jīng)有一個模板加載器,您可以使用它來解析模板。請注意,如果您指定了html加載器并使用.html文件作為模板,也會發(fā)生這種情況。
module: {
loaders: [
{ test: /\.hbs$/, loader: "handlebars-loader" }
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'Custom template using Handlebars',
template: 'index.hbs'
})
]
您可以使用現(xiàn)成的lodash語法。如果inject特性不適合你的需要,而你又想完全控制資產(chǎn)的位置,可以使用html-webpack-template項目的默認(rèn)模板作為你自己編寫模板的起點。
Webpack 是一個強大的模塊打包工具,它的配置文件webpack.config.js
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。