react-styleguidist
react-styleguidist copied to clipboard
Examples not displayed when using react-scripts@5
Current behavior
Examples in .md
files is not displayed when using react-styleguidist
with react-scripts@5
.
To reproduce
https://github.com/malcolm-kee/react-styleguidist-cra5-md-bug
Expected behavior
The examples should be displayed.
hello i have the same issue, someone can help on this please ?
package.json :
{
"name": "cms",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.0.3",
"@types/node": "^16.11.17",
"@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"typescript": "^4.5.4",
"web-vitals": "^2.1.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"styleguide": "styleguidist server",
"styleguide:build": "styleguidist build"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"react-docgen-typescript": "^2.2.2",
"react-styleguidist": "^11.1.7",
"webpack": "^5.65.0"
}
}
styleguide.config.js :
module.exports = {
components: 'src/components/**/*.{jsx,tsx}',
propsParser: require('react-docgen-typescript').withCustomConfig(
'./tsconfig.json'
).parse
};
Running into the same issue with CRA 5 (which comes with webpack 5). All components are blank:
Problem
I debugged this a bit and the problem here seems to be, the way that Webpack 5 is handling assets. It has a new Asset Module mechanism, which determines how webpack will bundle/treat an import. For Markdown files this seems to be asset/resource
by default, i.e. it will "copy" the file to a hashed location and make the require
return the URL to it.
This is problematic, since react-styleguidist actually specifies a custom inline loader (see getExamples.ts#31
and examples-loader.ts
). This loader will return JavaScript, which is now handled by Webpack wrongly as an asset. The solution would be to inform webpack to treat that result as JavaScript via the asset type javascript/auto
(see Workaround below).
Also it seems there is a second problem, that in the JavaScript code, that the examples-loader generate absolute paths are used (see examples-loader.ts#19-20
). Those seem to no longer resolve properly and will cause those two modules (requireInRuntime
and evalInContext
) to not resolve properly. It seems relative paths would work fine (see workaround below).
Workaround
Tested with [email protected]
To workaround this, you can put the following into your styleguide.config.js
:
const webpack = require('webpack');
const webpackConfig = {
module: {
rules: [
{
test: /\.examples\.md$/, // see comment below!
type: 'javascript/auto', // Tell webpack to interpret the result from examples-loader as JavaScript
},
],
},
plugins: [
// Rewrites the absolute paths to those two files into relative paths
new webpack.NormalModuleReplacementPlugin(
/react-styleguidist\/lib\/loaders\/utils\/client\/requireInRuntime$/,
'react-styleguidist/lib/loaders/utils/client/requireInRuntime'
),
new webpack.NormalModuleReplacementPlugin(
/react-styleguidist\/lib\/loaders\/utils\/client\/evalInContext$/,
'react-styleguidist/lib/loaders/utils/client/evalInContext'
),
],
};
module.exports = {
webpackConfig,
// The rest of your styleguidist config
};
Couple of notes to this workaround:
- If you already specify a
webpackConfig
in yourstyleguide.config.js
(e.g. because you are using craco and want to inject its webpack config) make sure to properly merge therules
andplugins
into that config. - All my styleguide examples end on
.examples.md
(using thegetExampleFilename
configuration). You must make sure to write atest
that will match your example markdown files (and also not accidentally other markdown files if you have them in your code). If you can't achieve this with thetest
option, in the worst case you'd need to use theinclude
andexclude
option to include and exclude individual files.
Hello Any plans to fix this issue? Still happens on v11.2.0 for me
Same for me
Maybe anyone find a solution? because I'm having same problem :/
@timroes thanks for the workaround, helped me a lot to sort it out easily.
Thanks @timroes for this ❤️
It took me some time to make this work with Typescript and Tailwind CSS but it was totally worth it!
In case someone is interested here is a gist for that.
I'm struggling with this issue myself - we don't use typescript, so in that case can anyone show me how to use the gist for .js as opposed to .ts?
For those struggling to hook up existing webpack config with the workaround, adding the below to the styleguide.config.js worked for me. It';s not an ideal solution but works for me while waiting for this to get resolved on the styleguidist end.
dangerouslyUpdateWebpackConfig(config) {
config.module.rules.push({
test: /.\.md$/,
type: "javascript/auto"
});
config.plugins.push(
new webpack.NormalModuleReplacementPlugin(
/react-styleguidist\/lib\/loaders\/utils\/client\/requireInRuntime$/,
"react-styleguidist/lib/loaders/utils/client/requireInRuntime"
)
);
config.plugins.push(
new webpack.NormalModuleReplacementPlugin(
/react-styleguidist\/lib\/loaders\/utils\/client\/evalInContext$/,
"react-styleguidist/lib/loaders/utils/client/evalInContext"
)
);
return config;
},
...the rest of your config
For those struggling to hook up existing webpack config with the workaround, adding the below to the styleguide.config.js worked for me. It';s not an ideal solution but works for me while waiting for this to get resolved on the styleguidist end.
dangerouslyUpdateWebpackConfig(config) { config.module.rules.push({ test: /.\.md$/, type: "javascript/auto" }); config.plugins.push( new webpack.NormalModuleReplacementPlugin( /react-styleguidist\/lib\/loaders\/utils\/client\/requireInRuntime$/, "react-styleguidist/lib/loaders/utils/client/requireInRuntime" ) ); config.plugins.push( new webpack.NormalModuleReplacementPlugin( /react-styleguidist\/lib\/loaders\/utils\/client\/evalInContext$/, "react-styleguidist/lib/loaders/utils/client/evalInContext" ) ); return config; }, ...the rest of your config
Working solution, thanks!
For those struggling to hook up existing webpack config with the workaround, adding the below to the styleguide.config.js worked for me. It';s not an ideal solution but works for me while waiting for this to get resolved on the styleguidist end.
dangerouslyUpdateWebpackConfig(config) { config.module.rules.push({ test: /.\.md$/, type: "javascript/auto" }); config.plugins.push( new webpack.NormalModuleReplacementPlugin( /react-styleguidist\/lib\/loaders\/utils\/client\/requireInRuntime$/, "react-styleguidist/lib/loaders/utils/client/requireInRuntime" ) ); config.plugins.push( new webpack.NormalModuleReplacementPlugin( /react-styleguidist\/lib\/loaders\/utils\/client\/evalInContext$/, "react-styleguidist/lib/loaders/utils/client/evalInContext" ) ); return config; }, ...the rest of your config
Thank you for this; very helpful!
But, two remarks:
-
Your comment
...the rest of your config
is not 100% obvious. For anyone who is puzzled here: (1) I needed to addconst webpack = require("webpack")
at the head of the file. (2) This new code goes inside themodule.exports = { ... }
, followed by rest of the existing content. -
This fixes the problem of examples not displaying after updating from react-scripts 4.0.3 to 5.0.1. But, even though the content is being served correctly, I still got a
FAIL Failed to compile
error, followed by many lines of "require stack" and other details. Fixing each just required carefully searching the messages for which dependencies were causing each problem, updating them, and also deleting and rebuilding node_modules.
For those struggling to hook up existing webpack config with the workaround, adding the below to the styleguide.config.js worked for me. It';s not an ideal solution but works for me while waiting for this to get resolved on the styleguidist end.
dangerouslyUpdateWebpackConfig(config) { config.module.rules.push({ test: /.\.md$/, type: "javascript/auto" }); config.plugins.push( new webpack.NormalModuleReplacementPlugin( /react-styleguidist\/lib\/loaders\/utils\/client\/requireInRuntime$/, "react-styleguidist/lib/loaders/utils/client/requireInRuntime" ) ); config.plugins.push( new webpack.NormalModuleReplacementPlugin( /react-styleguidist\/lib\/loaders\/utils\/client\/evalInContext$/, "react-styleguidist/lib/loaders/utils/client/evalInContext" ) ); return config; }, ...the rest of your config
Thank you for this; very helpful!
But, two remarks:
- Your comment
...the rest of your config
is not 100% obvious. For anyone who is puzzled here: (1) I needed to addconst webpack = require("webpack")
at the head of the file. (2) This new code goes inside themodule.exports = { ... }
, followed by rest of the existing content.- This fixes the problem of examples not displaying after updating from react-scripts 4.0.3 to 5.0.1. But, even though the content is being served correctly, I still got a
FAIL Failed to compile
error, followed by many lines of "require stack" and other details. Fixing each just required carefully searching the messages for which dependencies were causing each problem, updating them, and also deleting and rebuilding node_modules.
Hey there. By 'the rest of your config' I am referring to any other configuration you use from here. Things like sections, styles etc.
You're right, you do need to import webpack
, since you are referring to it in the config overrides. You can see more examples of config for react-styleguidist in the gist that @nebomilic posted above :)
Workaround for JavaScript + TailwindCSS + Styleguidist + Create React App 5
I was also stuck on the issue of getting TailwindCSS to work with Styleguidist and CRA for my component library but using JavaScript. I tried using the dangerouslyUpdateWebpackConfig option that @alexdunham provided and while this worked properly for getting Styleguidist working itself, once I published the package as an ES6 module it caused loader issues when I imported the package into other apps (specifically RedwoodJS apps, which is a framework using React). This solution is building on what @timroes and @nebomilic created for their apps and hopefully I can give more info for those who want to use their component library in other applications.
I can't publish the full repo I was working on but here's a gist of my styleguide config that allows a Styleguidist component library to work properly on its own, while also being able to publish it as a package and use it in other apps. It's important to make the following other changes to get Styleguidist working:
- In your package.json make sure you add
"type": "module"
to make sure we get the benefits of ES6 syntax while also allowing us to use TailwindCSS, which does not support ES6 syntax - Change your CommonJS files to end in .cjs. This means your repo should have
styleguide.config.cjs
,tailwind.config.cjs
(can use default config), andpostcss.config.cjs
at the root of your repo. My postcss.config.cjs had the following code:
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
- Make sure your components are using .jsx extension. I don't know why using a .js extension never worked for me but it would always cause issues when trying to get Styleguidist to run. Maybe this is because of the mixing of CommonJS and ES6 syntax within my monorepo. You can try using .js but Styleguidist would always throw an error at all of components when trying to do this.
- Make sure you have the necessary dev dependencies installed in your repo that are listed in the styleguide config (like @babel/preset-env, @babel/preset-react, url-loader, etc)
- After publishing your component library as a package, you may need to edit the webpack of the app using your component library to use babel-loader. In my case, for a RedwoodJS app I had to add the following to the
webpack.config.js
to properly load the components:
config.module.rules.push({
test: /\.(js|jsx)$/,
loader: 'babel-loader',
options: { presets: ['@babel/preset-env',['@babel/preset-react', {"runtime": "automatic"}]]},
resolve: {
fullySpecified: false,
},
})
Please note that you may have to modify my styleguide config in order to get them to work for your component library. For example, I use .jsx components so if you're not using .jsx this solution may not work and you should try modifying components: 'src/components/**/[A-Z]*.jsx'
and same deal with
resolve: {
extensions: ['.js','.jsx'],
}
and
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: { presets: ['@babel/preset-env',['@babel/preset-react', {"runtime": "automatic"}]]},
}
Make sure your Tailwind config knows to look for .jsx files instead of just .js files too!
For those struggling to hook up existing webpack config with the workaround, adding the below to the styleguide.config.js worked for me. It';s not an ideal solution but works for me while waiting for this to get resolved on the styleguidist end.
dangerouslyUpdateWebpackConfig(config) { config.module.rules.push({ test: /.\.md$/, type: "javascript/auto" }); config.plugins.push( new webpack.NormalModuleReplacementPlugin( /react-styleguidist\/lib\/loaders\/utils\/client\/requireInRuntime$/, "react-styleguidist/lib/loaders/utils/client/requireInRuntime" ) ); config.plugins.push( new webpack.NormalModuleReplacementPlugin( /react-styleguidist\/lib\/loaders\/utils\/client\/evalInContext$/, "react-styleguidist/lib/loaders/utils/client/evalInContext" ) ); return config; }, ...the rest of your config
my man 👏 👏 👏 .... about 3 days in with me and a colleague and this.. this was the solution! how can i buy you a coffee or something at least??