webpack css-loader、style-loader、mini-css-extract-plugin 的作用

901 阅读2分钟

css-loader

经过 css-loader 处理后,CSS 代码会被转译为等价 JS 字符串,但这些字符串还不会对页面样式产生影响,需要继续接入 style-loader 加载器。

css-loader 只是解决打包报错 但是不会把 css 引入到 html 中

module.exports = {
  module: {
    rules: [
      {
        test: /.css$/i,
        use: ["css-loader"],
      },
    ],
  },
};

style-loader

style-loader 并不会对代码内容做任何修改,而是简单注入一系列运行时代码,用于将 css-loader 转译出的 JS 字符串插入到页面的 style 标签。

PS:注意保持 style-loader 在前,css-loader 在后

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

经过 style-loader + css-loader 处理后,样式代码最终会被写入 Bundle 文件,并在运行时通过 style 标签注入到页面。这种将 JS、CSS 代码合并进同一个产物文件的方式有几个问题:

  • JS、CSS 资源无法并行加载,从而降低页面性能;
  • 资源缓存粒度变大,JS、CSS 任意一种变更都会致使缓存失效。

mini-css-extract-plugin

生产环境中通常会用 mini-css-extract-plugin 插件替代 style-loader,将样式代码抽离成单独的 CSS 文件。

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    module: {
        rules: [{
            test: /.css$/,
            use: [
                // 根据运行环境判断使用那个 loader
                (process.env.NODE_ENV === 'development' ?
                    'style-loader' :
                    MiniCssExtractPlugin.loader),
                'css-loader'
            ]
        }]
    },
    plugins: [
        new MiniCssExtractPlugin(),
        new HTMLWebpackPlugin()
    ]
}

这里需要注意几个点:

  • mini-css-extract-plugin 库同时提供 Loader、Plugin 组件,需要同时使用
  • mini-css-extract-plugin 不能与 style-loader 混用,否则报错,所以上述示例中第 9 行需要判断 process.env.NODE_ENV 环境变量决定使用那个 Loader
  • mini-css-extract-plugin 需要与 html-webpack-plugin 同时使用,才能将产物路径以 link 标签方式插入到 html 中

综上,在 Webpack 中处理 CSS,通常需要使用 css-loader + style-loader 或 css-loader + mini-css-extract-plugin 组合,两种方式最终都能实现加载样式代码的效果。但鉴于原生 CSS 语言的种种缺陷,我们还可以在此基础上增加更多 Webpack 组件,更优雅、高效地编写页面样式

三者的区别

css-loader处理 css 文件
style-loader把 js 中 import 导入的样式文件代码,打包到 js 文件中,运行 js 文件时,将样式自动插入到<style>标签中
mini-css-extract-plugin把 js 中 import 导入的样式文件代码,打包成一个实际的 css 文件,结合 html-webpack-plugin,在 dist/index.html 中以 link 插入 css 文件;默认将 js 中 import 的多个 css 文件,打包时合成一个

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