HTML Webpack Plugin(英译中)
原文地址
HTML Webpack Plugin
----为打包时简化HTML文件生成的插件
下载
npm i --save-dev html-webpack-plugin
yarn add --dev html-webpack-plugin
这是一个可以在使用webpck打包时简化你的HTML文件生成的webpack插件。它对于webpck
打包尤其有用,例如在每次编译后在文件名中生成的hash值。你既可以让插件使用lodash
应用你自己的模板为你生成一个HTML文件,也可以使用你自己的loader。
用法
这个插件会为你生成一个HTML5文件,并在body中使用script标签引入了你所有webpack打包文件。只要在你的webpack配置文件中添加如下促代码:
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin()
]
}
它将会生成一个 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
标签引入到生成的HTML文件中。
如果你在webpack的出口中拥有多个CSS资源(例如,使用mini-css-extra-plugin提取出的CSS文件),它们都将会被使用<link>
标签引入到HTML的头部。
如果你有其它想要使用的插件,html-webpack-plugin
应当被第一个引入。
参数
你可以使用许多html-webpack-plugin
的配置参数。如下:
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
title | String | Webpack App | 用于生成HTML文档的title |
filename | String | 'index.html' | 将HTML写入的文件。默认为index.html 。你也可以在此外指定一个子目录(如assets/admin.html ) |
template | String | `` | webpack中到模板文件的相对或绝对路径。如果存在的话默认使用src/index.ejs 。更多 |
templateContent | string|Function|false | false | 可以代替template 用于提供一个嵌入式模板。更多 |
templateParameters | Boolean|Object|Function | false | 能够重写模板中的配置参数。例子 |
inject | Boolean|String | true | 使用`true |
scriptLoading | 'blocking'|'defer' | 'blocking' | 当代浏览器支持非阻塞javascript加载('defer' )来提高页面启动性能。 |
favicon | String | `` | 为输出的HTML文件提供 favicon 路径。 |
meta | Object | {} | 允许注入meta 标签。例如meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'} |
base | Object|String|false | false | 注入base 标签。例如base: "https://example.com/path/page.html |
minify | Boolean|Object | mode为‘production’时为true,否则为false | 用于控制输出文件的压缩方式。更多 |
hash | Boolean | false | 值为true 时将会为所有的script和CSS文件添加一个独特的webpack编译hash值。这对于清除缓存很有用。 |
cache | Boolean | true | 仅在文件被修改后提交文件 |
showErrors | Boolean | true | 错误信息将会被显示在HTML页面中。 |
chunks | ? | 允许你只添加指定的块文件(例如只添加unit-test块) | |
chunksSortMode | String|Function | auto | 允许你控制块文件在被引入HTML前的顺序。可用的值有`'none' |
excludeChunks | Array. |
`` | 允许你略过一些块文件(例如不添加 unit-test 块) |
xhtml | Boolean | false | 值为true时标签渲染为自动闭合(符合XHTML) |
例子
下面是一个描述怎样使用以上选项的webpack config 例子:
单个HTML文件
webpack.config.js
{
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
title: 'My App',
filename: 'assets/admin.html'
})
]
}
生成多个HTML文件
为了生成多个HTML文件,要在plugins数组中多次声明该插件
webpack.config.js
{
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'
})
]
}
书写你自己的模板
如果默认生成的HTML模板不能满足你的需求,你可以使用你自己的模板。最简单的方法是使用template
选项,传递一个自定义的HTML文件。html-webpack-plugin将会自动注入所有需要的CSS,JS,manifest以及favicon文件到标记中。
更多使用其它模板loader的描述在文档
plugins: [
new HtmlWebpackPlugin({
title: 'Custom template',
// Load a custom template (lodash by default)
template: 'index.html'
})
]
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
</body>
</html>
如果你已经的拥有了一个模板loader,你可以使用它来解析模板。需要注意的是当你指定html-loader以及使用 .html 文件也会发生这种情况。
webpack.config.js
module: {
loaders: [
{ test: /\.hbs$/, loader: "handlebars-loader" }
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'Custom template using Handlebars',
template: 'index.hbs'
})
]
你还可以直接使用lodash
语法。如果inject
功能不符合你的要求而你想要完全控制你的所有资源,你可以使用
html-webpack-plugin的默认模板作为你自定义模板编写的起点。
默认情况下,下面这些变量可以在模板中使用(你可以使用templateParameters
选项去扩展它们)。
-
htmlWebpackPlugin
:用于声明插件的data-
htmlWebpackPlugin.options
:传递给插件的hash值。除了此插件实际使用的选项之外,你还可以使用此hash值将任意数据传递到模板。 -
htmlWebpackPlugin.tags
:提前准备好的用于渲染<base>
,<meta>
,<script>
和<link>
标签的head标签和body标签。可以被直接在template和文字中使用。例如:<html> <head> <%= htmlWebpackPlugin.tags.headTags %> </head> <body> <%= htmlWebpackPlugin.tags.bodyTags %> </body> </html>
-
htmlWebpackPlugin.files
:直接访问编译时所使用和文件。publicPath: string; js: string[]; css: string[]; manifest?: string; favicon?: string;
-
-
webpackConfig
:在webpack编译时所使用的配置。例如,它可以用来获取publicPath(webpackConfig.output.pblicPath
) -
complilation
:webpack编译对象。例如,可以使用它来获取已处理资源的内容,并通过compilation.assets[...].source()
将它们直接内联到页面中。([例子][https://github.com/jantimon/html-webpack-plugin/blob/master/examples/inline/template.pug])
模板也可以直接内联到options对象中。
⚠️templateContent
不允许对模板使用webpack加载程序,并且不会监视模板文件的修改。
webpack.config.js
new HtmlWebpackPlugin({
templateContent: `
<html>
<body>
<h1>Hello World</h1>
</body>
</html>
`
})
templateContent
还可以访问所有的templateParameters
的值。
webpack.config.js
new HtmlWebpackPlugin({
inject: false,
templateContent: ({htmlWebpackPlugin}) => `
<html>
<head>
${htmlWebpackPlugin.tags.headTags}
</head>
<body>
<h1>Hello World</h1>
${htmlWebpackPlugin.tags.bodyTags}
</body>
</html>
`
})
过滤块 (Filtering Chunks)
可以用来限制仅使用某些特定的块。
webpack.config.js
plugins: [
new HtmlWebpackPlugin({
chunks: ['app']
})
]
也可以通过设置excludeChunks
选项来排除某些块文件。
webpack.config.js
plugins: [
new HtmlWebpackPlugin({
excludeChunks: [ 'dev-helper' ]
})
]
压缩文件 (Minification)
如果minify
选项被设置为true
时(生产环境下默认为true),生成的HTML文件将会使用html-minifier-terser
和以下的选项进行压缩:
{
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true
}
可以通过传递一个对象来自定义html-minifier
选项,他不会与上面的选项合并。
将minify
选项设为false
即可在生产环境下禁用压缩。
Meta 标签
如果设置了meta
选项,html-webpack-plugin将会注入meta标签。
在html-webpack-plugin的默认模板中已经注入了viewport
的meta标签。
[查看所有meta标签][https://github.com/joshbuchea/HEAD#meta]
name/content meta标签
大部分的meta标签都要通过设置name
和content
属性来配置。
可以使用健值对(key/value)来添加:
webpack.config.js
plugins: [
new HtmlWebpackPlugin({
'meta': {
'viewport': 'width=device-width, initial-scale=1, shrink-to-fit=no',
// 生成: <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
'theme-color': '#4285f4'
// 生成: <meta name="theme-color" content="#4285f4">
}
})
]
Base 标签
当设置了base
选项时,html-webpack-plugin将会注入一个base标签。base标签默认不会被引入。
下面两种不同的方法都能插入<base href="http://example.com/some/page.html">
:
new HtmlWebpackPlugin({
'base': 'http://example.com/some/page.html'
})
new HtmlWebpackPlugin({
'base': { 'href': 'http://example.com/some/page.html' }
})
可以用相应的值来指定target
:
new HtmlWebpackPlugin({
'base': {
'href': 'http://example.com/some/page.html',
'target': '_blank'
}
})
这样会插入一个<base href="http://example.com/some/page.html" target="_blank">
元素。
长期缓存 (Long Term Caching)
在文件名中添加contenthash/templatehash
来处理长期缓存。
例如
plugins: [
new HtmlWebpackPlugin({
filename: 'index.[contenthash].html'
})
]
contenthash/templatehash
是输出文件内容的hash值。
你可以像[<hashType>:contenthash:<disgestType>:<length>]
一样来配置:
hashType
:sha1
,md5
,sha512
中的任意一个或其它node.js支持和hash值类型。disgestType
:hex
,base26
,base32
,base36
,base49
,base52
,base62
,base64
中的任意一个。maxlength
:(以字符为单位)生成的hash值的最大长度。
默认值:[md5:contenthash:hex:9999]
事件 (Events)
该插件执行的能让其它插件更改HTML文件的tapable钩子函数。
lib/hook.js包含了所有能被传递的参数的信息。
beforeAssetTagGeneration
函数
AsyncSeriesWaterfallHook<{
assets: {
publicPath: string,
js: Array<{string}>,
css: Array<{string}>,
favicon?: string | undefined,
manifest?: string | undefined
},
outputName: string,
plugin: HtmlWebpackPlugin
}>
alterAssetTags
函数
AsyncSeriesWaterfallHook<{
assetTags: {
scripts: Array<HtmlTagObject>,
styles: Array<HtmlTagObject>,
meta: Array<HtmlTagObject>,
},
outputName: string,
plugin: HtmlWebpackPlugin
}>
afterTemplateExecution
函数
AsyncSeriesWaterfallHook<{
html: string,
headTags: Array<HtmlTagObject | HtmlTagObject>,
bodyTags: Array<HtmlTagObject | HtmlTagObject>,
outputName: string,
plugin: HtmlWebpackPlugin,
}>
beforeEmit
函数
AsyncSeriesWaterfallHook<{
html: string,
outputName: string,
plugin: HtmlWebpackPlugin,
}>
afterEmit
函数
AsyncSeriesWaterfallHook<{
outputName: string,
plugin: HtmlWebpackPlugin
}>
plugin.js
// 如果你的插件直接依赖于html-webpack-plugin:
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 如果你只是将html-webpack-plugin作为一个附属依赖
// 你可以使用 https://github.com/tallesl/node-safe-require:
const HtmlWebpackPlugin = require('safe-require')('html-webpack-plugin');
class MyPlugin {
apply (compiler) {
compiler.hooks.compilation.tap('MyPlugin', (compilation) => {
console.log('The compiler is starting a new compilation...')
// Static Plugin interface |compilation |HOOK NAME | register listener
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
'MyPlugin', // <-- Set a meaningful name here for stacktraces
(data, cb) => {
// Manipulate the content
data.html += 'The Magic Footer'
// Tell webpack to move on
cb(null, data)
}
)
})
}
}
module.exports = MyPlugin
webpack.config.js
plugins: [
new MyPlugin({ options: '' })
]
请注意,必须将回调传递给HtmlWebpackPluginData才能将其传递给侦听同一beforeEmit事件的其他任何插件。