使用 Gatsby v3 (css-loader v5) 在 CSS 类名中使用短划线

pks*_*pks 5 javascript webpack css-loader gatsby

在 Gatsby v2 中,您可以className={styles["block__element--modifier"]}通过将以下代码添加到来启用此语法gatsby-node.js

const process_rule = rule => {
  if (rule.oneOf) {
    return {
      ...rule,
      oneOf: rule.oneOf.map(process_rule),
    };
  }

  if (Array.isArray(rule.use)) {
    return {
      ...rule,
      use: rule.use.map(use => {
        const css_loader_regex = /\/css-loader\//;

        if (!css_loader_regex.test(use.loader)) {
          return use;
        }

        return {
          ...use,
          options: {
            ...use.options,
            camelCase: false,
          },
        };
      }),
    };
  }

  return rule;
};

exports.onCreateWebpackConfig = ({ getConfig, actions }) => {
  const config = getConfig();

  const new_config = {
    ...config,
    module: {
      ...config.module,
      rules: config.module.rules.map(process_rule),
    },
  };
  actions.replaceWebpackConfig(new_config);
};
Run Code Online (Sandbox Code Playgroud)

然而 Gatsby v3 正在使用 css-loader v5,它不再接受camelCase: false选项中的字段。相反,它具有exportLocalsConvention可以取值的字段asIs,但是在启用namedExport编译器时会抛出错误:

The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "camelCaseOnly" or "dashesOnly".

我试过了:

options: {
  ...use.options,
  modules: {
    ...use.options.modules,
    auto: true,
    exportLocalsConvention: "asIs",
    exportOnlyLocals: false,
    namedExport: false,
  },
},
Run Code Online (Sandbox Code Playgroud)

但这不会使 JSX 中的 CSS 类名称可访问并给出警告:

warn Attempted import error: 'block' is not exported from './styles.module.css' (imported as 'styles').

它看起来像namedExport必须设置为true要访问的JSX编译的类名称但此后CSS加载器将只接受camelCaseOnlydashesOnlyexportLocalsConvention

我不确定如何在 v3 中启用与 Gatsby v2 相同的功能。我希望能够继续使用该className={styles["block__element--modifier"]}语法,因为它可以轻松识别 CSS 类,并且还可以保持 CSS 和 JSX 之间的一致性(我也不想重写一堆代码)。

我正在导入像 Gatsby v2 到 v3 迁移指南解释的样式:

import * as styles from "./styles.module.css"

我也尝试过以旧方式 ( import styles from "./styles.module.css")导入它们,但不幸的是没有任何区别。

pks*_*pks 1

所以事实证明问题出在选项esModule中的字段上css-loader。它默认启用并且:

生成使用 ES 模块语法的 JS 模块。在某些情况下,使用 ES 模块是有益的,例如模块串联和树摇动的情况。

据我了解,这会将 CSS 类名转换为 JS 变量,该变量不能有连字符,因此它们会更改为驼峰命名法。

因此,为了在 CSS 类名中保留连字符并使用className={styles["block__element--modifier"])我们需要重写css-loader选项的语法:

options: {
  ...use.options,
  esModule: false,
  modules: {
    exportLocalsConvention: "asIs",
    namedExport: false,
  },
},
Run Code Online (Sandbox Code Playgroud)

然而,当我将这些选项直接传递给 webpack 配置时,我仍然遇到构建错误,gatsby-node.js但我找到了使用 Gatsby 插件gatsby-plugin-postcss(仅 129B 缩小 + gzipped)以及以下选项的解决方法gatsby-config.js

{
  resolve: "gatsby-plugin-postcss",
  options: {
    cssLoaderOptions: {
      esModule: false,
      modules: {
        exportLocalsConvention: "asIs",
        namedExport: false,
      },
    },
  },
},
Run Code Online (Sandbox Code Playgroud)

这将产生警告:

warn You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on https://www.postcss.parts/ and use them in postcss.config.js.
Run Code Online (Sandbox Code Playgroud)

但这只是一个警告,不会导致任何其他问题!

通过此实现,您将需要使用 Gatsby v2 方法导入样式:

warn You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on https://www.postcss.parts/ and use them in postcss.config.js.
Run Code Online (Sandbox Code Playgroud)

请记住,这可以防止 Gatbsy v3 / css-loaderv5 的默认树抖动行为。

事实证明,这实际上已包含在此处的迁移指南中。exportLocalsConvention: "asIs"然而,根据我的测试,它并不表明需要使用哪个。