plugin是用于扩展webpack的功能,各种各样的plugin几乎可以让webpack做任何与构建先关的事情。
plugin的配置很简单,plugins配置项接收一个数组,数组里的每一项都是一个要使用的plugin的实例,plugin需要的参数通过构造函数传入。
举个栗子
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({ // 打包输出HTML
title: 'Hello World app',
minify: { // 压缩HTML文件
removeComments: true, // 移除HTML中的注释
collapseWhitespace: true, // 删除空白符与换行符
minifyCSS: true// 压缩内联css
},
filename: 'index.html',
template: 'index.html'
}),
]
使用plugin的难点在于plugin本身的配置项,而不是如何在webpack中引入plugin,几乎所有webpack无法直接实现的功能,都能找到开源的plugin去解决,我们要做的就是去找更据自己的需要找出相应的plugin。
这个plugin曝光率很高,他主要有两个作用
生成html文件的标题
输出的html的文件名称
html模板所在的文件路径
根据自己的指定的模板文件来生成特定的 html 文件。这里的模板类型可以是任意你喜欢的模板,可以是 html, jade, ejs, hbs, 等等,但是要注意的是,使用自定义的模板文件时,需要提前安装对应的 loader, 否则webpack不能正确解析。
如果你设置的 title 和 filename于模板中发生了冲突,那么以你的title 和 filename 的配置值为准。
注入选项。有四个选项值 true, body, head, false.
给生成的 html 文件生成一个 favicon。属性值为 favicon 文件所在的路径名
minify 的作用是对 html 文件进行压缩,minify 的属性值是一个压缩选项或者 false 。默认值为false, 不对生成的 html 文件进行压缩。
下面罗列了一些常用的配置:
plugins:[
new HtmlWebpackPlugin({
//部分省略,具体看minify的配置
minify: {
//是否对大小写敏感,默认false
caseSensitive: true,
//是否简写boolean格式的属性如:disabled="disabled" 简写为disabled 默认false
collapseBooleanAttributes: true,
//是否去除空格,默认false
collapseWhitespace: true,
//是否压缩html里的css(使用clean-css进行的压缩) 默认值false;
minifyCSS: true,
//是否压缩html里的js(使用uglify-js进行的压缩)
minifyJS: true,
//Prevents the escaping of the values of attributes
preventAttributesEscaping: true,
//是否移除属性的引号 默认false
removeAttributeQuotes: true,
//是否移除注释 默认false
removeComments: true,
//从脚本和样式删除的注释 默认false
removeCommentsFromCDATA: true,
//是否删除空属性,默认false
removeEmptyAttributes: true,
// 若开启此项,生成的html中没有 body 和 head,html也未闭合
removeOptionalTags: false,
//删除多余的属性
removeRedundantAttributes: true,
//删除script的类型属性,在h5下面script的type默认值:text/javascript 默认值false
removeScriptTypeAttributes: true,
//删除style的类型属性, type="text/css" 同上
removeStyleLinkTypeAttributes: true,
//使用短的文档类型,默认false
useShortDoctype: true,
}
}),
]
hash选项的作用是 给生成的 js 文件一个独特的 hash 值,该 hash 值是该次 webpack 编译的 hash 值。默认值为 false 。同样看一个例子。
plugins: [
new HtmlWebpackPlugin({
hash: true
})
]
编译打包后
<script type=text/javascript src=bundle.js?22b9692e22e7be37b57e></script>
执行 webpack 命令后,你会看到你的生成的 html 文件的 script 标签内引用的 js 文件,是不是有点变化了。
bundle.js 文件后跟的一串 hash 值就是此次 webpack 编译对应的 hash 值。
默认是true的,表示内容变化的时候生成一个新的文件。
这个我们自运行项目的时候经常会用到,showErrors 的作用是,如果 webpack 编译出现错误,webpack会将错误信息包裹在一个 pre 标签内,属性的默认值为 true ,也就是显示错误信息。
开启这个,方便定位错误
chunks主要用于多入口文件,当你有多个入口文件,那就回编译后生成多个打包后的文件,那么chunks 就能选择你要使用那些js文件
entry: {
index: path.resolve(__dirname, './src/index.js'),
devor: path.resolve(__dirname, './src/devor.js'),
main: path.resolve(__dirname, './src/main.js')
}
plugins: [
new httpWebpackPlugin({
chunks: ['index','main']
})
]
那么编译后:
<script type=text/javascript src="index.js"></script>
<script type=text/javascript src="main.js"></script>
而如果没有指定 chunks 选项,默认会全部引用。
排除掉一些js,
entry: {
index: path.resolve(__dirname, './src/index.js'),
devor: path.resolve(__dirname, './src/devor.js'),
main: path.resolve(__dirname, './src/main.js')
}
plugins: [
new httpWebpackPlugin({
excludeChunks: ['devor.js']//和的等等效
})
]
那么编译后:
<script type=text/javascript src="index.js"></script>
<script type=text/javascript src="main.js"></script>
用最新版本的的 html-webpack-plugin你可能还会遇到如下的错误:
throw new Error('Cyclic dependency' + nodeRep)
产生这个 bug 的原因是循环引用依赖,如果你没有这个问题可以忽略。
目前解决方案可以使用 Alpha 版本,npm i --save-dev html-webpack-plugin@next
或者加入chunksSortMode: 'none'就可以了。
但仔细查看文档发现设置成chunksSortMode: 'none'这样是会有问题的。
这属性会决定你 chunks 的加载顺序,如果设置为none,你的 chunk 加载在页面中加载的顺序就不能够保证了,可能会出现样式被覆盖的情况。比如我在app.css里面修改了一个第三方库element-ui的样式,通过加载顺序的先后来覆盖它,但由于设置为了none,打包出来的结果变成了这样:
<link href="/app.8945fbfc.css" rel="stylesheet">
<link href="/chunk-elementUI.2db88087.css" rel="stylesheet">
app.css被先加载了,之前写的样式覆盖就失效了,除非你使用important或者其它 css 权重的方式覆盖它,但这明显是不太合理的。
vue-cli正好也有这个相关 issue,尤雨溪也在不使用@next版本的基础上 hack 了它,有兴趣的可以自己研究一下,
其它 html-webpack-plugin 的配置和之前使用没有什么区别。