前言

若文章有误,欢迎读者留言反馈

💻Installation

1
git clone https://github.com/coding327/learn_webpack5.git

认识css-loader

由于webpack社区很强大,这个loader不需要我们去编写,对于css在社区有个很强大的css-loader,我们只需要使用npm安装上即可,同时loader只在开发环境使用安装时可以加上参数-D

1
npm install css-loader -D

安装了不代表就能直接使用,还需要配置

css-loader使用方案

如何使用这个loader来加载css文件呢?有三种方式:

  • 内联方式;
  • CLI方式 ( webpack5中不再使用);
  • 配置方式;
  1. 内联方式
    由于abc.js-->abc.css我们可以在abc.js文件中配置
    1
    import "css-loader!../css/abc.css"
    注意!一定要加上,它是起分割作用的
    之后打包,没有报错,但是这个样式文件没有生效,浏览器审查元素发现样式没加上去啊,其实一个loader还不够,我们还需要其它loader把样式添加到元素上面去
  • 内联方式:内联方式使用较少,因为不方便管理
    • 在引入的样式前加上使用的loader,并且使用!分割;
  • CLI方式
    • webpack5的文档中已经没有了--module-bind
    • 实际应用中也比较少使用,因为不方便管理;
  • loader配置方式【在我们的webpack.config.js文件中写明配置信息】
    • module.rules中允许我们配置多个loader(因为我们也会继续使用其他的loader,来完成其他文件的加载);
    • 这种方式可以更好的表示loader的配置,也方便后期的维护,同时也让你对各个Loader有一个全局的概览;

进入webpack.config.js文件中配置

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
29
30
31
32
33
34
35
36
37
38
39
const path = require('path')

// webpack是运行在node环境下的,不要使用ES6 module导出【如果非要使用它还需要做额外配置】
// 注意出口文件中的path得是绝对路径,需要使用到path模块,做路径拼接即可,__dirname就是当前编写代码文件所在目录【绝对路径】
module.exports = {
entry: "./src/main.js",
output: {
path: path.resolve(__dirname, './build/'),
filename: "main.js"
},
module: { // 配置module
rules: [ // 注意rules是数组,以后会有多个规则
{
test: /\.css$/, // 正则表达式,由于.在正则表达式中有特殊含义,使用反斜杠转义
// 1. loader的写法(语法糖,是use: "css-loader"的简写,use可以写字符串、对象及数组)
// loader: "css-loader"

// use: "css-loader"
// use: {
// loader: "xxx-loader",
// options: xxx
// }

// 2. 完整的写法【数组】
// 但是一个loader是搞不定的,use这里一般是放数组
use: [
// 对象写法语法格式【一般对象都是作为配置项】
// {loader: "xxx-loader", options: xxx}
// {loader: "css-loader"}
// 如果loader没有其它参数配置,一般可以写下面这种
"css-loader"
]
}, // 加载css需要规则
{}, // 加载less需要规则
{}, // 加载js以后可能也需要规则
{}, // 加载ts需要规则
]
}
}

以上便是css-loader的最终使用方案【当然还需要其它loader把样式插入到html页面中】

认识style-loader

  • 我们已经可以通过css-loader来加载css文件了
    • 但是你会发现这个css在我们的代码中并没有生效(页面没有效果)。
  • 这是为什么呢?
    • 因为css-loader只是负责将.css文件进行解析,并不会将解析之后的css插入到页面中;
    • 如果我们希望再完成插入style的操作,那么我们还需要另外一个loader,就是style-loader;
  • 安装style-loader
    1
    npm install style-loader -D

安装完,在rules中添加style-loader,其中的细节我已经写在注释里面了

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
29
30
31
32
33
34
35
36
37
38
39
40
41
const path = require('path')

// webpack是运行在node环境下的,不要使用ES6 module导出【如果非要使用它还需要做额外配置】
// 注意出口文件中的path得是绝对路径,需要使用到path模块,做路径拼接即可,__dirname就是当前编写代码文件所在目录【绝对路径】
module.exports = {
entry: "./src/main.js",
output: {
path: path.resolve(__dirname, './build/'),
filename: "main.js"
},
module: { // 配置module
rules: [ // 注意rules是数组,以后会有多个规则
{
test: /\.css$/, // 正则表达式,由于.在正则表达式中有特殊含义,使用反斜杠转义
// 1. loader的写法(语法糖,是use: "css-loader"的简写,use可以写字符串、对象及数组)
// loader: "css-loader"

// use: "css-loader"
// use: {
// loader: "xxx-loader",
// options: xxx
// }

// 2. 完整的写法【数组】,注意这里数组它是从后往前执行loader,而对于css应该先使用加载loader再使用插入loader,这里的执行顺序一定要注意
// 但是一个loader是搞不定的,use这里一般是放数组
use: [
// 对象写法语法格式【一般对象都是作为配置项】
// {loader: "xxx-loader", options: xxx}
// {loader: "style-loader"},
// {loader: "css-loader"}
// 如果loader没有其它参数配置,一般可以写下面这种
"style-loader",
"css-loader"
]
}, // 加载css需要规则
{}, // 加载less需要规则
{}, // 加载js以后可能也需要规则
{}, // 加载ts需要规则
]
}
}

这个style-loader它是怎么做的呢?

  • 其实就是在head中创建一个style标签,把我们的样式给它放到style标签里面
  • 在开发里面我们一般是把它提取到专门的css文件里面,然后给它link进来,后面再说,其实就是通过一个插件完成的

如何处理less文件?

在平时开发中,我们可能会喜欢写sassless,相比于css,可以说是增强了,比如定义变量、嵌套关系
这时候我们写一个less文件,并把它加入到依赖图里【element.js—>title.less】
我们尝试进行打包,发现报错

1
2
Module parse failed: Unexpected character '@' (2:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

如果写个原生项目并使用过sass或者less,我们之前都是会使用工具【vscode也有这种插件,需要配置】将它们转换为原始的css,因为浏览器它不认识sassless

由于有npm,我们可以使用lessc这个工具,当然有的时候也可以直接使用这个less,它会自己去找这个lessc
lessc完整的应该叫less compiler

全局安装lessc工具【注意安装的虽然是less但是它会帮我们安装lessc工具】

1
npm install less -g

局部安装lessc工具【注意安装的虽然是less但是它会帮我们安装lessc工具】

1
npm install less -D

安装成功后,我们可以在node_modules/.bin找到这个lessc文件
我们可以在项目根目录创建一个test.less文件,并写一点less代码

1
2
3
4
5
6
7
8
// 定义两个变量
@bgColor: blue;
@textDecoration: underline;

.title {
background-color: @bgColor;
text-decoration: @textDecoration;
}

然后使用npx命令来对这个less文件进行转换【使用npx命令,它自己会去node_modules下找lessc

1
npx lessc ./test.less demo.css

demo.css是输出文件

运行完之后,项目根目录就会多一个demo.css文件,打开demo.css,其中代码就是原始css代码

1
2
3
4
.title {
background-color: blue;
text-decoration: underline;
}

实际开发中,不可能每次都去找这个less文件相对路径,那么如何在webpack中,把less文件的处理和lessc工具结合起来呢?
这个时候需要一个less-loader这样的一个工具
其实在安装less-loader的时候,我们还需要安装less这个工具
它本质是依赖于lessc的。
局部安装less-loader

1
npm install less-loader -D

回到webpack.config.js文件里,配置rules

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
const path = require('path')

// webpack是运行在node环境下的,不要使用ES6 module导出【如果非要使用它还需要做额外配置】
// 注意出口文件中的path得是绝对路径,需要使用到path模块,做路径拼接即可,__dirname就是当前编写代码文件所在目录【绝对路径】
module.exports = {
entry: "./src/main.js",
output: {
path: path.resolve(__dirname, './build/'),
filename: "main.js"
},
module: { // 配置module
rules: [ // 注意rules是数组,以后会有多个规则
{
test: /\.css$/, // 正则表达式,由于.在正则表达式中有特殊含义,使用反斜杠转义
// 1. loader的写法(语法糖,是use: "css-loader"的简写,use可以写字符串、对象及数组)
// loader: "css-loader"

// use: "css-loader"
// use: {
// loader: "xxx-loader",
// options: xxx
// }

// 2. 完整的写法【数组】,注意这里数组它是从后往前执行loader,而对于css应该先使用加载loader再使用插入loader,这里的执行顺序一定要注意
// 但是一个loader是搞不定的,use这里一般是放数组
use: [
// 对象写法语法格式【一般对象都是作为配置项】
// {loader: "xxx-loader", options: xxx}
// {loader: "style-loader"},
// {loader: "css-loader"}
// 如果loader没有其它参数配置,一般可以写下面这种
"style-loader",
"css-loader"
]
}, // 加载css需要规则
{
test: /\.less$/, // less文件
use: [
"style-loader", // 解析了css代码,但是样式并未插入到index.html中,所以还需要style-loader,把css代码插入到index.html文件中,其实就是创建style标签把css代码放里面
"css-loader", // less代码转为了css代码,但是webpack也无法加载解析css,所以需要css-loader
"less-loader" // lessc独立于webpack,使用less-loader它不仅处理了less文件的import依赖关系【webpack并不识别除js以外的文件,无法加载解析除js以外的文件】,同时使用lessc帮我们将less代码转换为css代码
]
}, // 加载less需要规则
{}, // 加载js以后可能也需要规则
{}, // 加载ts需要规则
]
}
}

对于less文件处理,需要安装的包有lessless-loader

1
npm i less less-loader -D

认识PostCSS工具

什么是PostCSS呢?

  • PostCSS是一个通过JavaScript来转换样式的工具;
    • 这个工具可以帮助我们进行一些CSS的转换和适配,比如自动添加浏览器前缀、css样式的重置;
    • 但是实现这些功能,我们需要借助于PostCSS对应的插件;
  • 如何使用PostCSS呢?主要就是两个步骤︰
    • 第一步:查找PostCSS在构建工具中的扩展,比如webpack中的postcss-loader;
    • 第二步:选择可以添加你需要的PostCSS相关的插件;

命令行使用postcss

  • 当然,我们能不能也直接在终端使用PostCSS呢?
    • 也是可以的,但是我们需要单独安装一个工具postcss-cli;
  • 我们可以安装一下它们:postcsspostcss-cli
1
npm install postcss postcss-cli -D
1
2
3
4
5
6
7
:fullscreen {
color: red;
}

.content {
user-select: none;
}

autoprefixer插件

autoprefixer自动添加浏览器前缀的插件

  • 因为我们需要添加前缀,所以要安装autoprefixer:
    1
    npm install autoprefixer -D
  • 直接使用使用postcss工具,并且制定使用autoprefixer
    1
    npx postcss --use autoprefixer -o end.css ./src/css/style.css
    --use是使用什么插件
    -o输出到哪里
    最后一个是入口文件

我们可以在项目根目录创建一个test.css文件,并输入如下需要添加浏览器前缀的代码:

1
2
3
4
.title {
/* 这个代码是需要添加浏览器前缀的 */
user-select: none;
}

局部安装postcsspostcss-cli
1
npm install postcss postcss-cli -D

经过一系列转换,最终要输出为有浏览器前缀的代码
postcss这个工具还需要一个自动添加浏览器前缀的plugins插件—>autoprefixer

局部安装自动添加浏览器前缀autoprefixer插件

1
npm install autoprefixer -D

在终端使用:

1
npx postcss --use autoprefixer -o demo.css test.css

demo.css中代码如下:

1
2
3
4
5
.title {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}

为了方便接下来测试,我们进入src/css/style.css文件中添加user-select: none;代码,这个代码其实是需要添加浏览器前缀的

1
2
3
4
5
6
7
.title {
color: red;
font-weight: 700;
font-size: 30px;
/* 这个代码是需要添加浏览器前缀的 */
user-select: none;
}

实际开发肯定不是这样在终端里面还要输入文件路径,很麻烦,那么在webpack中应该怎么使用postcss呢?

同样也是需要使用一个loader工具—>postcss-loader
主要是webpack它也不识别postcss,安装这个插件webpack就能使用postcss
局部安装postcss-loader

1
npm install postcss-loader -D

和之前一样,安装完这个插件肯定还需要配置rules

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const path = require('path')

// webpack是运行在node环境下的,不要使用ES6 module导出【如果非要使用它还需要做额外配置】
// 注意出口文件中的path得是绝对路径,需要使用到path模块,做路径拼接即可,__dirname就是当前编写代码文件所在目录【绝对路径】
module.exports = {
entry: "./src/main.js",
output: {
path: path.resolve(__dirname, './build/'),
filename: "main.js"
},
module: { // 配置module
rules: [ // 注意rules是数组,以后会有多个规则
{
test: /\.css$/, // 正则表达式,由于.在正则表达式中有特殊含义,使用反斜杠转义
// 1. loader的写法(语法糖,是use: "css-loader"的简写,use可以写字符串、对象及数组)
// loader: "css-loader"

// use: "css-loader"
// use: {
// loader: "xxx-loader",
// options: xxx
// }

// 2. 完整的写法【数组】,注意这里数组它是从后往前执行loader,而对于css应该先使用加载loader再使用插入loader,这里的执行顺序一定要注意
// 但是一个loader是搞不定的,use这里一般是放数组
use: [
// 对象写法语法格式【一般对象都是作为配置项】
// {loader: "xxx-loader", options: xxx}
// {loader: "style-loader"},
// {loader: "css-loader"}
// 如果loader没有其它参数配置,一般可以写下面这种
"style-loader",
"css-loader",
{
loader: "postcss-loader", // 这个比较特殊,它使用了autoprefixer插件,需要做配置项
options: {
postcssOptions: {
plugins: [
require("autoprefixer")
]
}
}
}
]
}, // 加载css需要规则
{
test: /\.less$/, // less文件
use: [
"style-loader", // 解析了css代码,但是样式并未插入到index.html中,所以还需要style-loader,把css代码插入到index.html文件中,其实就是创建style标签把css代码放里面
"css-loader", // less代码转为了css代码,但是webpack也无法加载解析css,所以需要css-loader
"less-loader" // lessc独立于webpack,使用less-loader它不仅处理了less文件的import依赖关系【webpack并不识别除js以外的文件,无法加载解析除js以外的文件】,同时使用lessc帮我们将less代码转换为css代码
]
}, // 加载less需要规则
{}, // 加载js以后可能也需要规则
{}, // 加载ts需要规则
]
}
}

最后npm run build,在浏览器上运行,通过审查元素,我们可以快速找到样式,发现浏览器前缀已经成功添加上了

1
2
3
4
5
6
7
8
9
<style>.title {
color: red;
font-weight: 700;
font-size: 30px;
/* 这个代码是需要浏览器前缀的 */
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}</style>

但是我们发现这个postcss-loader需要额外配置有一大堆,那么有没有其它简便方式呢?
把配置信息抽取出去:

  • 首先我们在webpack.config.js文件中依旧像之前一样使用字符串语法糖写法
  • 其实我们还可以在项目根目录创建一个postcss.config.js,然后在其中输入以下代码
    1
    2
    3
    4
    5
    6
    module.exports = {
    // 把插件抽离到这里
    plugins: [
    require("autoprefixer")
    ]
    }

然后重新打包,运行咱们文件,审查元素,发现浏览器前缀依旧添加成功

那么它是如何做到的呢?

其实它默认是会在webpack.config.js的那个postcss-loader那里先看看有没有配置信息,如果没有它就会在当前项目根目录去找这个postcss.config.js,接着会查看这个文件有没有导出对象,如果有它就会把这个导出的对象当成配置信息

以上其实我们只需要安装如下几个插件,postcss-cli其实并不需要,那个是测试我们在终端使用postcss命令

1
npm install postcss postcss-loader autoprefixer -D

postcss-preset-env插件

  • 事实上,在配置postcss-loader时,我们配置插件并不需要使用autoprefixer
  • 我们可以使用另外一个插件:postcss-preset-env
    • postcss-preset-env也是一个postcss的插件;
    • 它可以帮助我们将一些现代的CSS特性,转成大多数浏览器认识的CSS,并且会根据目标浏览器或者运行时环境添加所需的polyfill;
    • 也包括会自动帮助我们添加autoprefixer(所以相当于已经内置了autoprefixer) ;

局部安装插件

1
npm install postcss-preset-env -D

由于postcss-preset-env插件已经内置autoprefixer我们可以去postcss.config.js文件中require这个postcss-preset-env插件即可

1
2
3
4
5
6
7
module.exports = {
// 把插件抽离到这里
plugins: [
// require("autoprefixer")
require("postcss-preset-env")
]
}

然后打包,我们可以在浏览器发现浏览器前缀是添加成功了的

接着测试它是否能把css新特性转换为大多数浏览器认识的css,进入src/css/style.css文件中,添加css颜色8位写法

1
2
3
4
5
6
7
8
9
.title {
/* color: red; */
/* css新特性支持8位,最后两位是透明度 */
color: #12345678;
font-weight: 700;
font-size: 30px;
/* 这个代码是需要浏览器前缀的 */
user-select: none;
}

我们重新打包,运行在浏览器,我们发现颜色由8位转为rgba—>大多数浏览器能识别的css代码

1
2
3
4
5
6
7
8
9
10
11
.title {
/* color: red; */
/* css新特性支持8位,最后两位是透明度 */
color: rgba(18,52,86,0.47059);
font-weight: 700;
font-size: 30px;
/* 这个代码是需要浏览器前缀的 */
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}

最后postcss需要安装插件归为以下几个

1
npm install postcss postcss-loader postcss-preset-env -D

最后补充一个知识点:
我们在写那个rules时,test那个正则是可以把css、less写在一块的,这样可以不用分开写

1
2
3
4
5
6
7
8
{
test: /\.(css|less)$/,
use: [
"style-loader",
"css-loader",
"less-loader"
]
}, // css、less合并写法