I'm trying to setup Storybook for the shared components library which uses stylus.
And this is what I'm getting after running npm run build-storybook
ERR! => Failed to build the preview
ERR! Module build failed (from ./node_modules/css-loader/dist/cjs.js):
ERR!
ERR! SyntaxError
ERR!
ERR! (1:1) /Users/user/Work/webcomponents/src/components/button/buttonV2/buttonV2.styl Unknown word
ERR!
ERR! > 1 | [Root]
ERR! | ^
ERR!
Here is my Storybook config: (.storybook/main.ts)
import type { StorybookConfig } from "@storybook/react-webpack5";
import commonConfig from '../webpack.config'
const defaultWebpackConfig = commonConfig();
const config: StorybookConfig = {
stories: ["../src/**/button.stories.ts"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
framework: {
name: "@storybook/react-webpack5",
options: {},
},
docs: {
autodocs: "tag",
},
core: {
disableTelemetry: true
},
webpackFinal: async (config) => {
config?.module?.rules?.push(
// manually push stylus rules, which is 3rd & 4th
defaultWebpackConfig.module.rules[2],
defaultWebpackConfig.module.rules[3],
);
config.resolve!.alias = Object.assign(
{},
config?.resolve?.alias,
defaultWebpackConfig.resolve.alias,
);
config.resolve!.extensions!.push('.ts', '.tsx', '.js', '.styl');
return config;
}
};
export default config;
Here is my Webpack config:
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = (env, argv) => {
const isProd = argv?.mode === 'production';
return {
entry: path.resolve(__dirname, './src/components/index.ts'),
devtool: isProd ? 'source-map' : 'cheap-module-source-map',
output: {
path: path.resolve(__dirname, 'build'),
publicPath: '/build/',
filename: 'webcomponents.js',
library: {
name: 'webcomponents',
type: 'umd',
},
},
target: 'web',
resolve: {
extensions: ['.ts', '.tsx', '.js', '.styl'],
alias: {
'@src': path.resolve(__dirname, 'src'),
// add styles alias
'@styles': path.resolve(__dirname, 'src/styles'),
// import 'monaco-editor' incode will build all bundles
// add this and monaco languages will limit outputs
'monaco-editor': 'monaco-editor/esm/vs/editor/editor.api.js',
},
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
],
},
// split out global style, in order to include fixed className
{
test: /\.styl$/,
include: [
path.resolve(__dirname, 'src/components/html.styl'),
],
use: [
'style-loader',
'css-loader',
{ loader: 'stylus-loader' },
],
},
{
test: /\.styl$/,
exclude: [
path.resolve(__dirname, 'src/components/html.styl'),
],
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[local]-[hash:base64:16]',
},
},
},
{
loader: 'stylus-loader',
options: {
stylusOptions: {
import: [path.resolve(__dirname, 'src/styles/index.styl')],
},
},
},
],
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 100000,
},
},
},
],
},
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, 'src/styles/'),
to: path.resolve(__dirname, 'build/styles/'),
},
],
}),
],
externals: [
{
ramda: 'ramda',
lodash: {
commonjs: 'lodash',
commonjs2: 'lodash',
amd: 'lodash',
root: '_',
},
react: {
root: 'React',
commonjs2: 'react',
commonjs: 'react',
amd: 'react',
},
'react-dom': {
root: 'ReactDOM',
commonjs2: 'react-dom',
commonjs: 'react-dom',
amd: 'react-dom',
},
moment: 'moment',
},
nodeExternals({
allowlist: [
'd3',
'material-icons',
'monaco-editor',
],
}),
],
};
};
And I'm able to build project successfully with Webpack, but Storybook throws this error.
I have tried to debug storybook building process and it looks like Stylus return AST tree instead of compiled CSS to css-loader
I can't understand why it works correctly directly with webpack, but it breaks when we use it in storybook