如何使用 Next.js、Ant Design、Less 和 TypeScript 配置 Storybook.js Webpack
How can I configure Storybook.js Webpack with Next.js, Ant Design, Less, and TypeScript
我正在尝试配置 Storybook 以使用 Next.js、Ant Design、Less 和 TypeScript。我已经按照我可能找到的所有教程进行操作,但没有任何效果。我将 post 我的配置和下面的错误...
我的 .storybook/main.js
看起来像:
const path = require('path');
module.exports = {
stories: ['../**/*.stories.mdx', '../**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/preset-ant-design',
],
presets: [path.resolve(__dirname, './next-preset.js')],
};
我的 .storybook/next-preset.js
看起来像:
const path = require('path');
module.exports = {
webpackFinal: async (baseConfig, options) => {
// Modify or replace config. Mutating the original reference object can cause unexpected bugs.
const { module = {} } = baseConfig;
const newConfig = {
...baseConfig,
module: {
...module,
rules: [...(module.rules || [])],
},
};
// TypeScript with Next.js
newConfig.module.rules.push({
test: /\.(ts|tsx)$/,
include: [
path.resolve(__dirname, '../components'),
path.resolve(__dirname, '../stories'),
],
use: [
{
loader: 'babel-loader',
options: {
presets: ['next/babel'],
plugins: ['react-docgen'],
},
},
],
});
newConfig.resolve.extensions.push('.ts', '.tsx');
// // SCSS
// newConfig.module.rules.push({
// test: /\.(s*)css$/,
// loaders: ['style-loader', 'css-loader', 'sass-loader'],
// include: path.resolve(__dirname, '../styles/global.scss'),
// });
// Less
newConfig.module.rules.push({
test: /\.less$/,
use: [
'style-loader',
'css-loader',
{
loader: 'less-loader',
options: {
javascriptEnabled: true,
},
},
],
include: path.resolve(__dirname, '../assets/styles'),
});
//
// CSS Modules
// Many thanks to https://github.com/storybookjs/storybook/issues/6055#issuecomment-521046352
//
// First we prevent webpack from using Storybook CSS rules to process CSS modules
newConfig.module.rules.find(
(rule) => rule.test.toString() === '/\.css$/'
).exclude = /\.module\.css$/;
// Then we tell webpack what to do with CSS modules
newConfig.module.rules.push({
test: /\.module\.css$/,
include: [
path.resolve(__dirname, '../common/components'),
path.resolve(__dirname, '../common/layout'),
],
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
},
},
],
});
return newConfig;
},
};
我的 .storybook/preview.js
看起来像:
require('../assets/styles/antd.less');
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
};
我的 antd.less
文件如下所示:
@import '~antd/dist/antd.less';
@primary-color: red;
最后,我的 next.config.js
看起来像:
const withLess = require('@zeit/next-less');
const withCSS = require('@zeit/next-css');
module.exports = withCSS({
cssModules: true,
cssLoaderOptions: {
importLoaders: 1,
localIdentName: '[local]___[hash:base64:5]',
},
...withLess({
lessLoaderOptions: {
javascriptEnabled: true,
},
}),
});
我在尝试 运行 Storybook 时遇到的错误是:
ERROR in ./assets/styles/antd.less (./node_modules/css-loader/dist/cjs.js!./node_modules/less-loader/dist/cjs.js??ref--11-2!./node_modules/style-loader/dist/cjs.js!./node_modules/css-loader/dist/cjs.js!./node_modules/less-loader/dist/cjs.js??ref--16-2!./assets/styles/antd.less)
Module build failed (from ./node_modules/less-loader/dist/cjs.js):
import api from "!../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js";
^
Unrecognised input
in /assets/styles/antd.less (line 1, column 16)
@ ./assets/styles/antd.less 2:12-284 9:17-24 13:7-14 45:20-27 47:4-60:5 49:6-59:7 50:38-45 56:26-33 58:21-28 68:15-22
@ ./.storybook/preview.js
@ ./.storybook/preview.js-generated-config-entry.js
@ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/react/config.js-generated-other-entry.js ./node_modules/@storybook/addon-links/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/defaultParameters.js-generated-other-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined
如有任何帮助,我们将不胜感激。如果我只是从 Storybook 配置中省略所有 Less 配置,我可以让 Storybook 工作,但是 none 我对 Ant Design 的自定义会通过。
编辑 1:
我的相关依赖项是:
"css-loader": "^5.0.1",
"less-loader": "^5.0.0",
"style-loader": "^2.0.0",
"ts-loader": "^8.0.10",
"typescript": "^4.0.5",
"@storybook/addon-actions": "^6.0.28",
"@storybook/addon-essentials": "^6.0.28",
"@storybook/addon-links": "^6.0.28",
"@storybook/preset-ant-design": "0.0.1",
"@storybook/react": "^6.0.28",
"less": "^3.12.2",
"next": "^9.5.5",
"@zeit/next-css": "^1.0.1",
"@zeit/next-less": "^1.0.1",
""antd": "^4.8.0",
编辑 2:
这是 link 到 GitHub repo,您应该可以通过 运行ning npm install
和 npm run storybook
.
重现问题
我发现问题出在使用原始 less
webpack 加载器配置上。但是删除它并不是让它工作的唯一方法。
以下是您必须执行的几个步骤:
- 在添加你的之前删除原来的 less loader:
baseConfig.module.rules = baseConfig.module.rules.filter(
f => f.test.toString() !== '/\.less$/'
);
- 通过包含它们也可以减少
antd
个文件:
{
test: /\.less$/,
include: [
/[\/]node_modules[\/].*antd/,
// ...
],
}
- 简而言之,这是您的最终配置:
const path = require('path');
module.exports = {
webpackFinal: async (baseConfig, options) => {
const { module = {} } = baseConfig;
// Remove original less loader
baseConfig.module.rules = baseConfig.module.rules.filter(
f => f.test.toString() !== '/\.less$/'
);
const newConfig = {
...baseConfig,
module: {
...module,
rules: [...(module.rules || [])],
},
};
// ...
// Less
newConfig.module.rules.push({
test: /\.less$/,
include: [
// Include antd to rebuild
/[\/]node_modules[\/].*antd/,
path.resolve(__dirname, '../assets/styles'),
],
use: [
'style-loader',
'css-loader',
{
loader: 'less-loader',
options: {
javascriptEnabled: true,
},
},
],
});
//...
return newConfig;
},
};
我正在尝试配置 Storybook 以使用 Next.js、Ant Design、Less 和 TypeScript。我已经按照我可能找到的所有教程进行操作,但没有任何效果。我将 post 我的配置和下面的错误...
我的 .storybook/main.js
看起来像:
const path = require('path');
module.exports = {
stories: ['../**/*.stories.mdx', '../**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/preset-ant-design',
],
presets: [path.resolve(__dirname, './next-preset.js')],
};
我的 .storybook/next-preset.js
看起来像:
const path = require('path');
module.exports = {
webpackFinal: async (baseConfig, options) => {
// Modify or replace config. Mutating the original reference object can cause unexpected bugs.
const { module = {} } = baseConfig;
const newConfig = {
...baseConfig,
module: {
...module,
rules: [...(module.rules || [])],
},
};
// TypeScript with Next.js
newConfig.module.rules.push({
test: /\.(ts|tsx)$/,
include: [
path.resolve(__dirname, '../components'),
path.resolve(__dirname, '../stories'),
],
use: [
{
loader: 'babel-loader',
options: {
presets: ['next/babel'],
plugins: ['react-docgen'],
},
},
],
});
newConfig.resolve.extensions.push('.ts', '.tsx');
// // SCSS
// newConfig.module.rules.push({
// test: /\.(s*)css$/,
// loaders: ['style-loader', 'css-loader', 'sass-loader'],
// include: path.resolve(__dirname, '../styles/global.scss'),
// });
// Less
newConfig.module.rules.push({
test: /\.less$/,
use: [
'style-loader',
'css-loader',
{
loader: 'less-loader',
options: {
javascriptEnabled: true,
},
},
],
include: path.resolve(__dirname, '../assets/styles'),
});
//
// CSS Modules
// Many thanks to https://github.com/storybookjs/storybook/issues/6055#issuecomment-521046352
//
// First we prevent webpack from using Storybook CSS rules to process CSS modules
newConfig.module.rules.find(
(rule) => rule.test.toString() === '/\.css$/'
).exclude = /\.module\.css$/;
// Then we tell webpack what to do with CSS modules
newConfig.module.rules.push({
test: /\.module\.css$/,
include: [
path.resolve(__dirname, '../common/components'),
path.resolve(__dirname, '../common/layout'),
],
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
},
},
],
});
return newConfig;
},
};
我的 .storybook/preview.js
看起来像:
require('../assets/styles/antd.less');
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
};
我的 antd.less
文件如下所示:
@import '~antd/dist/antd.less';
@primary-color: red;
最后,我的 next.config.js
看起来像:
const withLess = require('@zeit/next-less');
const withCSS = require('@zeit/next-css');
module.exports = withCSS({
cssModules: true,
cssLoaderOptions: {
importLoaders: 1,
localIdentName: '[local]___[hash:base64:5]',
},
...withLess({
lessLoaderOptions: {
javascriptEnabled: true,
},
}),
});
我在尝试 运行 Storybook 时遇到的错误是:
ERROR in ./assets/styles/antd.less (./node_modules/css-loader/dist/cjs.js!./node_modules/less-loader/dist/cjs.js??ref--11-2!./node_modules/style-loader/dist/cjs.js!./node_modules/css-loader/dist/cjs.js!./node_modules/less-loader/dist/cjs.js??ref--16-2!./assets/styles/antd.less)
Module build failed (from ./node_modules/less-loader/dist/cjs.js):
import api from "!../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js";
^
Unrecognised input
in /assets/styles/antd.less (line 1, column 16)
@ ./assets/styles/antd.less 2:12-284 9:17-24 13:7-14 45:20-27 47:4-60:5 49:6-59:7 50:38-45 56:26-33 58:21-28 68:15-22
@ ./.storybook/preview.js
@ ./.storybook/preview.js-generated-config-entry.js
@ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/react/config.js-generated-other-entry.js ./node_modules/@storybook/addon-links/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/defaultParameters.js-generated-other-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined
如有任何帮助,我们将不胜感激。如果我只是从 Storybook 配置中省略所有 Less 配置,我可以让 Storybook 工作,但是 none 我对 Ant Design 的自定义会通过。
编辑 1: 我的相关依赖项是:
"css-loader": "^5.0.1",
"less-loader": "^5.0.0",
"style-loader": "^2.0.0",
"ts-loader": "^8.0.10",
"typescript": "^4.0.5",
"@storybook/addon-actions": "^6.0.28",
"@storybook/addon-essentials": "^6.0.28",
"@storybook/addon-links": "^6.0.28",
"@storybook/preset-ant-design": "0.0.1",
"@storybook/react": "^6.0.28",
"less": "^3.12.2",
"next": "^9.5.5",
"@zeit/next-css": "^1.0.1",
"@zeit/next-less": "^1.0.1",
""antd": "^4.8.0",
编辑 2:
这是 link 到 GitHub repo,您应该可以通过 运行ning npm install
和 npm run storybook
.
我发现问题出在使用原始 less
webpack 加载器配置上。但是删除它并不是让它工作的唯一方法。
以下是您必须执行的几个步骤:
- 在添加你的之前删除原来的 less loader:
baseConfig.module.rules = baseConfig.module.rules.filter(
f => f.test.toString() !== '/\.less$/'
);
- 通过包含它们也可以减少
antd
个文件:
{
test: /\.less$/,
include: [
/[\/]node_modules[\/].*antd/,
// ...
],
}
- 简而言之,这是您的最终配置:
const path = require('path');
module.exports = {
webpackFinal: async (baseConfig, options) => {
const { module = {} } = baseConfig;
// Remove original less loader
baseConfig.module.rules = baseConfig.module.rules.filter(
f => f.test.toString() !== '/\.less$/'
);
const newConfig = {
...baseConfig,
module: {
...module,
rules: [...(module.rules || [])],
},
};
// ...
// Less
newConfig.module.rules.push({
test: /\.less$/,
include: [
// Include antd to rebuild
/[\/]node_modules[\/].*antd/,
path.resolve(__dirname, '../assets/styles'),
],
use: [
'style-loader',
'css-loader',
{
loader: 'less-loader',
options: {
javascriptEnabled: true,
},
},
],
});
//...
return newConfig;
},
};