Skip to content

抽离 css 文件

目前,css 代码被 css-loader 转换后,交给的是 style-loader 进行处理。

style-loader 使用的方式是用一段 js 代码,将样式加入到 style 元素中。

而实际的开发中,我们往往希望依赖的样式最终形成一个 css 文件

此时,就需要用到一个库:mini-css-extract-plugin

该库提供了 1 个 plugin 和 1 个 loader

  • plugin:负责生成 css 文件
  • loader:负责记录要生成的 css 文件的内容,同时导出开启 css-module 后的样式对象

使用方式:

js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
  module: {
    rules: [
      //负责记录css内容
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader?modules"],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin(), //负责生成css文件
  ],
};

配置生成的文件名

output.filename的含义一样,即根据 chunk 生成的样式文件名

配置生成的文件名,例如[name].[contenthash:5].css

js
new MiniCssExtractPlugin({
  filename: "css/[name].[contenthash:5].css",
}); //负责生成css文件

默认情况下,每个 chunk 对应一个 css 文件

js
  entry: {
    main: "./src/index.js",		//会生成main.js和main.css
    a: "./src/a.js",			//a.js和a.css
  },

实践

  • 搭建 webpack 环境,package.json 依赖如下
  • 创建对应的文件目录
  • 配置 webpack.config.js
sh
--dist;
--public;
    --index.html;
--src;
    --assets;
        --imgs;
            --webnpack.jpg;
        --index.css;
        --a.css;
    --index.js; //入口文件
    --a.js; //第二入口
--webpack.config.js;
json
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "dev": "webpack-dev-server"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "clean-webpack-plugin": "^3.0.0",
    "css-loader": "^3.4.2",
    "file-loader": "^5.0.2",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.9.0",
    "style-loader": "^1.1.3",
    "webpack": "^4.41.5",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.10.3"
  }
}
js
import "./assets/index.css";
js
//MiniCssExtractPlugin插件的loader也会将css-loader处理好的内容导出。
import styleB from "./assets/b.css";
console.log(styleB);
css
@import "./a.css"; /*会被打包到同一个css文件中,类似js打包出来的bundle*/

.main {
  width: 500px;
  height: 300px;
  background: url("./img/china.jpg");
  background-size: 100% 100%;
}
css
.a {
  color: #f55;
}
js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  mode: "development",
  devtool: "source-map",
  //
  devServer: {
    open: true,
  },
  //
  entry: {
    main: "./src/index.js",
    a: "./src/a.js",
  },
  //
  output: {
    filename: "js/[name].[chunkhash:5].js",
    publicPath: "/", //css中引用了图片,打包之后图片路径会变成相对路径,需要配置publicPath
  },
  //   loader
  module: {
    rules: [
      //使用MiniCssExtractPlugin的静态方法loder
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader?modules"],
      },
      //因为css中会产生图片的引用,所以需要file-loader
      {
        test: /\.jpg$/,
        use: {
          loader: "file-loader",
          options: {
            name: "img/[hash:5].[ext]",
          },
        },
      },
    ],
  },
  //plugin
  plugins: [
    //
    new HtmlWebpackPlugin({
      template: "./public/index.html",
      //   chunks: ["main"],
    }),
    //
    new CleanWebpackPlugin(),
    //使用MiniCssExtractPlugin插件生成css文件
    new MiniCssExtractPlugin({
      filename: "css/[name].[contenthash:5].css",
    }),
  ],
};

最后,执行pnpm run build看打包结果。

MIT License