问题描述
在 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);
};
但是 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,
但这不会使 JSX 中的 CSS 类名称可访问并给出警告:
warn Attempted import error: 'block' is not exported from './styles.module.css' (imported as 'styles').
看起来 namedExport
必须设置为 true
才能访问 JSX 中已编译的类名,但是 css-loader 将只接受 camelCaseOnly
或 dashesOnly
exportLocalsConvention
。
我不确定如何在 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"
) 导入它们,但不幸的是没有任何区别。
解决方法
因此,问题出在 esModule
选项中的 css-loader
字段。它是 enabled by default 和:
生成使用 ES 模块语法的 JS 模块。在某些情况下,使用 ES 模块是有益的,例如模块串联和摇树的情况。
据我所知,这将 CSS 类名转换为 JS 变量,其中不能有连字符,因此将它们更改为驼峰式。
因此,为了在 CSS 类名称中保留连字符并使用语法 className={styles["block__element--modifier"])
,我们需要使用以下内容覆盖 css-loader
选项:
options: {
...use.options,esModule: false,modules: {
exportLocalsConvention: "asIs",namedExport: false,},
但是,在通过 gatsby-node.js
将这些选项直接传递给 webpack 配置时,我仍然遇到构建错误,但我找到了使用 Gatsby 插件 gatsby-plugin-postcss
(只有 129B 缩小 + gzipped)和这些选项的解决方法在gatsby-config.js
:
{
resolve: "gatsby-plugin-postcss",options: {
cssLoaderOptions: {
esModule: false,modules: {
exportLocalsConvention: "asIs",
这将产生警告:
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.
然而,这只是一个警告,不会导致任何其他问题!
使用此实现,您将需要使用 Gatsby v2 方法导入样式:
import styles from "./styles.module.css";
请记住,这会阻止 Gatbsy v3 / css-loader
v5 的默认摇树行为。
事实证明,迁移指南here中实际上已经涵盖了这一点。然而,它并不表示使用 exportLocalsConvention: "asIs"
,根据我的测试,这是必需的。