如何在 Webpack 项目中构建现代 CSS 工程环境?

87 阅读2分钟

原生 Webpack 并不能识别 CSS 语法,通常需要使用以下 loader 来处理:

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

image.png

处理原生 CSS 方案

  1. 安装依赖
yarn add -D mini-css-extract-plugin style-loader css-loader

2. 搭建 Webpack 配置

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  module: {
    rules: [
      {
        test: /.css$/i,
        // 注意保持 style-loader在前,css-loader 在后
        use: [
                // 根据运行环境判断使用那个 loader
                (process.env.NODE_ENV === 'development' ?
                    'style-loader' :
                    MiniCssExtractPlugin.loader),
                'css-loader'
        ],
      },
    ],
  },
    plugins: [
        new MiniCssExtractPlugin(),
        new HTMLWebpackPlugin()
    ]
};

3. 解析 * style-loader + css-loader处理后,样式代码最终会被写入 Bundle 文件,并在运行时通过 style标签注入到页面。这种将 JS、CSS 代码合并到同一个产物文件的方式有两个问题: * JS、CSS 资源无法并行加载、从而降低页面性能 * 资源缓存粒度变大,JS、CSS 任意一种变更都会导致缓存失效。 * 解决上述问题,可以使用 mini-css-extract-plugin 插件替代 style-loader,将样式代码抽离成单独的 CSS 文件。注意事项如下: * mini-css-extract-plugin库同时提供 Loader、Plugin 组件,需要同时使用 * mini-css-extract-pluginstyle-loader混用会报错,所以结合环境变量决定使用哪个 loader * mini-css-extract-plugin需要与html-webpack-plugin同时使用,才能将产物路径以link标签方式插入到 html 中

less 方案

  1. 安装依赖
yarn add -D less less-loader

2. 搭建 Webpack 配置

module.exports = {
    module: {
        rules: [{
            test: /.less$/,
            use: [
                'style-loader',
                'css-loader',
                'less-loader'
            ]
        }]
    }
}

sass方案

  1. 安装依赖
yarn add -D sass sass-loader

2. 搭建 Webpack 配置

module.exports = {
    module: {
        rules: [{
            test: /\.s(ac)ss$/,
            use: [
                'style-loader',
                'css-loader',
                'sass-loader'
            ]
        }]
    }
}

stylus方案

  1. 安装依赖
yarn add -D stylus stylus-loader

2. 搭建 Webpack 配置

module.exports = {
    module: {
        rules: [{
            test: /\.styl$/,
            use: [
                'style-loader',
                'css-loader',
                'stylus-loader'
            ]
        }]
    }
}

post-css+less方案

  1. 安装依赖
yarn add -D postcss postcss-loader less less-loader autoprefixer

2. 搭建 Webpack 配置

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

3. 解析 * postcss在原生 CSS 基础上增加更多表达力、可维护性、可读性更强的语言特性。 * 使用 autoprefixer插件,通过 Webpack机制,为 CSS 代码自动添加浏览器前缀,实现自动兼容功能

其他

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