简体   繁体   English

无法从 CSS 模块转换中跳过 3rd 方库 CSS

[英]Unable to skip 3rd party library CSS from CSS-Module transformation

I am trying CSS Modules for the first time with React and Webpack and I came across at least three ways to achieve it:我第一次使用 React 和 Webpack 尝试 CSS Modules,我遇到了至少三种实现它的方法:

  1. css-loader css加载器
  2. react-css-modules react-css-modules
  3. babel-plugin-react-css-modules babel-plugin-react-css-modules

I went with babel-plugin-react-css-modules in order to balance code simplicity and performance and everything seems to be working fine except for one thing: my 3rd party libraries (Bootstrap and Font Awesome) are also included in CSS Modules transformation.我使用babel-plugin-react-css-modules来平衡代码的简单性和性能,除了一件事之外,一切似乎都运行良好:我的 3rd 方库(Bootstrap 和 Font Awesome)也包含在 CSS Modules 转换中。

<NavLink to="/about" styleName="navigation-button"></NavLink>

The above assigns a properly transformed className to the NavLink .以上将正确转换的className分配给NavLink However, a span inside needs to refer to global styles in order to render an icon.但是,内部的span需要引用全局样式才能呈现图标。

<span className="fa fa-info" />

The above span is not assigned a transformed className which is expected, but my bundled stylesheet does not have these CSS classes as they are being transformed into something else, to simulate local scope.上面的 span 没有分配一个预期的转换className ,但是我的捆绑样式表没有这些 CSS 类,因为它们被转换成其他东西,以模拟本地范围。

Below is the content in my .babelrc file to activate babel-plugin-react-css-modules :以下是我的.babelrc文件中用于激活babel-plugin-react-css-modules

{
  "presets": ["env", "react"],
  "plugins": [
    ["react-css-modules", {
      "generateScopedName": "[name]__[local]___[hash:base64:5]",
      "filetypes": {
        ".less": {
          "syntax": "postcss-less"
        }
      }
    }]
  ]
}

In my Webpack configuration, below is the section to configure css-loader for transforms:在我的 Webpack 配置中,下面是为转换配置css-loader的部分:

{
    test: /\.(less|css)$/,
    exclude: /node_modules/,
    use: extractCSS.extract({
        fallback: 'style-loader',
        use: [
            {
                loader: 'css-loader',
                options: {
                    minimize: true,
                    modules: true,
                    sourceMap: true,
                    localIdentName: '[name]__[local]___[hash:base64:5]'
                }
            },
            {
                loader: 'less-loader'
            }
        ]
    })
}

As far as I have read, the above rule should exclude the library stylesheets and I also tried adding another rule specifically for the excluded stylesheets, however that did not seem to work, as I guess as those stylesheets were still transformed with the original rule.据我所知,上面的规则应该排除库样式表,我还尝试专门为排除的样式表添加另一条规则,但这似乎不起作用,因为我猜这些样式表仍然使用原始规则进行了转换。

In order to import CSS from the two libraries, I have the below two lines in my parent stylesheet that declares some global styles:为了从两个库中导入 CSS,我在父样式表中有以下两行声明了一些全局样式:

@import '../../../node_modules/bootstrap/dist/css/bootstrap.min.css';
@import '../../../node_modules/font-awesome/css/font-awesome.min.css';

I find these two approaches below might be helpful:我发现以下这两种方法可能会有所帮助:

In short, there seems to be no options to ignore/exclude certain paths from being modularized by the css-modules webpack plugin so far.简而言之,到目前为止,似乎没有选项可以忽略/排除某些路径被 css-modules webpack 插件模块化。 Ideally it should be supported by the plugin, but here're some approaches you can try out:理想情况下,插件应该支持它,但您可以尝试以下一些方法:

use two webpack rules to utilise the webpack rule exclusion/inclusion :使用两个 webpack 规则来利用 webpack 规则排除/包含

module.exports = {
  rules: [
    {
      test: /\.css$/,
      exclude: /node_modules/,
      use: [
        'style-loader',
        {
          loader: 'css-loader',
          options: {
            modules: true,
            localIdentName: '[path]__[local]___[hash:base64:5]',
          },
        },
      ],
    },
    {
      test: /\.css$/,
      include: /node_modules/,
      use: ['style-loader', 'css-loader']
    }
  ]
}

...or, inject into webpack's getLocalIdent from the second answer above to manually exclude certain paths. ...或者,从上面的第二个答案中注入 webpack 的 getLocalIdent以手动排除某些路径。

const getLocalIdent = require('css-loader/lib/getLocalIdent');

{
  loader: 'css-loader',
  options: {
    modules: true,
    localIdentName: '[path][name]__[local]--[hash:base64:5]',
    getLocalIdent: (loaderContext, localIdentName, localName, options) => {
      return loaderContext.resourcePath.includes('semantic-ui-css') ?
        localName :
        getLocalIdent(loaderContext, localIdentName, localName, options);
    }
  }
}

For me using :global worked :对我来说,使用:global有效:

.my-component {
    :global {
        .external-ui-component {
           padding: 16px;
           // Some other styling adjustments here
        }
        ...
    }
}

Ps: for doing it with webpack config, please see another answer. Ps:要使用 webpack 配置来做,请参阅另一个答案。

source来源

Updated solution from playing771play771更新解决方案

 {
    loader: 'css-loader',
    options: {
      modules: {
        auto: (resourcePath) => !resourcePath.includes('node_modules'),
        localIdentName: '[name]__[local]__[hash:base64:5]',
      },
    },
 },

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM