storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.48k stars 9.29k forks source link

[Bug]: Storybook 7 + Gatsby 5 - Module parse failed: Unexpected token #22796

Open alex-major-digital opened 1 year ago

alex-major-digital commented 1 year ago

Describe the bug

I've recently migrated from Storybook V6 to V7. I followed the guide, and ran the auto migration command - no issues there.

When then attempting to run storybook dev -p 6006, I'm hit with the error:

Module parse failed: Unexpected token (13:4)

You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| 
|   return (
>     <React.Fragment>
|       {finalData && render(finalData)}
|       {!finalData && <div>Loading (StaticQuery)</div>}

Here's my main.ts code:

const path = require('path');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const webpack = require('webpack');

/** @type { import('@storybook/react-webpack5').StorybookConfig } */
const config = {
    stories: [
        '../src/**/AccordionPanel.mdx',
        '../src/**/AccordionPanel.stories.@(js|jsx|ts|tsx)',
    ],
    addons: [
        '@storybook/addon-links',
        '@storybook/addon-essentials',
        '@storybook/addon-viewport/register',
        '@storybook/addon-a11y',
        {
            name: '@storybook/addon-postcss',
            options: {
                postcssLoaderOptions: {
                    implementation: require('postcss'),
                },
            },
        },
        {
            name: 'storybook-css-modules',
            options: {
                cssModulesLoaderOptions: {
                    importLoaders: 1,
                    modules: {
                        localIdentName: '[path][name]__[local]--[hash:base64:5]',
                    },
                    localsConvention: 'camelCase',
                },
            },
        },
    ],
    framework: {
        name: '@storybook/react-webpack5',
        options: {},
    },
    typescript: {
        check: false,
        checkOptions: {},
        reactDocgen: 'react-docgen-typescript',
        reactDocgenTypescriptOptions: {
            shouldExtractLiteralValuesFromEnum: true,
            propFilter: (prop) =>
                prop.parent ? !/node_modules/.test(prop.parent.fileName) : true,
        },
    },
    docs: {
        autodocs: 'tag',
    },
    webpackFinal: async (config, { configType }) => {
        const fileLoaderRule = config.module.rules.find(
            (rule: any) => rule.test && rule.test.test('.svg')
        );

        fileLoaderRule.exclude = /\.svg$/;
        config.module.rules.push({
            test: /\.svg$/,
            use: ['@svgr/webpack', 'url-loader'],
        });

        config.resolve.modules = [
            ...(config.resolve.modules || []),
            path.resolve(__dirname, '../'),
        ];

        // remap @reach/router to fork included in Gatsby
        config.plugins.push(
            new webpack.NormalModuleReplacementPlugin(
                /^@reach\/router/,
                '@gatsbyjs/reach-router'
            )
        );

        config.resolve.mainFields = ['browser', 'module', 'main'];

        config.resolve.plugins = [
            ...(config.resolve.plugins || []),
            new TsconfigPathsPlugin({
                extensions: config.resolve.extensions,
            }),
        ];

        return config;
    },
};
export default config;

Any ideas?

Many thanks, Alex

To Reproduce

No response

System

System:
    OS: Windows 10 10.0.22621
    CPU: (16) x64 AMD Ryzen 7 PRO 4750U with Radeon Graphics
  Binaries:
    Node: 18.13.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.19.0 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 9.1.2 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.22621.1702.0), Chromium (113.0.1774.50)

Additional context

No response

ChrisSargent commented 1 year ago

Okay, just ran in to this problem myself and actually the solution is pretty simple. In the Gatsby docs here: https://www.gatsbyjs.com/docs/how-to/testing/visual-testing-with-storybook/#manual-configuration, we see:

config.module.rules[0].exclude = [/node_modules\/(?!(gatsby|gatsby-script)\/)/]

But actually, the rules for the babel config are no longer the first item in the array, they are the third. Simply changing that to the following worked for us:

config.module.rules[2].exclude = [/node_modules\/(?!(gatsby|gatsby-script)\/)/]

Frankly, that's very brittle and it would be better to do something like:

const index = config.modules.rules.find((rule) => rule.loader.contains('/babel-loader/'))
config.module.rules[index].exclude = [/node_modules\/(?!(gatsby|gatsby-script)\/)/]

Would need to be a bit more complicated than that because use is also an arrary...