zoukankan      html  css  js  c++  java
  • webpack 自动识别 css modules(cssModule混用)

    期望达到的效果

    import Test from './test.less';  // 这样的引入需要css modules
    import './test.less';            // 这样的不需要css modules
    

    虽然 css-loader 自带一些配置可以用来配置是否开启当前文件cssModule(配置特殊的文件名,路径等),但是还是觉得没有上面的那种用起来方便。

    参考 umi css module 的实现,源码:babel-plugin-auto-css-modules,通过写 Babel 插件,在 import 的 url 上加上参数,webpack 匹配这个参数,进行不同的配置。

    这样的引入方式也可以消除开启 css module 后,ant design 组件样式出错的问题

    Babel 插件

    // scripts/plugin/auto-css-modules.js
    const { extname } = require('path');
    const CSS_EXTNAMES = ['.css', '.scss', '.sass', '.less'];
    module.exports = () => {
      return {
        visitor: {
          ImportDeclaration(path) {
            const { specifiers, source } = path.node;
            const { value } = source;
            if (specifiers.length > 0 && CSS_EXTNAMES.includes(extname(value))) {
              source.value = `${value}?css_modules`; // 在路径末尾加上 css_modules 用于 webpack 匹配该文件,如 import Test from './test.less'; 变成 import Test from './test.less?css_modules';
            }
          },
        },
      };
    };
    

    .babelrc 中引入插件

    {
      "presets": [
        "@babel/preset-react",
        "@babel/preset-env",
        "@babel/preset-typescript"
      ],
      "plugins": [
        "@babel/plugin-transform-runtime",
        "@babel/plugin-proposal-class-properties",
        "lodash",
        "./scripts/plugin/auto-css-modules.js", // 引入插件
        ["import", {
          "libraryName": "antd",
          "libraryDirectory": "es",
          "style": "css"
        }]
      ]
    }
    

    在 webpack 中进行配置

    声明两个不同的loader配置

    // 未开启 css module 的 loader
    const cssLoader = [
      'style-loader',
      !isEnvDevelopment && {
        loader: MiniCssExtractPlugin.loader,
      },
      'css-loader',
      {
        loader: 'postcss-loader',
        options: {
          ident: 'postcss',
          plugins: () => [
            require('postcss-preset-env')({
              autoprefixer: {
                flexbox: 'no-2009',
              },
              stage: 3,
            }),
          ],
        },
      },
      {
        loader: 'less-loader',
        options: {
          javascriptEnabled: true,
        },
      },
    ];
    // 开启 css module 的 loader
    const cssModulesLoader = JSON.parse(JSON.stringify(cssLoader));
    cssModulesLoader[2] = {
      loader: 'css-loader',
      options: {
        modules: {
          localIdentName: '[local]_[hash:base64:5]',
        },
      },
    };
    

    webpack rules 配置:

    module: {
      rules: [
        {
          test: /.(css|less)$/,
          oneOf: [
            {
              resourceQuery: /css_modules/, // 只要匹配到了这个,就是用css modules,
              use: cssModulesLoader.filter(Boolean),
            },
            {
              use: cssLoader.filter(Boolean),
            },
          ],
        },
      ]
    }
    

    这样配置后,就可以在项目中查看具体的效果了。。。。。

  • 相关阅读:
    前台传入的application/json;charset=UTF-8格式的数据,java后端从request中获取json数据
    vue-element-admin实战 | 第二篇: 最小改动接入后台实现根据权限动态加载菜单
    vue-element-admin
    进程间通信的几种方式以及线程间通信的几种方式
    vue调用api接口解决跨域问题
    C#多态性(函数重载)
    VirtualBox中安装CentOS7后无法上网的解决方案
    C#继承
    android通过url下载文件
    python的数据爬取
  • 原文地址:https://www.cnblogs.com/hl1223/p/13073628.html
Copyright © 2011-2022 走看看