Skip to content

CSS 优化

以下都是基于 webpack5

前置知识

Webpack 并不能识别 CSS 语法,如果不做额外的配置直接引入 css 文件,那么会直接报错。

如何让 webpack 识别 CSS

webpack 是通过 loader 来扩展自己对其它文件的识别和处理能力,那么识别 CSS 可以使用下面两个 loader:

  • css-loader:该 Loader 会将 CSS 等价翻译为形如 module.exports = "${css}" 的JavaScript 代码,使得 Webpack 能够如同处理 JS 代码一样解析 CSS 内容与资源依赖
  • style-loader:该 Loader 将在产物中注入一系列 runtime 代码,这些代码会将 CSS 内容注入到页面的 <style> 标签,使得样式生效;

两者各司其职:css-loader 让 Webpack 能够正确理解 CSS 代码、分析资源依赖;style-loader 则通过适当方式将 CSS 插入到页面,对页面样式产生影响:

webpack

使用 post-css

PostCSS 之于 CSS,像 Babel 与 JavaScript,让我们的 CSS 通过添加前缀等适配更多浏览器。

PostCSS 的接入步骤也很简单,首先安装依赖

npm install -D postcss postcss-loader

之后添加 Webpack 配置:

js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          "style-loader", 
          "css-loader", 
          "postcss-loader"
        ],
      },
    ],
  }
}

不过,这个时候的 PostCSS 还只是个空壳,下一步还需要使用适当的 PostCSS 插件进行具体的功能处理,例如我们可以使用 autoprefixer 插件自动添加浏览器前缀,首先安装依赖:

npm install -D autoprefixer

之后,修改 Webpack 配置:

js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          "style-loader", 
          {
            loader: "css-loader",            
            options: {
              importLoaders: 1
            }
          }, 
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                // 添加 autoprefixer 插件
                plugins: [require("autoprefixer")],
              },
            },
          }
        ],
      },
    ],
  }
};

之后,再次运行 Webpack 即可为 CSS 代码自动添加浏览器前缀。

PostCSS 最大的优势在于其简单、易用、丰富的插件生态,基本上已经能够覆盖样式开发的方方面面。实践中,经常使用的插件有:

  • autoprefixer:基于 Can I Use 网站上的数据,自动添加浏览器前缀
  • postcss-preset-env:一款将最新 CSS 语言特性转译为兼容性更佳的低版本代码的插件
  • stylelint:一个现代 CSS 代码风格检查器,能够帮助识别样式代码中的异常或风格问题
  • postcss-less:兼容 Less 语法的 PostCSS 插件,类似的还有:postcss-sasspoststylus

CSS 分割

在传统开发中我们一般会把 script 的引入放在最后面,让游览器先运行加载 CSS 和 HTML,优先把页面显示出来,能给用户很好的体验。而在 webpack 则是默认把 css 打包进 js 里面,导致 css 和 js 同时加载。

使用 MiniCssExtractPlugin

webpack 提供了 MiniCssExtractPlugin 插件来讲 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。

首先需要安装该插件

npm install --save-dev mini-css-extract-plugin

webpack.config.js中的配置

js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin()
  ]
};

需要注意几个点:

  • mini-css-extract-plugin 库同时提供 Loader、Plugin 组件,需要同时使用
  • mini-css-extract-plugin 不能与 style-loader 混用
  • mini-css-extract-plugin 需要与 html-webpack-plugin 同时使用,才能将产物路径以 link 标签方式插入到 html 中

TIP

  • 开发环境:使用 style-loader 将样式代码注入到页面 <style> 标签
  • 生产环境:使用 mini-css-extract-plugin 将样式代码抽离到单独产物文件,并以 <link> 标签方式引入到页面中。

TIP

至于 CSS 压缩,现在 webpack5 在生产环境下默认支持并开启了