项目中所有的css文件全部打包到dist下面的css文件夹下面。
一、背景
webpack是可以直接去处理javascript的代码,但是对于css、image、font等,是不能直接处理的,需要使用到loader将其转化成javascript代码片,然后在对其进行处理。
对于处理css,需要使用到的loader:
| loader | 解析顺序 | 作用 |
|---|---|---|
| sass-loader | 1 | 加载 Sass/SCSS 文件并将他们编译为 CSS。 |
| css-loader | 2 | css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。用于加载CSS文件(并没有添加到页面) |
| style-loader | 3 | 把 CSS 插入到 DOM 中。将样式通过标签插入到head中 |
注意:loader 支持链式传递,从右向左传递,sass-loade解析完交给css-loader,css-loader解析完交给style-loader。
module:{
rules:[
{
test:/.css$/,
use:["style-loader","css-loader"] //注意:loader是从右往左开始加载处理的,所以先执行css-loader
},
// scss 文件的处理
{
test: /.scss$/,
use: ['style-loader','css-loader', {
loader: 'sass-loader?sourceMap=true',
options: {
importer: require('node-sass-import-once')
}
}]
},
],
}
二、带来的问题
以上对css处理,会将css打包到对应的js里面去,那么页面加载的时候会先解析完了js之后再去加载css,这样会影响用户体验。
所以我们需要将css单独提取出来,产生“将CSS文件单独打包”的需求,以link的方式注入到文件里面。
三、打包优化
所以在线上环境时,使用mini-css-extract-plugin。将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件(打包出来的) 创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。
四、为什么loader从右向左解析
loader 本质上是一个函数,我们配置多个 loader 本质上就是先后调用多个函数,所以 loader 顺序配置错误可能导致潜在问题,得不到预期的输出。
Webpack 配置实际上是基于 compose,假如把 loader 当作函数,可以将配置看成嵌套的函数调用,如 style-loader(css-loader(sass-loader(content))),从函数调用顺序可以很容易得出 loader 生效顺序。
compose:javascript函数式编程中另外一个很重要的函数compose,compose函数的作用就是组合函数的,将函数串联起来执行,将多个函数组合起来 ,一个函数的输出结果是另一个函数的输入参数,一旦第一个函数开始执行,就会像多米诺骨牌一样推导执行了。