Webpack 阻止为某些具有 css 个模块的文件发出 css

Webpack prevent emit css for some files with css modules

我正在尝试以这种方式配置 webpack,对于某些 .css 文件,它不会发出 css(不向 styles.css) 添加任何内容,但会发出局部变量(className 到 js 中导入对象中的样式映射)。在 css-loader 中,modules 选项始终启用(又名 CSS Modules)。例如:

在一些.js文件中:

import cssNoEmit from './styles.noemit.scss'
import cssEmit from './styles.scss'

styles.noemit.scss的内容:

.testNoEmit {
  background: orange;
}

styles.scss的内容:

.testEmit {
  background: blue;
}

我想实现的是最终生成的.css只包含.testEmitclass。此外,cssNoEmitcssEmit 都包含到生成的 .css

中相关 classes 的映射

可能可以用 extract-text-plugin 解决这个问题,但我不是在寻找那个解决方案,因为这个插件已被弃用。

这是我尝试过的方法:

所有尝试都有可重现的例子here

编辑:尝试 1(感谢@felixmosh)和 5 成功了。

尝试 1(有效)css-loader 有一个选项 onlyLocalscss-loader documentation 中的描述非常模糊,但据我了解,它应该做的事情与我想要实现的完全相同。

  {
    test: /\.noemit\.scss$/,
    use: [
      //MiniCssExtractPlugin.loader, // after disabling this, it started to work
      {
        loader: 'css-loader',
        options: {
          modules: {
            mode: 'local',
            exportGlobals: true,
            localIdentName: '[path][name]__[local]--[hash:base64:5]',
            context: path.resolve(__dirname, 'src'),
            hashPrefix: '_',
          },
          importLoaders: 2,
          onlyLocals: true, // setting this to true causes transpilation to crash
        },
      },
      
      ...

    ],
  },

尝试 5(有效,不完美)。尝试使用 webpack 内置功能 SplitChunksPlugin。我尝试基于 this, SplitChinksPlugin docs, this, this.

为此用例创建配置
  ...

  optimization: {
    splitChunks: {
      cacheGroups: {
        groupUnusedStyles: {
          name: "unusedStyles",
          chunks: "all",

          test: /\.noemit\.scss$/,

          enforce: true
        },
      }
    }
  }

这种方法将不需要的 css 重定向到 unusedStyles.css

它有效,但有一个小但令人沮丧的缺点。除了 unusedStyles.css 之外,它会生成 unusedStyles.js 并且必须包含在 html 中,否则应用程序不会 运行.

更具体地说,两个块都必须在 html:

  <script type="text/javascript" src="/app.bundle.js"></script>
  <script type="text/javascript" src="/unusedStyles.bundle.js"></script>

有谁知道如何在不需要添加另一个包的情况下使其工作?

尝试 2(无效)。不要使用 onlyLocals 设置并省略负责“css 输出”的加载程序(例如 style-loadermini-extract-css-plugin)。在这种情况下导入的内容 css 很奇怪

尝试 3(无效) null-loader 也无效,因为它只导入一个空对象

尝试 4(无效)There是另一种思路:

class ServerMiniCssExtractPlugin extends MiniCssExtractPlugin {
  getCssChunkObject(mainChunk) {
    return {};
  }
}

... // use ServerMiniCssExtractPlugin the same way as MiniCssExtractPlugin 

这行不通,因为final .css有所有样式,就好像使用了普通的MiniCssExtractPlugin

此外,there 是 github 上的相关主题。

您的第一次尝试是正确的,只需从 noemit.scss 加载程序列表中删除 MiniCssExtractPlugin.loader

我已经在本地试过了,它有效,out css 只包含 none "noemit" 文件,但是两者都有 css-modules 对象映射.

删除的加载程序 (MiniCssExtractPlugin) 是负责在最终 css 文件中包含 scss 的加载程序。