CSS 模块导入在 Gatsby 和 Storybook 中的行为不同

CSS Modules import behaves differently in Gatsby vs Storybook

我正在构建一个 Gatsby 网络应用程序,其中每个组件都有一个 .module.css 文件、一个 .jsx 文件和一个 stories.jsx 文件。我正在使用以下导入行 as required by Gatsby(尽管没有 tree shaking):

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

然后,例如,如果我的 filename.module.css 中有一个名为 .button 的 CSS 选择器,则关联 class 名称可以在 styles 对象为 styles.button.

但是,同样的 styles.button 并没有在 Storybook 中访问正确的 class 名称,它 returns undefined。检查 styles 对象后,我发现 class 名称包含在 styles 内的 default 对象中。我假设我必须以与 Gatsby 相同的方式处理导入的方式配置 Storybook。我同样发现使用以下导入在 Storybook 中有效,但在 Gatsby 中无效:

import styles from ./"filename.module.css"

关于如何配置 Storybook 以与 Gatsby 相同的方式处理 CSS 模块导入的任何建议?理想情况下,我想避免 tree shaking CSS 模块,并且从一些快速测试来看,这似乎不是问题的原因。

是 webpack 决定了你的样式是否会摇动,以及需要使用一个语句 (import * as styles from "./filename.module.css") 还是另一个 (import styles from "./filename.module.css")。似乎您在每个项目上使用不同的版本,因此 CSS 模块的行为也会发生变化。

在所有选项中,我建议使用 Gatsby 要求的命名导入,因为正如我所说,它允许 webpack 对您的样式进行 tree shake,从而提高网站的性能。

而不是:

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

最好导入每个特定的 CSS 模块并单独应用它们:

import { style1, style2 } from "./filename.module.css"

摘自:

使用第二种方法将成为您项目的有效语法。

如果您仍想更改 Storybook 的行为(以避免 tree shaking),您可以尝试如下配置 Storybook(在您的 .storybook/main.js 中):

const path = require("path");

module.exports = {
  // You will want to change this to wherever your Stories will live
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
  core: {
    builder: "webpack5",
  },
  webpackFinal: async (config) => {
    // Prevent webpack from using Storybook CSS rules to process CSS modules
    config.module.rules.find(
      (rule) => rule.test.toString() === "/\.css$/"
    ).exclude = /\.module\.css$/;

    // Tell webpack what to do with CSS modules
    config.module.rules.push({
      test: /\.module\.css$/,
      include: path.resolve(__dirname, "../src"),
      use: [
        {
          loader: "style-loader",
          options: {
            modules: {
              namedExport: true,
            },
          },
        },
        {
          loader: "css-loader",
          options: {
            importLoaders: 1,
            modules: {
              namedExport: true,
            },
          },
        },
      ],
    });
    // Transpile Gatsby module because Gatsby includes un-transpiled ES6 code.
    config.module.rules[0].exclude = [/node_modules\/(?!(gatsby)\/)/];
    // use babel-plugin-remove-graphql-queries to remove static queries from components when rendering in storybook
    config.module.rules[0].use[0].options.plugins.push(
      require.resolve("babel-plugin-remove-graphql-queries")
    );
    return config;
  },
};

其他资源: