webpack4配置总结(五)

上一篇整理了babelpostcss-loader的配置,结束了webpack的loader部分。这边开始整理plugins

plugins

plugins插件是用来拓展webpack功能的。他们会在整个webpack打包构建过程中生效,执行相关的任务。插件与laoder不同,loader主要是处理某一些源文件的,用完就不需要了,但是插件是在一直作用于构建中。

使用插件时,需要先npm安装插件,然后在plugins属性下添加插件的实例。plugins属性接受的值是一个数组。

插件有很多,根据项目的需求使用的插件也不一样,不像loader那种可能比较固定。所以这里就结合项目需求来整理插件。

DefinePlugin

我们一般会需要在项目全局上设置一些常量,比如不同环境下,可能需要设定版本,不同的请求域名,可能需要标识常量来区分测试环境跟生产环境。但是在开发项目时,这些值可能需要在打包前根据打包的环境不同手动修改。如果常量不多还好,如果很多,容易改错,或者忘记修改,导致项目上线不正常。

DefinePlugin是webapck官方插件,这个插件允许创建一个在编译时可以配置的全局常量。这个插件就可以很好的解决这个问题。

这个插件允许用户自定义键值对,其中对键值有四个判断处理:

  1. 如果这个值是一个字符串,它会被当作一个代码片段来使用。
  2. 如果这个值不是字符串,它会被转化为字符串(包括函数)。
  3. 如果这个值是一个对象,它所有的 key 会被同样的方式定义。
  4. 如果在一个 key 前面加了 typeof,它会被定义为 typeof 调用。

使用时,直接使用常量即可,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// webpack配置
const webpack = require('webpack');
let isDev = env.development;

plugins: [
new webpack.DefinePlugin({ // 可以在项目中拿到当前环境变量
'NODE_ENV': JSON.stringify(isDev ? 'dev' : 'prod'),
}),
]

// 项目中业务代码
if (NODE_ENV === 'dev') {
// ...
}

vue-loader plugin

当项目是基于Vuejs开发时,webpack就需要配置vue-loader plugin。通过官方文档可以知道,这个插件就是用来处理.vue文件中各个模块匹配不同loader。如前面.js文件配置的loader会应用到.vue文件中的script模块,.css文件,.scss文件配置的loader会应用到.vue文件中的style模块。

这个插件不是独立的,是配置vue-loader的时候同时需要使用到的,在vue-loader/lib/plugin目录下。

1
2
3
4
5
const VueLoaderPlugin = require('vue-loader/lib/plugin');

plugins: [
new VueLoaderPlugin(), // 作用是处理匹配.vue文件的rule
]

html-webpack-plugin

前面写了这么一系列的配置,但是有个关键的问题,就是打包后的文件会从哪里引用。因为是网页,所以一定需要用一个html文件来引用。但是手动创建一个比较麻烦。这里就可以使用html-webpack-plugin这个插件。

这个插件可以自动生成一个html文件,并使用script标签引入打包后的文件。

1
2
3
4
5
const HtmlWebpackPlugin = require('html-webpack-plugin');

plugins: [
new HtmlWebpackPlugin(),
]

上面就是最简单的配置,打包之后会生成一个index.html

这个插件也支持配置。详细的配置项可以通过官网查看。这里简单介绍几个配置项:

template用来配置生成index.html基于的模板,值是模板在项目中的相对路径或者绝对路径。

filename用来配置生成html文件的命名,默认为index.html

minify用来配置在打包生产环境时生成的html文件压缩设置。这个配置项默认在生成环境下为true,也可以手动配置压缩哪些,比如去除空白,删除注释等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const HtmlWebpackPlugin = require('html-webpack-plugin');
let isDev = env.development;

plugins: [
new HtmlWebpackPlugin({ // 自动生成html文件
template: path.resolve(__dirname, '../public/index.html'), // 配置生成HTML文件的模板
filename: 'index.html', // 生成html文件的命名
minify: !isDev && {
removeComments: !isDev, // 移除注释
removeAttributeQuotes: !isDev, // 移除引号
collapseWhitespace: !isDev // 折叠空白
}
}),
]

html-webpack-tags-plugin

我们在项目中不免会需要在html文件中直接引入一些文件,比如用来重写标签一般样式的css文件,项目中涉及微信api时需要引入相关的js文件。这些文件我们当然可以直接利用html-webpack-plugin,把需要引入文件写到html模板文件中,然后打包的时候直接生成。不过这样肯定有些人觉得不够优雅。那么就可以试试使用html-webpack-tags-plugin这个插件。

html-webpack-tags-plugin这个插件支持在打包的时候把配置文件自动引入到html文件中。这样我们就可以在webpack配置中对引入的文件一目了然。

html-webpack-tags-plugin也有很多配置项,我这里也只是对几个用上的配置项做介绍,其他配置项可以根据项目需求使用。

tags用来指定需要插入的文件列表。这个配置项接受一个数组,这个数据的元素可以是字符串,表示引入的文件地址,也可以是一个json格式,可以配置除了引入文件的地址path之外其他配置。如type指定文件类型,publicPath指定文件路径前是否需要应用publicPath

append用来指定是否将tags中列出的文件在打包文件位置前引入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const HtmlWebpackTagsPlugin = require('html-webpack-tags-plugin');

plugins: [
new HtmlWebpackTagsPlugin({ // 在html文件中插入引用文件
tags: [
{
path: '//res.wx.qq.com/open/js/jweixin-1.4.0.js',
type: 'js',
publicPath: false, //不在路径面前应用publicPath
}
],
append: false, //插入顺序在打包文件前面
}),
]

clean-webpack-plugin

clean-webpack-plugin这个插件是用来在打包输出文件之前,清理打包输出目录文件的工具。一般我们配置的打包输出目录是固定的,每次打包如果不清除目录内的文件,会导致目录内的文件越来越多。在这种情况下,我们可以使用这个插件来清除。

这里有一个实际使用的问题。旧版本的clean-webpack-plugin不会清除隐藏文件及目录,但是新版本中会完全清除。这就导致出现一个问题。在实际业务中,打包目录有可能就是远程仓库对应的目录,那么目录中是会有被隐藏的.git目录。如果直接使用新版的插件,打包时也会把.git目录清除,导致无法使用推送代码。

我查了官方文档及很多博客,也没有找到比较合适的解决方案,但是还是找到了cleanOnceBeforeBuildPatterns这个配置项。这个配置项可以指定哪些文件需要清除的。它接受一个数组,数组的每一项都是一个正则。默认为全部清除。我就使用这个配置项来排除.git目录。最后是得到使用以下配置可以达到保留.git目录,其他文件清除的效果:

1
2
3
4
5
6
7
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

plugins: [
new CleanWebpackPlugin({ // 输出打包文件前清除旧的打包文件
cleanOnceBeforeBuildPatterns: ['**/*', '!\.git', '!\.git/**/*']
})
]

mini-css-extract-plugin

这个插件用来抽离css代码到一个单独的style文件。官方介绍有以下特点:1. 异步加载;2. 无重复编译;3. 使用简便;4. 针对css。

使用的时候,除了需要在plugins中new一个插件的实例,还需要在loader上配置对css打包上使用插件对应的loader。

mini-css-extract-plugin也有一些配置项,最常用的就是filenamechunkFilename,用来配置css文件的命名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
let isDev = env.development;

{
module: {
rules: [
{
test: /\.css$/,
use: [
// ...
isDev ? 'style-loader' : MiniCssExtractPlugin.loader, // 一般使用MiniCssExtractPlugin就不使用style-loader
// ...
]
},
]
},
plugins: [
!isDev && new MiniCssExtractPlugin({ // 将css单独打包成一个文件的插件,它为每个包含css的js文件都创建一个css文件。它支持css和sourceMaps的按需加载。
filename: 'main.css'
}),
].filter(Boolean)
}

webpack-bundle-analyzer

这个插件是用来分析打包文件的,目的是让打包的项目以图表的形式展示给开发者,可以直观的分析项目打包文件的情况,为优化做判断。配置这个插件后,在打包完成之后,会启动http服务器打开一个页面来显示打包文件的情况。

使用也比较简单,也有一些配置项,这里项目中没有用到,就简单略过:

1
2
3
4
5
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

plugins: [
new BundleAnalyzerPlugin() // 打包代码分析
]

接下来将整理剩下的webpack配置中剩下的部分。