html-webpack-plugin详解
引言
我们来看看主要作用:
为html文件中引入的外部资源如script
、link
动态添加每次compile后的hash,防止引用缓存的外部文件问题
可以生成创建html入口文件,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin
可以生成N个页面入口
html-webpack-plugin
插件的基本作用就是生成html文件。原理很简单:
将 webpack中
`entry`配置的相关入口chunk 和
`extract-text-webpack-plugin`抽取的css样式 插入到该插件提供的
`template`或者
`templateContent`配置项指定的内容基础上生成一个html文件,具体插入方式是将样式
`link`插入到
`head`元素中,
`script`插入到
`head`或者
`body`中。
实例化该插件时可以不配置任何参数,例如下面这样:
- var HtmlWebpackPlugin = require('html-webpack-plugin')
- webpackconfig = {
- plugins: [
- new HtmlWebpackPlugin()
- ]
- }
不配置任何选项的html-webpack-plugin
插件,他会默认将webpack中的entry
配置所有入口thunk和extract-text-webpack-plugin
抽取的css样式都插入到文件指定的位置。例如上面生成的html文件内容如下:
- <!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>
当然可以使用具体的配置项来定制化一些特殊的需求,那么插件有哪些配置项呢?
html-webpack-plugin配置项
插件提供的配置项比较多,通过源码可以看出具体的配置项如下:
- this.options = _.extend({
- template: path.join(__dirname, 'default_index.ejs'),
- templateParameters: templateParametersGenerator,
- filename: 'index.html',
- hash: false,
- inject: true,
- compile: true,
- favicon: false,
- minify: false,
- cache: true,
- showErrors: true,
- chunks: 'all',
- excludeChunks: [],
- chunksSortMode: 'auto',
- meta: {},
- title: 'Webpack App',
- xhtml: false
- }, options);
title
: 生成的html文档的标题。配置该项,它并不会替换指定模板文件中的title元素的内容,除非html模板文件中使用了模板引擎语法来获取该配置项值,如下ejs模板语法形式:
- <title>
{%= o.htmlWebpackPlugin.options.title %}
</title>
filename
:输出文件的文件名称,默认为index.html,不配置就是该文件名;此外,还可以为输出文件指定目录位置(例如'html/index.html')
- 关于filename补充两点:
1、filename配置的html文件目录是相对于webpackConfig.output.path路径而言的,不是相对于当前项目目录结构的。
2、指定生成的html文件内容中的link
和script
路径是相对于生成目录下的,写路径的时候请写生成目录下的相对路径。
template
: 本地模板文件的位置,支持加载器(如handlebars、ejs、undersore、html等),如比如 handlebars!src/index.hbs
;
- 关于template补充几点:
1、template配置项在html文件使用file-loader
时,其所指定的位置找不到,导致生成的html文件内容不是期望的内容。
2、为template指定的模板文件没有指定任何loader的话,默认使用ejs-loader
。如template:
,若没有为
'./index.html'.html
指定任何loader就使用ejs-loader
templateContent:
string|function,可以指定模板的内容,不能与template共存。配置值为function时,可以直接返回html字符串,也可以异步调用返回html字符串。
inject
:向template或者templateContent中注入所有静态资源,不同的配置值注入的位置不经相同。
1、true或者body:所有JavaScript资源插入到body元素的底部
2、head:
所有JavaScript资源插入到head元素中
3、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页面
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
webpack的stats对象
;注意一点:
这个可以访问的stats
对象是htm文件生成时所对应的stats
对象,而不是webpack运行完成后所对应的整个stats
对象。
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
映射的值。例如对应上面配置插件各个属性配置项例子中生成的数据格式如下:
- "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插件在插入静态资源时存在一些问题:
- 在插入js资源只能插入head或者body元素中,不能一些插入head中,另一些插入body中
- 不支持在html中文件内联*,例如在文件的某个地方用
<script src="xxx.js?__inline"></script>
来内联外部脚本
为此,有人专门给插件作者提问了这个问题;对此插件作者提供了插件事件,允许其他插件来改变html文件内容。具体的事件如下:
Async(异步事件):
* html-webpack-plugin-
before-html-generation
* html-webpack-plugin-
before-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: ''})
- ]
html-webpack-plugin详解的更多相关文章
- vue-cli 中的 webpack 配置详解
本篇文章主要介绍了 vue-cli 2.8.2 中的 webpack 配置详解, 做个学习笔记 版本 vue-cli 2.8.1 (终端通过 vue -V 可查看) vue 2.2.2 webpack ...
- webpack配置详解
webpack配置详解 先点个赞吧,再挨个点下面的连接,觉得不值这个赞的回来骂我啊. Webpack傻瓜式指南(一) Webpack傻瓜指南(二)开发和部署技巧 Webpack傻瓜式指南 原生的官网详 ...
- webpack入门详解
webpack入门详解(基于webpack 3.5.4 2017-8-22) webpack常用命令: webpack --display-error-details //执行打包 webpa ...
- vue-cli中webpack配置详解
vue-cli是构建vue单页应用的脚手架,命令行输入vue init <template-name> <project-name>从而自动生成的项目模板,比较常用的模板有we ...
- mysql 5.7.12 新增 X plugin 详解
https://dev.mysql.com/doc/refman/5.7/en/document-store.html 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息 ...
- Spring Boot的Maven插件Spring Boot Maven plugin详解
Spring Boot的Maven插件(Spring Boot Maven plugin)能够以Maven的方式为应用提供Spring Boot的支持,即为Spring Boot应用提供了执行Mave ...
- 10. vue之webpack打包详解
一.什么是webpack webpack官网给出的定义是 本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler).当 webpack 处理应 ...
- 从零学脚手架(三)---webpack属性详解
如果此篇对您有所帮助,在此求一个star.项目地址: OrcasTeam/my-cli 在上一篇中,介绍了webpack的entry.output.plugins属性. 在这一篇,接着介绍其它配置属性 ...
- 详解前端模块化工具-webpack
webpack是一个module bundler,抛开博大精深的汉字问题,我们暂且管他叫'模块管理工具'.随着js能做的事情越来越多,浏览器.服务器,js似乎无处不在,这时,使日渐增多的js代码变得合 ...
- webpack安装配置使用教程详解
webpack安装配置使用教程详解 www.111cn.net 更新:2015-09-01 编辑:swteen 来源:转载 本文章来为各位详细的介绍一下关于webpack安装配置使用教程吧,这篇文章对 ...
随机推荐
- python学习——读取染色体长度(一、简化问题)
# 读取fasta # 解析每条序列的长度 chr1_len = 10 chr2_len = 20 chr3_len = 30 chr4_len = 40 chr5_len = 50 # 求和 tot ...
- Python--day11(函数的参数)
今日主要内容 1. 函数的参数 2. 函数的嵌套调用 1. 形参与实参 1. 参数介绍: 函数为什么要有参数:因为内部的函数体需要外部的数据 怎样定义函数的参数:在定义函数阶段,函数名在后面( ...
- 腾讯通信云服务端使用心得,腾讯云IM
腾讯通信云服务端使用心得 1.腾讯通信服务入口并创建应用 方便使用保留url地址 : https://cloud.tencent.com/product/im 注册账号腾讯云账号->通过审核 ...
- 01-jQuery基本语法
一.jQuery基础 1.为什么要用jquery? 写起来简单,省事,开发效率高,兼容性好2.什么是jQuery? jQuery是一个兼容多浏览器的JavaScript库(类似python里面的模块) ...
- PL2303HX在Windows 10下面不装安装驱动的解决办法(Code:10)
Prolific在很早之前推出了一款名为PL2303HX的芯片, 用于USB转RS232, 这款芯片使用的范围非常广, 并且年代久远. 但是这款芯片因为用的特别多, 所以中国就有很多厂家生产了仿造的P ...
- 快速去水印(win10换图3D工具)
之前抠图都用ps啥的,后来发现win10自带的工具画图3D可以直接扣简单的图案,达到去水印的效果 1.将图片放入软件中 2.使用神奇选择工具,调整大小,框出图标 3.点击下一步,将没选上的或选多的进行 ...
- spring boot下使用logback或log4j生成符合Logstash标准的JSON格式
spring boot下使用logback或log4j生成符合Logstash标准的JSON格式 一.依赖 由于配置中使用了json格式的日志输出,所以需要引入如下依赖 "net.logst ...
- visp库中解决lapack库的问题
解决的办法是——绕过去,不要用这个库: 使用中发现如下代码抛出异常: //vpTemplateTracker.cpp try { initHessienDesired(I); ptTemplateSu ...
- CF235B Let's Play Osu! 期望DP
貌似是一道很裸的期望\(DP\).直接说思路: 设\(f[i]\)表示到\(i\)位置时的期望分数,但是只有\(f[i]\)的话我们发现是无法转移的,我们还需要知道到\(i\)位置时的期望连续长度,于 ...
- DDCTF-2019
Web 滴 Web 签到题 Web 大吉大利,今晚吃鸡 1)滴 网址http://117.51.150.246/index.php?jpg=TmpZMlF6WXhOamN5UlRaQk56QTJOdz ...