目录
一、CSS-Loader
为什么需要loader
css-loader的使用
二、style-loader的使用
三、browserslitrc工作流程
通过.browserslistrc配置文件进行筛选
四、postcss工作流程
五、Postcss-loader处理兼容
postcss预设
给postcss添加配置文件
六、importLoaders属性
大家好,这里是小杰,这是webpack相关学习的第二期,如果你没有看过第一期的话我强烈建议你先看完第一期的内容,这是链接:webpack5学习第一期,因为在第二期中我们的项目沿用第一期的,下面让我们一起由浅入深探索一下webpack的世界吧!✌️
我们还是用webpack第一篇里的webpack初体验项目,下面是我们的项目目录结构:
我们创建一个login.js文件,在里面先创建dom标签,然后再把它放在界面上进行展示,之后再去给相应的元素添加样式,然后再通过webpack做一个统一的打包,之后输出到一个静态资源上去,为我们所用进行部署。
下面我们一步步地实现:
我们在 login.js 文件中 创建一个 login 函数,在里面创建一个 h2 标签,给他一段文本,然后设置一下类名,有了这样的一个函数以后,将来肯定会被别人所调用,这样就我们就需要返回一下在函数执行中创建的 h2 标签。最后调用 login 函数把标签添加到 body 当中。
function login() {
const oH2 = document.createElement('h2')
oH2.innerHTML = '小杰学前端'
oH2.className = 'title'
return oH2
}
document.body.appendChild(login())
将login.js文件导入到入口文件index.js中:
import './js/login'
命令行执行 npm run build 进行打包:
目录里生成dist文件夹,里面的build.js就是我们打包后的文件
在index.html里引入打包后的文件:
在浏览器中运行,看看效果:
可以看到我们在 login.js 文件夹下通过 login 函数添加的 h2 标签在我们页面里成功显示出来了
下一步我们就要给这个标签添加一个样式
先在src目录下新建一个css文件夹,在里面创建一个login.css文件来写标签的样式
我们先给标签添加样式:
.title {
color: red;
}
思考一下,如果我们再次进行打包,浏览器会显示添加样式后的标签吗?
很明显,页面不会有任何变化,因为我们根本没有把css文件引入依赖图中。依据我们的设计,login.css 属于组件 login.js 里的样式,所以我们应该在 login.js里导入 login.css 文件,这样我们的入口文件会先去找 login.js,login.js 再去找 login.css。这样打包就可以完成了。
这样css文件就需要把它当成一个模块去处理才能有导入导出的行为,那么我们就在login.js文件中引入login.css:
import '../css/login.css'
运行 npm run build 看看是否打包成功:
为什么会报错?
因为默认情况下,webpack是不会处理css文件的,因为他并不是一个js模块,这样我们就需要有人能够给这个css文件做一个转换,然后让webpack可以拿着转换后的内容去执行打包操作。这样的话就需要loader了,它的功能就是做这样一个转换。
loader是什么?
当前的话,我们只需要记住两点,loader是必须的,并且它可以起到转换的作用。
首先安装css-loader:
npm i css-loader -D
安装完css-loader后,我们执行打包会成功吗?
答案还是不会的,因为css-loader还得在webpack中进行相应的配置才能工作。
行内loader的使用:
修改login.css里导入login.css文件这行代码,给他加上loader
import 'css-loader!../css/login.css'
这句话的意思就是css-loader会对这个路径的css文件进行处理,如果有多个loader,就用感叹号进行分割就行。
引入css-loader后,再次执行打包会成功吗?
在通过npm run build执行完毕后,并没有报错,我们打开浏览器运行发现样式并没有成功引入进来
因为css-loader只是将我们的css语法处理为当前js可以识别的模块类型,但是它并不能把样式放在界面上进行使用。如果页面上的元素要想具备样式,那要么我们写了style标签,要么写了行内style属性,要么通过link引入外部css文件。但是上述三种行为css-loader都是做不到的,因此我们想在页面上看到具体的样式变化,就需要另一种loader。
这里我们先不去说明另一种loader,因为在行内这样写是非常麻烦的,如果还有个index.css也需要在他前面加上css-loader,这样文件多了就非常麻烦,下面我们就看一下在配置文件中如何使用css-loader,注意把login.js的引入恢复到原来的状态:
import '../css/login.css'
module就是一个对象,里面来放具体的匹配规则,rules就是在相应规则下需要添加的属性和属性值,test一般就是一个正则表达式,用于匹配我们所需要处理的文件类型,use属性来告知webpack使用什么样的loader,下面以一种最全的loader的配置参数的书写方式,这里把webpack.config.js里的代码都粘出来:
const path = require('path')
module.exports = {
entry:'./src/index.js',
output: {
filename:'build.js',
path: path.resolve(__dirname,'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'css-loader'
}
]
}
]
}
}
因为 ' . '有特殊含义,所以加个转义符,因为我们希望它以 ' .css '结尾,所以在后面加了一个$符号。这样的话webpack看到 .css 结尾的文件时,就可以去用他下边所给定的loader了。在user里,除了loader,还有个options属性,它是可选的,用来添加参数。
下面我们执行 npm ren build,发现并没有报错,dist目录下生成了打包后的文件build.js,这样我们就学会了如何在配置文件中对css-loader进行配置
下面我们再一个简写方法:
module: {
rules: [
{
test: /\.css$/,
use: ['css-loader']
}
]
}
这样的执行结果和上里的结果相同,只是简单了一些。
css-loader只是让webpack去识别css语法,而并不能把样式放在界面上进行使用,这个活css-loader做不了。所以需要另一个loader,style-loader。
首先安装style-loader:
npm i style-loader -D
在配置文件中添加style-loader:
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader','css-loader']
}
]
}
注意:loader在执行的时候会从右往左或者从下往上执行。很明显我们想让css-loader处理css,再把处理的结果给style-loader去处理,这样我们才能在页面上看到样式。
查看结果,运行index.html文件:
这样我们的样式成功添加进来了,并且style-loader会生成一个style标签,然后把样式添加进来:
我们做前端开发基于工程化,我们有个需求就是要实现css和js的兼容问题,怎么去实现兼容呢,我们有一些工具来帮助我们,比如说babel,postcss等等,但是这些工具去工作总要有一些条件,我们得告诉这些工具,我们要兼容的都有哪些平台,根据相应的条件来进行筛选,然后再去做到兼容就可以了。
首先我们在项目目录下找到node_modules文件夹,找到里面的browserslist文件夹,在他的入口文件index.js里第二行有个caniuse-lite:
他就会帮我们向can i use网站发送请求,根据我们的条件进行筛选,把删选后的网站返回给我们。
下面进行一下演示:
npx browserslist
在命令行运行上面的代码,会根据默认条件返回一些浏览器的数据。
这里他的默认条件是市场占有率大于百分之零点五,然后没有死掉的浏览器。如果24个月这个浏览器没更新,那他们就相当于死掉了。
在package.json中自定义筛选条件
在package.json中添加下面的语句:
"browserslist": [
">1%",
"last 2 version",
"not dead"
]
这里的意思就是筛选市场占有率大于百分之1,是最新的两个版本,且没有最近一年不更新的浏览器
在上面他就把满足条件的浏览器都筛选出来了
这里我们不用在package.json中进行设置了,先把相应的代码删除掉,然后在目录下新建一个.borwserslistrc文件,把需要配置的条件写在这里,然后运行 npx browserslist就行。
postcss是一种javascript转换样式的工具
首先安装postcss:
npm i postcss -D
我们利用postcss可以做一些兼容性的操作,比如说给不同的样式针对浏览器添加前缀,或者做一些css样式的重置处理,这些都可以借助postcss以及它的一些插件来完成。
为了能在命令行中使用postcss,我们还得安装一下它的脚手架:
npm i postcss-cli -D
在css目录下新建test.css,看看postcss到底是怎么工作的,为了方便演示兼容性,我们随便写一些代码:
.title {
display: grid;
transition: all 0.5s;
user-select: none;
}
在login.js中把这个样式引入:
import '../css/test.css'
执行npm run build进行打包,运行浏览器看看样式效果:
但是样式前面并没有添加上兼容前缀,那为啥我们之前配置的browserslistrc文件没有生效呢,那我们只能借助postcss来对样式手动处理一下。
我们现在想做的事情就是给transiton和user-select依据我们在browserslistrc里设置好的条件对不同浏览器平台添加相应的前缀,这个时候就应该把加前缀的插件给拿进来。
安装加前缀的插件:
npm i autoprefixer -D
我们现在安装了很多东西,有的小伙伴可能有点懵,我们来做个简单的整理:
postcss相当于一个整体的工具,类似于一个解析器,但是它自己啥事也干不了,于是我们又安装了一个autoprefixer,它就相当于一个具体的功能,来给样式属性做一个前缀的添加,因为我们想在命令行直接使用postcss命令,默认情况下他不允许像npx browserslist这样去用,所以我们又装了个postcss-cli这样的脚手架。
执行 npx postcss --use autoprefixer -o ret.css ./src/css/test.css :
npx postcss --use autoprefixer -o ret.css ./src/css/test.css
这里的意思是,通过npx执行postcss命令,--use的意思是使用这个插件,-o ret.css就是输出到ret.css这个文件,后面的路径就是对这个css文件进行操作。
我们看看输出的ret.css文件,前面就多了很多兼容性的前缀。
我们在.browserslistrc文件里修改市场占有率为百分之零点零一,看看ret.css里前缀是否有相应的添加:
这是修改后的.browserslistrc文件:
再次执行npx postcss --use autoprefixer -o ret.css ./src/css/test.css ,看看ret.css里的内容:
可以看到里面的前缀就变多了,这样我们就很轻松的实现了兼容。
如果我们的项目里有很多的css文件都需要进行兼容性处理,那我们不可能像上一节那样在命令行里手动用postcss实现这个事情,这样我们就需要postcss-loader:
先安装postcss-loader:
npm i postcss-loader -D
在webpack.config.js中加入post-loader:
postcss要先把css代码做一些兼容性处理,所以应该在css-loader之前进行工作,再把处理好的css给css-loader,然后再交给style-loader,是这样的顺序。
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader','css-loader','postcss-loader']
}
]
}
加完之后进行打包的话,样式还是不会多相应的前缀,因为postcss-loader是处理postcss的,但是在上一节我们知道postcss啥也干不了,需要依赖插件,这样就需要给postcss-loader添加相应的参数了:
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions:{
plugins: [
require('autoprefixer')
]
}
}
}
]
}
]
}
这里options就是postcss-loader的参数,里面plugins就是依赖的插件。
执行 npm run build,运行浏览器查看效果:
现在我们的样式都是经过兼容性处理的了,如果我们想修改一下兼容条件,直接在.browserslistrc里改就行了。
现在我们修改一下字体颜色,把它设置为16进制的 #123456,看看效果:
我们再把颜色修改为 #12345678 看看效果:
那我们就有疑问了,正常颜色十六进制不是就六个数么,怎么8个数也能运行成功,因为后面的两个数就相当于给字体添加了 rgba 操作。问题是谷歌浏览器是可以兼容这种写法的,但是很多浏览器是不兼容的,只能识别 rgba 这种写法,那很多小伙伴就想说,我们不是安装了 autoprefixer 插件么,显然它是添加样式前缀的,做不了这种转换,这里我们要介绍的就是 postcss 预设,postcss-preset-env,那预设到底是啥意思呢,它就相当于是插件的集合,有了它我们甚至不需要autoprefixer了,因为都被预设给包括在内了。
安装 postcss-preset-env:
npm i postcss-preset-env -D
执行npm run build重新进行打包,在浏览器中运行查看结果:
在样式中,颜色从八位16进制数转换成了rgba 这样就能兼容其他的浏览器了。
如果我们都在webpack.config.js里配置的话代码显得有些乱,如果项目里有less文件的话,为了处理less文件。还得在webpack.config.js里再配置一遍,这样代码也非常冗余。我们同样可以把冗余的代码拿出来,放在postcss.config.js这个专门的配置文件当中。
这样我们就先重新修改一下webpack.config.js :
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader','css-loader','postcss-loader']
}
]
}
在postcss.config.js配置文件中我们添加这些就行:
module.exports = {
plugins: [
require('postcss-preset-env')
]
}
执行 npm run build ,运行浏览器查看效果:
颜色根据配置文件的预设转换为了rgba的形式,那这样实现了代码的复用,简便了我们的操作。
现在我们项目的css目录下有两个css文件:
这是test.css里的内容:
.title {
transition: all 0.5s;
user-select: none;
}
这是login.css里的内容:
.title {
color: #12345678;
}
我们通过import把test.css中的内容引入到 login.css中:
@import './test.css';
.title {
color: #12345678;
}
执行 npm run build 进行打包,打开浏览器查看样式:
我们可以看到样式里的兼容性前缀没了,这是为什么呢?
对css-loader添加属性:
因为loader不能回头找,所以我们得给他添加参数,让他能够回头找。来到webpack.config.js文件中对css-loader进行属性的添加:
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders:1
}
},
'postcss-loader'
]
}
]
}
我们在这里就多设置了一个importLoaders,把它设置为了1,1就是让css-loader可以往回再找一个loader,那如果第一个执行的不是postcss-loader还有一个别的loader,我们想让css文件被这两个loader都处理怎么办呢,很简单,设置为2就行了。
执行 npm run build ,打开浏览器查看样式:
现在我们的样式就能够成功添加兼容前缀了。