Webpack5 如何抽离和压缩 CSS

1,667 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情

如何抽离和压缩 CSS

前面,我们实现了 loader 加载 CSS,但是,CSS 样式和 HTML 在一起。在多数情况下,我们也可以进行压缩 CSS,以便在生产环境中节省加载时间,能不能将 style.css 样式文件的代码放置到一个单独的文件中,通过 标签加载它呢?这是肯定可以的。

那么,如何实现这个功能呢,我们需要借助 mini-css-extract-plugin 插件来实现。mini-css-extract-plugin 插件会将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。mini-css-extractplugin 插件基于 webpack 5 的新特性构建,并且需要 webpack 5 才能正常工作。

它与 extract-text-webpack-plugin 相比,具有异步加载、没有重复的编译(性能)、更容易使用和特别针对 CSS 开发优点

首先,你需要在本地安装 mini-css-extract-plugin:

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

建议 mini-css-extract-plugin 与 css-loader 一起使用。

插件安装成功之后,我们就可以在 webpack.config.js 配置文件引入和配置这个插件。

大家思考一下,之前 CSS 是通过 style-loader 放置到页面的 标签里的。现在,我们打算单独抽离 CSS 文件,因此,style-loader 无效了,需要用一个新的 loader 来代替它,这个 loader 就是 mini-css-extract-plugin 插件中 loader。

//webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
//...
module.exports = {
    //...
    plugins: [
        //...
        new MiniCssExtractPlugin(),
    ],


  //...


    module: {
        rules: [
             //...
              {
                test:/.css$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader'],
            },
        ]
    }
}

编译打包之后,可以看到在项目 dist 目录下生成 main.css 文件。

image.png

同时在 index_app.html 中没有 标签,但是生成 标签,通过 标签加载本地 main.css 样式,这个功能要得益于 html-webpack-plugin 插件。

<link href="main.css" rel="stylesheet">

 这里需要注意两点:

  • 如果你从 webpack 入口处导入 CSS 或者在 初始 chunk 中引入 style, mini-css-extract-plugin 则不会将这些 CSS 加载到页面中。请使用 html-webpack-plugin 自动生成 link 标签或者在创建 index.html 文件时使用 link 标签。

  • source map 只在 source-map/nosources-source-map/hidden-nosources-source-map/hidden-source-map 值情况下起作用,因为 CSS 仅支持带有 sourceMappingURL 注释的 source map (例如 //# sourceMappingURL=style.css.map)。如果你需要将 devtool 设置为其他值,你可以使用 css-loader 中的 sourceMap: true 来启用提取并生成 CSS 的 source map。

我们能不能自已去指定这个 CSS 样式所在的文件夹以及文件名呢?其实我们只需要在实例化 mini-css-extract-plugin 插件的时候,设置属性选项即可。mini-css-extract-plugin 给我们提供 8 个可选项属性。

在 webpack.config.js 配置文件初始化 mini-css-extract-plugin 插件是使用 filename 属性设置自定义输出文件名和路径。

//webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
//...
module.exports = {
    //...
    plugins: [
        //...
        new MiniCssExtractPlugin({
          filename:'style/[contenthash].css',
        }),
    ],


  //...


    module: {
        rules: [
             //...
              {
                test:/.css$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader'],
            },
        ]
    }
}

编译打包之后,可以看到在项目的 dist 下生成 style 目录,并且生成 hash 字符串名称的 CSS 样式文件。

image.png

发现通过 mini-css-extract-plugin 插件生成 CSS 样式文件并没有压缩和优化,为了压缩输出文件,需要借助 css-minimizer-webpack-plugin 插件来完成 CSS 样式文件的压缩。

要使用该插件,必须现先在本地安装它:

npm install css-minimizer-webpack-plugin --save-dev 

只安装没有用,要使用该插件能够生效,我们必须在 webpack.config.js 配置文件进行配置。需要注意,这个插件不是在 plugin(插件) 中进行配置,而是在optimization(优化)中进行配置。

// webpack.config.js
//...
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");


module.exports = {
    //...
    optimization: {
        minimizer: [
          // 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
          // `...`,
          new CssMinimizerPlugin(),
        ],
      },
}

编译打包,打开 .css样式文件,发现 CSS 样式文件已经被压缩。默认情况下仅在生产环境开启 CSS 优化。如果还想在开发环境下启用 CSS 优化,需要在 webpack.config.js 配置文件中将 optimization.minimize 设置为 true。

// webpack.config.js
//...
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");


module.exports = {
    //...
    optimization: {
        minimizer: [
          // 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
          // `...`,
          new CssMinimizerPlugin(),
        ],
       minimize:true,
      },
}