咱们来看看主要做用:javascript
为html文件中引入的外部资源如script
、link
动态添加每次compile后的hash,防止引用缓存的外部文件问题css
能够生成建立html入口文件,好比单页面能够生成一个html文件入口,配置N个html-webpack-plugin
能够生成N个页面入口html
插件的基本做用就是生成html文件。原理很简单:java
`entry``extract-text-webpack-plugin``template``templateContent``link``head``script``head``body`将 webpack中配置的相关入口chunk 和 抽取的css样式 插入到该插件提供的或者配置项指定的内容基础上生成一个html文件,具体插入方式是将样式插入到元素中,插入到或者中。
实例化该插件时能够不配置任何参数,例以下面这样:webpack
var HtmlWebpackPlugin = require('html-webpack-plugin') webpackconfig = { plugins: [ new HtmlWebpackPlugin() ] }
不配置任何选项的html-webpack-plugin
插件,他会默认将webpack中的entry
配置全部入口thunk和extract-text-webpack-plugin
抽取的css样式都插入到文件指定的位置。例如上面生成的html文件内容以下:git
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Webpack App</title> <link href="index-af150e90583a89775c77.css" rel="stylesheet"></head> <body> <script type="text/javascript" src="common-26a14e7d42a7c7bbc4c2.js"></script> <script type="text/javascript" src="index-af150e90583a89775c77.js"></script></body> </html>
固然可使用具体的配置项来定制化一些特殊的需求,那么插件有哪些配置项呢?github
插件提供的配置项比较多,经过源码能够看出具体的配置项以下:web
1 this.options = _.extend({ 2 template: path.join(__dirname, 'default_index.ejs'), 3 templateParameters: templateParametersGenerator, 4 filename: 'index.html', 5 hash: false, 6 inject: true, 7 compile: true, 8 favicon: false, 9 minify: false, 10 cache: true, 11 showErrors: true, 12 chunks: 'all', 13 excludeChunks: [], 14 chunksSortMode: 'auto', 15 meta: {}, 16 title: 'Webpack App', 17 xhtml: false 18 }, options);
: 生成的html文档的标题。配置该项,它并不会替换指定模板文件中的title元素的内容,除非html模板文件中使用了模板引擎语法来获取该配置项值,以下ejs模板语法形式:title
<title></title>{%= o.htmlWebpackPlugin.options.title %}
filename
:输出文件的文件名称,默认为index.html,不配置就是该文件名;此外,还能够为输出文件指定目录位置(例如'html/index.html')数组
关于filename补充两点:
一、filename配置的html文件目录是相对于webpackConfig.output.path路径而言的,不是相对于当前项目目录结构的。
二、指定生成的html文件内容中的link
和script
路径是相对于生成目录下的,写路径的时候请写生成目录下的相对路径。缓存
template
: 本地模板文件的位置,支持加载器(如handlebars、ejs、undersore、html等),如好比 handlebars!src/index.hbs
;
关于template补充几点:
一、template配置项在html文件使用file-loader
时,其所指定的位置找不到,致使生成的html文件内容不是指望的内容。
二、为template指定的模板文件没有指定任何loader的话,默认使用ejs-loader
。如template: './index.html'
,若没有为.html
指定任何loader就使用ejs-loader
templateContent: string|function,能够指定模板的内容,不能与template共存。配置值为function时,能够直接返回html字符串,也能够异步调用返回html字符串。
inject
:向template或者templateContent中注入全部静态资源,不一样的配置值注入的位置不经相同。
一、true或者body:全部JavaScript资源插入到body元素的底部
二、head: 全部JavaScript资源插入到head元素中
三、false: 全部静态资源css和JavaScript都不会注入到模板文件中
favicon
: 添加特定favicon路径到输出的html文档中,这个同title
配置项,须要在模板中动态获取其路径值
hash
:true|false,是否为全部注入的静态资源添加webpack每次编译产生的惟一hash值,添加hash形式以下所示:
html <script type="text/javascript" src="common.js?a3e1396b501cdd9041be"></script>
chunks
:容许插入到模板中的一些chunk,不配置此项默认会将entry
中全部的thunk注入到模板中。在配置多个页面时,每一个页面注入的thunk应该是不相同的,须要经过该配置为不一样页面注入不一样的thunk;
excludeChunks
: 这个与chunks
配置项正好相反,用来配置不容许注入的thunk。
chunksSortMode
: none | auto| function,默认auto; 容许指定的thunk在插入到html文档前进行排序。
>function值能够指定具体排序规则;auto基于thunk的id进行排序; none就是不排序
xhtml
: true|fasle, 默认false;是否渲染link
为自闭合的标签,true则为自闭合标签
cache
: true|fasle, 默认true; 若是为true表示在对应的thunk文件修改后就会emit文件
showErrors
: true|false,默认true;是否将错误信息输出到html页面中。这个颇有用,在生成html文件的过程当中有错误信息,输出到页面就能看到错误相关信息便于调试。
minify
: {....}|false;传递 html-minifier 选项给 minify 输出,false就是不使用html压缩,minify具体配置参数请点击html-minifier
下面的是一个用于配置这些属性的一个例子:
new HtmlWebpackPlugin({ title:'rd平台', template: 'src/index.html', // 源模板文件 filename: './index.html', // 输出文件【注意:这里的根路径是module.exports.output.path】 showErrors: true, inject: 'body', chunks: ["common",'index'] })
html-webpack-plugin
的一个实例生成一个html文件,若是单页应用中须要多个页面入口,或者多页应用时配置多个html时,那么就须要实例化该插件屡次;
即有几个页面就须要在webpack的plugins数组中配置几个该插件实例:
…… plugins: [ new HtmlWebpackPlugin({ template: 'src/html/index.html', excludeChunks: ['list', 'detail'] }), new HtmlWebpackPlugin({ filename: 'list.html', template: 'src/html/list.html', thunks: ['common', 'list'] }), new HtmlWebpackPlugin({ filename: 'detail.html', template: 'src/html/detail.html', thunks: ['common', 'detail'] }) ] ...
如上例应用中配置了三个入口页面:index.html、list.html、detail.html;而且每一个页面注入的thunk不尽相同;相似若是多页面应用,就须要为每一个页面配置一个;
不带参数的html-webpack-plugin
默认生成的html文件只是将thunk和css样式插入到文档中,可能不能知足咱们的需求;
另外,如上面所述,三个页面指定了三个不一样html模板文件;在项目中,可能全部页面的模板文件能够共用一个,由于html-webpack-plugin
插件支持不一样的模板loader,因此结合模板引擎来共用一个模板文件有了可能。
因此,配置自定义模板就派上用场了。具体的作法,借助于模板引擎来实现,例如插件没有配置loader时默认支持的ejs模板引擎,下面就以ejs模板引擎为例来讲明;
例如项目中有2个入口html页面,它们能够共用一个模板文件,利用ejs模板的语法来动态插入各自页面的thunk和css样式,代码能够这样:
<!DOCTYPE html> <html style="font-size:20px"> <head> <meta charset="utf-8"> <title><%= htmlWebpackPlugin.options.title %></title> <% for (var css in htmlWebpackPlugin.files.css) { %> <link href="<%=htmlWebpackPlugin.files.css[css] %>" rel="stylesheet"> <% } %> </head> <body> <div id="app"></div> <% for (var chunk in htmlWebpackPlugin.files.chunks) { %> <script type="text/javascript" src="<%=htmlWebpackPlugin.files.chunks[chunk].entry %>"></script> <% } %> </body> </html>
你可能会对代码中的上下文htmlWebpackPlugin
数据感到迷惑,这是啥东东?其实这是html-webpack-plugin
插件在生成html文件过程当中产生的数据,这些数据对html模板文件是可用的,而且咱们看<%%>是否是给java里面的jsp差很少了。
html-webpack-plugin
在生成html文件的过程当中,插件会根据配置生成一个对当前模板可用的特定数据,模板语法能够根据这些数据来动态生成html文件的内容。
那么,插件生成的特殊数据格式是什么,生成的哪些数据呢?从源码或者其官网都给出了答案。从源码中能够看出模板引擎具体能够访问的数据以下:
var templateParams = { compilation: compilation, webpack: compilation.getStats().toJson(), webpackConfig: compilation.options, htmlWebpackPlugin: files: assets, options: self.options } };
从中能够看出,有四个主要的对像数据。其中compilation
为全部webpack插件提供的均可以访问的一个编译对象,此处就不太作介绍,具体能够本身查资料。下面就对剩下的三个对象数据进行说明。
webpack的stats对象
;注意一点:
这个能够访问的stats
对象是htm文件生成时所对应的stats
对象,而不是webpack运行完成后所对应的整个stats
对象。
webpack的配置项
;经过这个属性能够获取webpack的相关配置项,如经过webpackConfig.output.publicPath
来获取publicPath
配置。固然还能够获取其余配置内容。
html-webpack-plugin
插件对应的数据。它包括两部分:
htmlWebpackPlugin.files
: 这次html-webpack-plugin插件配置的chunk和抽取的css样式该files值实际上是webpack的stats对象的assetsByChunkName
属性表明的值,该值是插件配置的chunk块对应的按照webpackConfig.output.filename
映射的值。例如对应上面配置插件各个属性配置项例子中生成的数据格式以下:
"htmlWebpackPlugin": {
"files": {
"css": [ "inex.css" ],
"js": [ "common.js", "index.js"],
"chunks": {
"common": {
"entry": "common.js",
"css": [ "index.css" ]
},
"index": {
"entry": "index.js",
"css": ["index.css"]
}
}
}
}
这样,就能够是用以下模板引擎来动态输出script脚本
<% for (var chunk in htmlWebpackPlugin.files.chunks) { %> <script type="text/javascript" src="<%=htmlWebpackPlugin.files.chunks[chunk].entry %>"></script> <% } %>
htmlWebpackPlugin.options
: 传递给插件的配置项,具体的配置项如上面插件配置项小节所描述的。
不知道你发现没有,html-webpack-plugin插件在插入静态资源时存在一些问题:
<script src="xxx.js?__inline"></script>
来内联外部脚本为此,有人专门给插件做者提问了这个问题;对此插件做者提供了插件事件,容许其余插件来改变html文件内容。具体的事件以下:
Async(异步事件):
before * html-webpack-plugin--html-generation
before * html-webpack-plugin--html-processing
* html-webpack-plugin-alter-asset-tags
* html-webpack-plugin-after-html-processing
* html-webpack-plugin-after-emit
Sync(同步事件):
* html-webpack-plugin-alter-chunks
这些事件是提供给其余插件使用的,用于改变html的内容。所以,要用这些事件须要提供一个webpack插件。例以下面定义的MyPlugin
插件。
function MyPlugin(options) { // Configure your plugin with options... } MyPlugin.prototype.apply = function(compiler) { // ... compiler.plugin('compilation', function(compilation) { console.log('The compiler is starting a new compilation...'); compilation.plugin('html-webpack-plugin-before-html-processing', function(htmlPluginData, callback) { htmlPluginData.html += 'The magic footer'; callback(null, htmlPluginData); }); }); };
module.exports = MyPlugin;
而后,在webpack.config.js
文件中配置Myplugin
信息:
plugins: [ new MyPlugin({options: ''}) ]