webpack4配置总结(三)

上一篇整理了webpack配置的四大配置概念。这篇来整理loader的使用。

loader

因为我的项目是基于Vue全家桶及sass的,所以loader部分会有偏向这方面的介绍,使用TS,React全家桶及less的可以找一下相应的loader

webpack打包模块时,会把模块拿到module这里的rules中做匹配,如果匹配到,则使用对应的loader进行解析。

因为loader有很多,不好整理,所以我这里就按照项目中不同文件模块所需要的loader来整理说明。

vue

我们一般在基于vue全家桶项目目录中都会使用.vue文件来开发vue组件,所以.vue文件模块需要单独解析。而vue本身就有一个专门解析.vue文件的loader

vue-loader

vue-loader是一个专门解析.vue文件的loader,顾名思义,只是解析.vue文件,并不能解析内部的写法。因为.vue文件一般会有三个部分,一个是template模块,用来写模板语言;一个是script模块,用来写组件的js部分;一个是style模块,用来写组件的css部分。template模块是通过vue的一个plugin插件来解析处理的,script模块跟style模块则提供出来自定义loader进行解析。

所以在loader的配置上也比较简单:

1
2
3
4
5
6
7
8
9
10
{
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader'
}
]
}
}

javascript

我们的项目中最多的代码就是js代码了,而且现在js的标准已经到了ES2020,很多ES6及以上的标准都需要编译成ES5才能在各种浏览器中使用,所以在webpack打包中,我们也需要解析项目中的js代码。这里就需要使用babel-loader

babel-loader

讲到babel,我们在webpack中使用的时候,其实有很多复杂的使用方式。这里先写一下在module中的内容:

1
2
3
4
5
6
7
8
9
10
{
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader'
}
]
}
}

单单只是这样配置是不足以完成js代码的解析的。实际上,如果你的代码中使用了es6及以上标准的语法,还需要配合.babelrc配置文件。这个配置文件的配置内容也是可以直接卸载 rules中,但是因为配置内容比较多,所以最好独立出来。

实际上,这里配置使用的babel-loader在解析代码时是调用了@babel/core,然后由@babel/core来转换代码。转换的过程中会调.babelrc配置文件中的配置。

关于.babelrc文件中的配置介绍,我会另起一篇来做详细介绍。

css

css也是项目中非常重要的一部分。我的项目中使用了sass来开发css。这里就需要安装使用以下loader:

sass-loader

sass-loader是用于解析sass语法的loader,使用这个loader时还需要安装node-sass依赖包。这个包是用于让sass可以在node端进行编译。

安装node-sass也有一些比较麻烦的地方。因为这个包是为了sass能在node端进行编译,所以它的版本要求比较高,不同版本对应不同的node版本范围,需要根据自己的node环境进行选择。同时,安装也不太顺利,一般的依赖包可以直接使用npm进行下载安装,而node-sass直接使用npm下载容易失败,需要考虑更换淘宝源或者使用cnpm安装。

postcss-loader

postcss-loader简单的理解就是一个js工具,用来转化css代码,为css样式处理适配,抹平差异。因为不同浏览器的内核不一样,导致一些样式在各个浏览器中实现不一样。postcss-loader就是用来抹平浏览器之间的差异而出现的。可以让我们在开发时无需考虑这些问题。不过,为css样式加处理实际上不是这个loader本身实现的,而是通过如autoprefixerpostcss-pxtorem配合实现的,所以需要安装并配置。配置上也可以新建一个postcss.config.js。这个后面再单独整理。

css-loader

css-loader主要是用于解释@importurl(),会在import/require()后再解析它们。loader有比较多的配置项,这里因为我的项目中只需要使用要importLoaders这个配置项,所以就只介绍这个,其他的配置项可以在webpack官网上查看。importLoaders是用来指定在css-loader之前使用loader的数量。如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
test: /\.css$/,
use: [
'vue-style-loader',
'style-loader',
{
loader: 'css-loader', // 用于编译@import和url()跟解析css
options: {
// 在 loader 前应用的 loader 的数量,意思是解析css时需要用到'postcss-loader','sass-loader'
// 因为引入的css文件中可能是sass文件
// 如配置1,则应用'postcss-loader',如配置2,则应用'postcss-loader','sass-loader'
importLoaders: 2
}
},
'postcss-loader',
'sass-loader'
]
},

上面配置中,importLoaders设置了2,指定在css-loader之前使用2个loader,而且指定的loader就是postcss-loadersass-loader,即指定的loader位于css-loader右侧(下方)最近的数个loader。

style-loader

style-loader的作用是在DOM里插入<style>标签,并将css写入这个标签内。这个loader跟抽离css的插件mini-css-extract-plugin中的内置loader会冲突,所以当使用mini-css-extract-plugin插件时,因为需要用到其loader,所以需要分别使用,比如因为mini-css-extract-plugin插件只能在正式环境使用,需要使用其loader来辅助编译打包时处理抽离,所以正式环境下就不能使用style-loader了。

vue-style-loader

vue-style-loader是配合vue-loader使用的。上面说到,vue-loader是用来解析.vue文件的,但是三个模块是需要分别解析的,而vue-style-loader就是用来解析.vue文件中的style模块的。官方文档介绍到,其实vue-style-loader是从style-loaderfork并基于这个loader开发的,所以作用也跟style-loader一样。但是也有一些区别,增加了对ssr的支持,去掉了一些style-loader支持的功能,所以基于我们项目的需要,还是需要同时使用这两个loader。

css及sass打包配置

基于这些loader,我们就可以进行配置,如sass需要通过scss-loader先做转化为css,然后再用postcss-loader处理加前缀,转单位,然后在使用css-loader处理import/require()语句,处理这些语句是对引入的文件又根据文件类型再使用scss-loaderpostcss-loader进行处理。最后再把处理好的css代码通过style-loadervue-style-loader插入到DOM中。

如果是在正式环境打包,则不使用style-loader,而是使用mini-css-extract-plugin插件配合压缩css代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
test: /\.css$/,
use: [
'vue-style-loader', // 用于编译.vue文件中css部分
isDev ? 'style-loader' : MiniCssExtractPlugin.loader, // 一般使用MiniCssExtractPlugin就不使用style-loader
{
loader: 'css-loader', // 用于编译@import和url()跟解析css
options: {
// 在 loader 前应用的 loader 的数量,意思是解析css时需要用到'postcss-loader','sass-loader'
// 因为引入的css文件中可能是sass文件
// 如配置1,则应用'postcss-loader',如配置2,则应用'postcss-loader','sass-loader'
importLoaders: 2
}
},
'postcss-loader', // 支持增加声明前缀,需要安装autoprefixer,并在postcss.config.js中配置
'sass-loader' // sass编译,还需要安装node-sass依赖。安装node-sass建议使用cnpm
]
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader'
]
},

其他文件

项目中通常还需要使用各种其他格式的文件,如文字图标会使用到woffttfeotsvg这些格式的文件,图片文件一般有jpgjpegpnggifsvg等格式。一般我们会考虑使用外部链接或者本地文件的形式引入。这里我们主要需要打包处理的是本地文件,所以就需要用到以下这些loader。

file-loader

file-loader就是打包文件时会默认使用文件内容生成MD5哈希值然后使用这个哈希值作为这个文件名字保存到打包目录中,并且不会修改扩展名。file-loader也要一些配置可以使用,这里简单介绍几个:name可以指定打包文件的命名,自定义的命名跟前面打包文件命名类似,可以使用[name](原文件名),[ext](原扩展名),[hash](哈希值),[path](原路径),[N](正则匹配第N个);publicPath指定路径前缀,方便使用CDN;outputPath指定打包目录。

url-loader

url-loader功能类似于file-loader,但是它有一个特点,就是可以根据文件的大小进行不用的打包处理,如小于一个特定的大小,则会打包返回一个DataURL的格式。比如一张图片小于10k,则直接转成DataURL打包存放在调用的文件中,这样会不需要再引用文件了。对于线上使用来说,客户端不需要为这个小文件发多一次请求。当然,这个需要配置limit属性。

其他文件的打包配置

file-loaderurl-loader各有不同,可以根据不同文件使用不同的loader,比如字体文件可以直接使用file-loader,图片类文件可以使用url-loader来分类处理:大小较小的图片可以直接打包进文件中,较大的图片可以打包引入文件中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
test: /\.(woff|ttf|eot|svg)$/,
use: 'file-loader' // 用于解析通过import/require()引入的文件或外部链接
},
{
test: /\.(jpe?g|png|gif|svg)$/,
use: {
loader: 'url-loader', // 用于把文件编译为base64格式
options: {
name: "image/[contentHash].[ext]", // 超过大小将使用file-loader解析,name为file-loader的配置,contentHash为图片的hash戳,ext是后缀
limit: 100 * 1024, // 尺寸限制
esModule: false // 启用CommonJS模块语法
}
}
}

下一篇整理一下babelpostcss-loader的配置。