【webpack】如何利用style-loader、css-loader、postcss-loader等配置css环境

webpack

如此熟悉的配置肯定有看到过,但是你知道他们每个loader具体是干啥的吗。

const path = require("path");

module.exports = {
  entry: "./src/index.js",
  mode: "development",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
  },
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

style-loader

作用

  • 将css注入到DOM。即将css样式注入到style标签

【webpack】如何利用style-loader、css-loader、postcss-loader等配置css环境

css-loader

作用

css-loader对 @import 和 url() 进行处理

几个重要属性

  • url. 启用/禁用 url/image-set 函数进行处理
background-image: url('image.png') 
background-image: url('./image.png') 
background-image: url('~module/image.png')
image-set(url('image2x.png') 1x, url('image1x.png') 2x)

...
  • import. 启用/禁用 @import 规则进行处理
@import 'style.css' 
// 俩种情况可以使用前缀,
// 1、`node_modules` path (include `resolve.modules`) 
// 2、for `alias`
@import url('~module/style.css')
@import url('~module/style.css')
...

以前我就碰过这种问题,在css中为啥不可以使用 ~ ,现在总算是明白了,毕竟之前没有这样去配置过

module.exports = {
  module: {
    rules: [
      {
        test: /.css$/i,
        loader: "css-loader",
        options: {
          import: true,
        },
      },
    ],
  },
};
  • importLoaders。 用于配置在处理@import规则、CSS modules 、 ICSS imports之前应用的加载器数量
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          process.env.NODE_ENV === "development"
            ? "style-loader"
            : MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              importLoaders: 2,
              // 0 => no loaders (default);
              // 1 => postcss-loader;
              // 2 => postcss-loader, sass-loader
              modules: {
                localIdentName: "[local]_[hash:base64:5]",
              },
            },
          },
        ],
      },
    ],
  },
};

其余更多的属性参考css-loader

css module

现在项目里面基本上都有这种写法

/* style.css */
.className {
  color: green;
}

import styles from "./style.css";

那么webpack中应该怎么配置

  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          process.env.NODE_ENV === "development"
            ? "style-loader"
            : MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              modules: {
                localIdentName: "[local]_[hash:base64:5]",
              },
            },
          },
        ],
      },
    ],
  },

更多参数css-loader

mini-css-extract-plugin

这个插件基于Webpack 5, 4是 extract-text-webpack-plugin

作用:将CSS提取到单独的文件中,为每个包含CSS的JS文件创建一个CSS文件,并且支持CSS和SOurceMaps的按需加载

注意: style-loader 不要和 mini-css-extract-plugin一起使用,这是因为development 环境使用了webpack-dev-server,它使用了multiple,注入css非常快。但是在production环境使用mini-css-extract-plugin分离css

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

  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          process.env.NODE_ENV === "development"
            ? "style-loader"
            : MiniCssExtractPlugin.loader,
          "css-loader",
        ],
      },
    ],
  },

预处理器

pnpm add --save-dev sass-loader less-loader stylus-loader
 module: {
   rules: [
    {
      test: /\.(scss|sass)$/,
      use: [
        process.env.NODE_ENV === "development"
          ? "style-loader"
          : MiniCssExtractPlugin.loader,
        "css-loader",
        "sass-loader"
      ],
    },
  ],
},

其他也是同理

PostCSS

PostCSS是一个使用JavaScript编写的工具,用于对CSS进行转换和处理。它可以通过插件机制对CSS进行各种自定义的转换操作,从而扩展CSS的功能和语法。而其他CSS预处理器,如SassLess,主要是将特定语法的样式文件编译为浏览器可以识别的CSS文件。

两者并非是互斥的关系,既能复用预处理语法特性,又能应用PostCSS丰富的插件能力处理如浏览器前缀等问题

pnpm add postcss-loader postcss  autoprefixer --save-dev
 {
   loader: "postcss-loader",
    options: {
       postcssOptions: {
          plugins: [
                [
                    "autoprefixer",
                    {
                      // autoprefixer options
                    },
             ],
          ],
      },
   },
},

完整的配置

以上配置支持了 csscss modulelessless modulesass/scsssass/scss module, 并且根据用户是否用了taildwindcss,而动态引入PostCSS 插件tailwindcss

这里再提醒一句,style-loadermini-css-extract-plugin需要根据环境来区分,生产用mini-css-extract-plugin, 开发用style-loader。这是因为style-loader 只会将css会处理成js文件,而mini-css-extract-plugin会分离

还有就是在处理 CSS Module的时候, mode的取值有local,也有icssglobalpure,详见css loader

  • pure: 没有全局或局部模式,所有的类名都将被局部化
  • local: 在这种模式下,所有的类名默认都会被局部化,也就是说,它们会被转换为唯一的类名以避免冲突。这意味着,即使你在不同的CSS文件中定义了相同的类名,它们也不会冲突,因为css-loader会为每个类名生成一个唯一的标识符。你可以使用:global伪类来切换到全局模式,这样类名就不会被局部化
  • global: 在这种模式下,所有的类名默认都会被视为全局类名,也就是说,它们会保持原样,不会被转换为唯一的类名。这意味着,如果你在不同的CSS文件中定义了相同的类名,它们可能会冲突。你可以使用:local伪类来切换到局部模式,这样类名就会被局部化
  • icss: 是一种CSS模块化的规范,定义了一种方式在CSS中表示导入和导出

vite

看了下vite的文档,类似于cli工具一样,将大部分已经封装在内部。

  • 比如导入.css文件会自动插入到style标签中,源码像是在这里css实现的, 然后结合html插件html

【webpack】如何利用style-loader、css-loader、postcss-loader等配置css环境

【webpack】如何利用style-loader、css-loader、postcss-loader等配置css环境

  • 对于@importurl这种语法识别, vite是通过postcss-import来实现的

  • CSS Module 处理。如果写成module.css也会被认为是一个CSS Module文件,所以用户根本不需要操心背后干了啥, 内部用postcss-modules进行处理的

  • CSS预处理器。则需要安装的对应的预处理器依赖

  • CSS压缩。vite默认采用esbuild,umi默认压缩也是esbuild, vite也可以设置lightnigncss

原文链接:https://juejin.cn/post/7316357622847930387 作者:南蓝

(0)
上一篇 2023年12月26日 下午5:10
下一篇 2023年12月27日 上午10:00

相关推荐

发表回复

登录后才能评论