[5] WebPack 对css(scss)的处理

435 阅读2分钟

项目中所有的css文件全部打包到dist下面的css文件夹下面。

一、背景

webpack是可以直接去处理javascript的代码,但是对于css、image、font等,是不能直接处理的,需要使用到loader将其转化成javascript代码片,然后在对其进行处理。

对于处理css,需要使用到的loader:

loader解析顺序作用
sass-loader1加载 Sass/SCSS 文件并将他们编译为 CSS。
css-loader2css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。用于加载CSS文件(并没有添加到页面)
style-loader3把 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函数的作用就是组合函数的,将函数串联起来执行,将多个函数组合起来 ,一个函数的输出结果是另一个函数的输入参数一旦第一个函数开始执行,就会像多米诺骨牌一样推导执行了。