在 storybook v6.4 中加载 css 模块类的问题

Posted

技术标签:

【中文标题】在 storybook v6.4 中加载 css 模块类的问题【英文标题】:issue loading css module classes in storybook v6.4 【发布时间】:2021-09-09 04:37:06 【问题描述】:

我在让 Storybook 与我的 Gatsby 项目中的 css 模块配合使用时遇到了麻烦。我能够渲染按钮组件,但它没有添加我的任何样式。在检查元素时,我只从以下代码中得到undefined undefined

button.jsx

import React from "react"
import * as css from "./style.module.css"

const Button = ( variant = "button", type, value = null ) => 
  const baseOfVariant = () => 
    if (variant === "input") 
      return (
        <input
          type=type
          value=value
          className=`$css.button $css.clear_button`
        />
      )
    
    return (
      <button type=type className=`$css.button $css.submit_button`>
        value
      </button>
    )
  
  return baseOfVariant()


export default Button

button.stories.jsx

import React from "react"
import Button from "./button"

export default 
  title: "Button",
  component: Button,


export const Template = args => <Button ...args />

export const ButtonRegular = Template.bind()
ButtonRegular.args = 
  variant: "button",
  value: "Click Me",
  type: "submit",

main.js

module.exports = 
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
  core: 
    builder: "webpack5",
  ,

我的 devDeps 中的故事书内容

"devDependencies": 
    "@babel/core": "^7.14.6",
    "@babel/polyfill": "^7.12.1",
    "@storybook/addon-actions": "^6.4.0-alpha.2",
    "@storybook/addon-essentials": "^6.4.0-alpha.2",
    "@storybook/addon-links": "^6.4.0-alpha.2",
    "@storybook/addon-viewport": "^6.4.0-alpha.2",
    "@storybook/builder-webpack5": "^6.4.0-alpha.2",
    "@storybook/manager-webpack5": "^6.4.0-alpha.2",
    "@storybook/react": "^6.4.0-alpha.2",
    "babel-loader": "^8.2.2",
    "prettier": "2.2.1",
    "resize-observer-polyfill": "^1.5.1"
  

【问题讨论】:

【参考方案1】:

如果有人正在寻找 sass/scss 相关的修复

import * as style from "./style.module.scss"

Storybook 仅识别此合成器:

您的.storybook/main.js 文件。

 const path = require("path");
    
    module.exports = 
        stories: ["../src/**/*.stories.js,mdx"],
        addons: [
            "@storybook/addon-docs",
            "@storybook/addon-actions",
            "@storybook/addon-controls",
            "@storybook/addon-a11y",
            "@storybook/addon-viewport",
        ],
        // https://gist.github.com/shilman/8856ea1786dcd247139b47b270912324
        core: 
            builder: "webpack5",
        ,
        webpackFinal: async config => 
            // https://www.gatsbyjs.com/docs/how-to/testing/visual-testing-with-storybook/
            config.module.rules.push(
                test: /\.(js)$/,
                use: [
                    
                        loader: require.resolve("babel-loader"),
                        options: 
                            presets: [
                                // use @babel/preset-react for JSX and env (instead of staged presets)
                                require.resolve("@babel/preset-react"),
                                require.resolve("@babel/preset-env"),
                            ],
                            plugins: [
                                // use @babel/plugin-proposal-class-properties for class arrow functions
                                require.resolve("@babel/plugin-proposal-class-properties"),
                                // use babel-plugin-remove-graphql-queries to remove static queries from components when rendering in storybook
                                require.resolve("babel-plugin-remove-graphql-queries"),
                                // use babel-plugin-react-docgen to ensure PropTables still appear
                                require.resolve("babel-plugin-react-docgen"),
                            ],
                        ,
                    ,
                ],
                exclude: [/node_modules\/(?!(gatsby)\/)/],
            );
    
            config.module.rules.push(
                test: /\.s[ac]ss$/i,
                oneOf: [
                    // module.scss files (e.g component styles.module.scss)
                    // https://webpack.js.org/loaders/style-loader/#modules
                    
                        test: /\.module\.s?css$/,
                        use: [
                            // Add exports of a module as style to DOM
                            
                                loader: "style-loader",
                                options: 
                                    esModule: true,
                                    modules: 
                                        namedExport: true,
                                    ,
                                ,
                            ,
                            // Loads CSS file with resolved imports and returns CSS code
                            
                                loader: "css-loader",
                                options: 
                                    esModule: true,
                                    modules: 
                                        namedExport: true,
                                    ,
                                ,
                            ,
                            // Loads and compiles a SASS/SCSS file
                            
                                loader: "sass-loader",
// only if you are using additional global variable
                                options: 
                                    additionalData: "@import 'src/styles/global.scss';",
                                    sassOptions: 
                                        includePaths: ["src/styles"],
                                    ,
                                ,
                            ,
                        ],
                    ,
                    // scss files that are not modules (e.g. custom.scss)
                    
                        use: [
                            // Add exports of a module as style to DOM
                            "style-loader",
                            // Loads CSS file with resolved imports and returns CSS code
                            "css-loader",
                            // Loads and compiles a SASS/SCSS file
                            
                                loader: "sass-loader",
// only if you are using additional global variable
                                options: 
                                    additionalData: "@import 'src/styles/global.scss';",
                                    sassOptions: 
                                        includePaths: ["src/styles"],
                                    ,
                                ,
                            ,
                        ],
                    ,
                ],
            );
    
            return config;
        ,
    ;

通过上述配置,Storybook 现在接受此导入合成器,并且 button.jsx 的样式正确。

import * as styles from "./style.module.scss"

【讨论】:

【参考方案2】:

Gatsby 需要使用以下合成器导入 css 模块:

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

Storybook 仅识别此合成器:

import css from "./style.module.css"

这是因为 Gatsby 和 Storybook 不使用相同的导入约定。幸运的是,您可以通过.storybook/main.js 文件配置 Storybook css 模块导入机制。

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
  ,

通过上述配置,Storybook 现在接受此导入合成器并且button.jsx 的样式正确。

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

【讨论】:

以上是关于在 storybook v6.4 中加载 css 模块类的问题的主要内容,如果未能解决你的问题,请参考以下文章

@font-face 未在反应应用程序中加载(故事书)

什么相当于 Storybook 中的 Meteor.startup

无法在 codeigniter 中加载 Css

在 Django 中加载 CSS/图像

在 Django 中的 css 文件中加载静态文件

无法在 html 页面中加载 Css 文件