一个插件,它简化了HTML文件的创建以服务于您的bundle
安装
npm i --save-dev html-webpack-plugin
yarn add --dev html-webpack-plugin
这是一个webpack插件,它简化了HTML文件的创建,为您的webpack包提供服务。这对于在文件名中包含哈希值的webpack包包特别有用,它会在每次编译更改。你可以让插件为你生成一个HTML文件,使用lodash模板提供你自己的模板,或者使用你自己的加载程序。
零配置
html-webpack-plugin无需配置即可工作。
这是对webpack-config-plugins.的一个很好的补充。
插件
html-webpack-plugin提供hooks来扩展你的网页包。已经有一些非常强大的插件可以与零配置集成
- webpack-subresource-integrity 提高资产安全性
- appcache-webpack-plugin 对于iOS和Android脱机使用
- favicons-webpack-plugin 它为iOS、Android和桌面浏览器生成favicons和图标
- html-webpack-harddisk-plugin 可用于始终将html文件写入磁盘,在使用webpack dev server/HMR时非常有用
- html-webpack-inline-source-plugin 将资产内联到生成的HTML文件中
- html-webpack-inline-svg-plugin 在生成的HTML文件中内联svg。
- html-webpack-exclude-assets-plugin 用于使用正则表达式排除资源
- html-webpack-include-assets-plugin 用于包含js或css文件路径的列表(例如由copy webpack插件复制的那些)。
- script-ext-html-webpack-plugin 向script元素添加async、defer或module属性,甚至内联它们
- style-ext-html-webpack-plugin 将外部样式转换为包含内部样式表的元素
- html-webpack-injector 在同一个html文档的头或体(不同的位置)中注入块。
- resource-hints-webpack-plugin 使用和
- preload-webpack-plugin 用于使用帮助延迟加载自动连接异步(和其他类型)JavaScript块
- link-media-html-webpack-plugin 允许注入样式表标记自动设置其媒体属性;对于提供浏览器将有条件下载的特定desktop/mobile/print等样式表非常有用
- inline-chunk-manifest-html-webpack-plugin 用于内联webpack的chunk manifest。默认提取manifest内联到
- html-webpack-inline-style-plugin 用于使用juice将样式内联到HTML元素。有助于电子邮件生成自动化。
- html-webpack-exclude-empty-assets-plugin 删除添加到html中的空资产。这修复了webpack4中的extract-text-plugin的一些问题。
- webpack-concat-plugin 对于concat和uglify文件,不需要是webpack bundle(对于遗留文件)并注入到html-webpack-plugin。
- html-webpack-link-type-plugin 将可配置的mimetype添加到作为链接注入的资源中(例如将type=“text/css”添加到外部样式表中),以与“strict mode”兼容。
- csp-html-webpack-plugin 向HTML输出添加内容安全策略元标记
- webpack-nomodule-plugin 允许您向特定的注入脚本添加nomodule属性,以防止脚本被较新的浏览器加载。有利于限制填充物的负荷。
- html-webpack-skip-assets-plugin 跳过将某些输出文件添加到html文件。内置为html-webpack-exclude-assets-plugin 的一个替换插件,适用于较新的 html-webpack-plugin版本
使用
该插件将为您生成一个HTML5文件,该文件使用脚本标记在主体中包含所有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入口点,它们都将包含在生成的HTML中的脚本标记中。
如果你在webpack的输出中有任何CSS资产(例如,用mini-css-extract-plugin提取的CSS),那么这些资产将包含在HTML头部的标记中。
如果你有使用它的插件,html-webpack-plugin应该在任何集成插件之前排序。
选项
下面是一个示例webpack config,说明如何使用这些选项
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-webpack-plugin。允许值如下
title
Type:{String}
Default:Webpack App
描述:注释用于生成的HTML文档的标题
filename
Type:{String}
Default:'index.html'
描述:要写入HTML的文件。默认为index.html. 你也可以在这里指定一个子目录(例如:assets/admin.html)
template
Type:{String}
Default:``
描述:指向模板的相对路径或绝对路径。默认情况下,它将使用src/index.ejs如果它存在的话。详情请参阅文件
templateContent
Type:{string|Function|false}
Default:false
描述:可以代替模板来提供内联模板-请阅读“编写自己的模板”部分
templateParameters
Type:{Boolean|Object|Function}
Default:false
描述:允许覆盖模板中使用的参数-请参阅示例
inject
Type:{Boolean|String}
Default:true
描述:true | |“head”| body“|false 将所有资产注入给定模板或模板内容。当传递true或'body'时,所有javascript资源都将放在body元素的底部,'head'将把脚本放在head元素中-参见inject:false示例
scriptLoading
Type:{'blocking'|'defer
Default:'blocking'
描述:现代浏览器支持非阻塞javascript加载(“defer”)以提高页面启动性能。
favicon
Type:{String}
Default:``
描述:将给定的favicon路径添加到输出HTML
meta
Type:{Object}
Default:{}
描述:允许注入元标记,例如 meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}
base
Type:{Object|String|false}
Default:false
描述:插入base标记。例如,base: "example.com/path/page.h…
minify
Type:{Boolean|Object}
Default: 如果 mode 是 'production'为true, 否则的话为false
描述:控制是否以及以何种方式缩小输出。更多细节请参见下面的缩小。
hash
Type:{Boolean}
Default:false
描述:如果为true,则将唯一的webpack编译哈希附加到所有包含的脚本和CSS文件。这对于缓存破坏非常有用
cache
Type:{Boolean}
Default:true
描述:仅当文件被更改时才发出该文件
showErrors
Type:{Boolean}
Default:true
描述:错误详细信息将写入HTML页面
chunks
Type:{?}
Default:?
描述:允许您只添加一些块(例如,只添加单元测试块)
chunksSortMode
Type:{String|Function}
Default:auto
描述:允许控制块在包含到HTML之前应如何排序。允许的值是“none”|“auto”|“manual”|{Function}
excludeChunks
Type:{Array.}
Default:``
描述:允许您跳过一些块(例如不添加单元测试块)
xhtml
Type:{Boolean}
Default:false
描述:如果为真,则将链接标记呈现为自动关闭(符合XHTML)
生成多个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网页包插件会自动将所有必需的CSS、JS、manifest和favicon文件注入到标记中。
其他模板loaders的详细信息在这里进行了记录。
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>
如果您已经有一个模板加载器,您可以使用它来解析模板。请注意,如果指定html加载程序并使用.html文件作为模板,也会发生这种情况。
module: {
loaders: [
{ test: /\.hbs$/, loader: "handlebars-loader" }
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'Custom template using Handlebars',
template: 'index.hbs'
})
]
你可以使用lodash 的语法。如果注入功能不符合您的需要,并且您希望完全控制资产放置,请使用 html-webpack-template project的默认模板作为编写自己的模板的起点。
默认情况下,模板中提供以下变量(可以使用templateParameters选项扩展它们):
- htmlWebpackPlugin:特定于此插件的数据
-
htmlWebpackPlugin.options:传递给插件的选项哈希。除了此插件实际使用的选项外,您还可以使用此哈希将任意数据传递到模板中。
-
htmlWebpackPlugin.tags: 准备好的headTags和bodyTags数组来呈现、、script和标记。可以直接在模板和文字中使用。例如:
<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.publicPath).
- compilation: webpack编译对象。例如,这可以用于获取已处理资产的内容,并将其直接内联到页面中compilation.assets[...].source() (请参阅内联模板示例)。
模板也可以直接内联到options对象中。
templateContent不允许对模板使用webpack loaders加载程序,并且不会监视模板文件的更改
webpack.config.js
new HtmlWebpackPlugin({
templateContent: `
<html>
<body>
<h1>Hello World</h1>
</body>
</html>
`
})
templateContent还可以访问所有templateParameters值
templateContent不允许对模板使用webpack loaders加载程序,并且不会监视模板文件的更改
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>
`
})
过滤块
为了只包含某些块,可以限制正在使用的块
webpack.config.js
plugins: [
new HtmlWebpackPlugin({
chunks: ['app']
})
]
也可以通过设置excludeChunks选项排除某些块
webpack.config.js
plugins: [
new HtmlWebpackPlugin({
excludeChunks: [ 'dev-helper' ]
})
]
Minification
如果minify选项设置为true(当webpack的模式为“production”时为默认值),则生成的HTML将使用 html-minifier-terser和以下选项进行缩小:
{
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true
}
若要使用自定 html-minifier options ,请将对象传递给minify。此对象不会与上述默认值合并。
要在生产模式期间禁用缩小,请将minify选项设置为false。
Meta Tags
如果设置了meta选项,则html-webpack-plugin将注入meta标记。
对于默认模板,hhtml-webpack-plugin 已经为viewport meta标记提供了一个默认值。
请看一下这个维护良好的几乎所有可能的元标记的列表。
name/content meta tags
大多数元标记都是通过设置名称和内容属性来配置的。
要添加这些值,请使用键/值对:
webpack.config.js
plugins: [
new HtmlWebpackPlugin({
'meta': {
'viewport': 'width=device-width, initial-scale=1, shrink-to-fit=no',
// Will generate: <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
'theme-color': '#4285f4'
// Will generate: <meta name="theme-color" content="#4285f4">
}
})
]
模拟http响应头
http-equiv属性本质上用于模拟http响应头。
使用对象表示法支持此格式,它允许您添加任何属性:
webpack.config.js
plugins: [
new HtmlWebpackPlugin({
'meta': {
'Content-Security-Policy': { 'http-equiv': 'Content-Security-Policy', 'content': 'default-src https:' },
// Will generate: <meta http-equiv="Content-Security-Policy" content="default-src https:">
// Which equals to the following http header: `Content-Security-Policy: default-src https:`
'set-cookie': { 'http-equiv': 'set-cookie', content: 'name=value; expires=date; path=url' },
// Will generate: <meta http-equiv="set-cookie" content="value; expires=date; path=url">
// Which equals to the following http header: `set-cookie: value; expires=date; path=url`
}
})
]
Base Tag
当使用base选项时,html-webpack-plugin将注入一个基标记。默认情况下,不会注入基标记。
以下两个相同,都将插入<base href=“example.com/some/page.h…:
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'
}
})
会注入元素.
长期缓存
对于长期缓存,请在文件名中添加contenthash/templatehash。
plugins: [
new HtmlWebpackPlugin({
filename: 'index.[contenthash].html'
})
]
contenthash/templatehash是输出文件内容的哈希。 或者,您可以配置
[<hashType>:contenthash:<digestType>:<length>]
- hashType - sha1、md5、sha256、sha512或任何其他类型之一node.js支持的哈希类型
- digestType -hex, base26, base32, base36, base49, base52, base58, base62, base64之一
- maxlength -生成的哈希的最大长度(以字符为单位)
Defaults:
[md5:contenthash:hex:9999]
事件
为了允许其他插件修改HTML,这个插件执行tapable钩子。
lib/hooks.js包含有关传递哪些值的所有信息。
beforeAssetTagGeneration hook
AsyncSeriesWaterfallHook<{
assets: {
publicPath: string,
js: Array<{string}>,
css: Array<{string}>,
favicon?: string | undefined,
manifest?: string | undefined
},
outputName: string,
plugin: HtmlWebpackPlugin
}>
alterAssetTags hook
AsyncSeriesWaterfallHook<{
assetTags: {
scripts: Array<HtmlTagObject>,
styles: Array<HtmlTagObject>,
meta: Array<HtmlTagObject>,
},
outputName: string,
plugin: HtmlWebpackPlugin
}>
alterAssetTagGroups hook
AsyncSeriesWaterfallHook<{
headTags: Array<HtmlTagObject | HtmlTagObject>,
bodyTags: Array<HtmlTagObject | HtmlTagObject>,
outputName: string,
plugin: HtmlWebpackPlugin
}>
afterTemplateExecution hook
AsyncSeriesWaterfallHook<{
html: string,
headTags: Array<HtmlTagObject | HtmlTagObject>,
bodyTags: Array<HtmlTagObject | HtmlTagObject>,
outputName: string,
plugin: HtmlWebpackPlugin,
}>
beforeEmit hook
AsyncSeriesWaterfallHook<{
html: string,
outputName: string,
plugin: HtmlWebpackPlugin,
}>
afterEmit hook
AsyncSeriesWaterfallHook<{
outputName: string,
plugin: HtmlWebpackPlugin
}>
实施示例:webpack-subresource-integrity
plugin.js
// If your plugin is direct dependent to the html webpack plugin:
const HtmlWebpackPlugin = require('html-webpack-plugin');
// If your plugin is using html-webpack-plugin as an optional dependency
// you can use https://github.com/tallesl/node-safe-require instead:
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,以便将其传递给监听相同beforeeemit事件的任何其他插件