webpack5-样式篇(二)
前言
若文章有误,欢迎读者留言反馈💻Installation1
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中不再使用);
- 配置方式;
- 内联方式
由于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
39const 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
41const 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文件?
在平时开发中,我们可能会喜欢写sass
、less
,相比于css
,可以说是增强了,比如定义变量、嵌套关系
这时候我们写一个less
文件,并把它加入到依赖图里【element.js—>title.less】
我们尝试进行打包,发现报错1
2Module 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
,因为浏览器它不认识sass
和less
由于有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
48const 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
文件处理,需要安装的包有less
和less-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
;
- 也是可以的,但是我们需要单独安装一个工具
- 我们可以安装一下它们:
postcss
、postcss-cli
1 | npm install postcss postcss-cli -D |
- 我们编写一个需要添加前缀的
css
:- https://autoprefixer.github.io/
- 我们可以在上面的网站中查询一些添加
css
属性的样式;
1 | :fullscreen { |
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;
}
局部安装postcss
、postcss-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
58const 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
6module.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
7module.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合并写法