原理
插件的基本作用就是生成html文件,原理很简单:
将 webpack 中 entry 配置的相关入口 chunk 和 extract-text-webpack-plugin 抽取的 css 样式 插入到该组件提供的 template 或者 templateContent 配置项指定的内容基础上生成一个 html 文件,具体插入方式是将样式 link 插入到 head 元素中, script 插入到 head 或者 body 中。
实例化该插件可以不配置任何参数:
const htmlWebpackPlugin=require('html-webpack-plugin'); webpackConfg={ ... plugins:[ ... new htmlWebpackPlugin(); ] }
不配置任何选项的 html-webpack-plugin 插件,他会默认将webpack中的entry配置所有入口thunk和extract-text-webpack-plugin抽取的css样式都插入到指定的位置。
配置项:
title
生成的html文档的标题。配置该项,它并不会替换指定模板文件中的title元素的内容,除非html模板文件中使用了模板引擎语法来获取改配置项值,如下ejs模板语法形式:
<title>{%= o.htmlWebpacPlugin.options.title %}</title>
filename
输出文件的文件名称,默认为index.html,不配置就是该文件名;此外,还可以为输出文件指定目录位置,例如html/index.html
filename配置的html文件目录是相对于webpackConfig.output.path路径而言的,不是相对于当前项目目录结构的。
指定生成的html文件内容中的link 和 script 路径是相对于生成目录下的写路径的时候请写生成目录下的相对路径。
template
本地模板文件的位置,支持加载器(handlebars ejs undersore html等)
template配置项在html文件使用file-loader时,其所指定的位置找不到,导致生成的html文件内容不是期望的内容。
为template指定的模板文件没有指定任何loader的话,默认使用ejs-loader。
templateContent
可以指定模板的内容,不能与template共存。
inject
向template或者templateContent中注入所有静态资源,不同的配置值注入的位置不经相同。
1 true/body 所有js资源插入到body元素的底部
2 head: 所有的js资源插入到head元素中
3 false 所有的静态资源css和js都不会注入到模板文件中
favicon
添加特定favicon路径到输出的html文档中,这个同title配置项,需要在模板中动态获取其路径值
hash
true|false,是否为所有注入的静态资源添加webpack每次编译生成的唯一hash值,
chunks
允许插入到模板中的一些chunk,不配置此项默认会将entry中所有的thunk注入到模板中,在配置多个页面时,每个页面注入的thunk应该时不相同的,需要通过该配置为不同页面注入不同的thunk。
excludeChunks
这个与chunks配置项正好相反
chunksSortMode
none|auto|function,默认auto;允许指定的thunk在插入到html文档前进行排序
配置多个html页面
需要实例化该插件多次
... 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-webpack-plugin 插件支持不同的模板loader,所以结合模板引擎来公用一个模板文件有了可能。
这时,配置自定义模板就派上用场了。具体的用法,借助模板引擎 来实现,例如插件没有设置loader时支持的ejs模板引擎,下面就以ejs模板引擎为例来说明;
例如项目中有2个入口html页面,它们可以公用一个模板文件,利用ejs模板的语法来动态插入各自页面的thunk和css样式,代码可以这样:
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title><%= htmlWebpackPlugin.options.title %></title></title> <% for(var css in htmlWebpackPlugin.files.css){ %> <link href="<%=htmlWebpackPlugin.files.css[css] %>" rel='stylesheet'> <% } %> <link> </head> <body> <div id='app'></div> <% for(var chunk in htmlWebpackPlugin.files.chunks) {%> <script type='text/script' src="<%=htmlWebpackPlugin.files.chunks[chunk].entry %>"></script> <% } %> </body> </html>
自定义模板上下文数据
html-webpack-plugin 在生成html文件的过程中,插件会根据配置生成一个对当前模板可用的特定数据,模板语法可以根据这些数据来动态生成html文件的内容。模板引擎具体可以访问的数据如下:
var templateParams={ compilation:compilation, webpack:compilation.getStats().toJson(), webpackConfig:compilation.options, htmlWebpackPlugin:{ files:assets, options:self.options } }
从中可以看出,有四个住哟啊的对象数据。其中 compilation 为所有webpack插件提供的都可以访问的一个编译对象
webpackConfig
webpack的配置项;通过这个属性可以获取webpack的相关配置项,如通过 webpackConfig.output.publicPath来获取publicPath配置,当然也可以获取其他配置内容
htmlWebpackPlugin
html-webpack-plugin插件对应的数据:
htmlWebpackPlugin.files:次html-webpack-plugin插件配置的chunk和抽取的css样式。该files值其实是webpack的stats对象的assetsByChunkName
属性代表的值,该值是插件配置的chunk块对应的按照webpackConfig.output.filename映射的值。