在故事书 v6.4 中加载 css 模块 类 时出现问题
issue loading css module classes in storybook v6.4
我无法让故事书与我的 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"
}
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"
如果有人正在寻找 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"
我无法让故事书与我的 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"
}
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"
如果有人正在寻找 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"