Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure Storybook to run from a directory other than the project root

I'm trying to configure Storybook to run from a directory that is not the root of the project and I'm having a little trouble. I've setup a mono-rep using https://github.com/jibin2706/cra-monorepo-demo as base.

My project directory looks like this:

- project
-- packages
---- app
---- components
---- utils
---- stories
------ .storybook
-------- main.js
------ ComponentA
-------- ComponentA.stories.mdx

Because I'm using a monorep with aliases (e.g. a component can import from @project/utils) I've configured webpack in .storybook/main.js to read like:

const path = require('path');

module.exports = {
  stories: ['../**/*.stories.mdx', '../../**/*.stories.@(js|jsx|ts|tsx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/preset-create-react-app',
  ],
  webpackFinal: async (config, { configType }) => {
    const result = {
      ...config,
      resolve: {
        ...config.resolve,
        alias: {
          ...config.resolve.alias,
          '@project/components': path.resolve(
            process.cwd(),
            'packages/components'
          ),
        },
      },
    };
  },
};

Then within my ComponentA.stories.mdx I have an import like import { ComponentA } from '@project/components';

When I run this however, I'm always hitting an error when it encounters JSX within a .js file:

ERROR in ./packages/components/MyComponent1/MyComponent1.js 106:11 Module parse failed: Unexpected token (106:11) File was processed with these loaders:

  • ./node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js You may need an additional loader to handle the result of these loaders. |

return <React.Fragment>{children}</React.Fragment>;

I can't seem to work out why this error is throwing. I've tried running with yarn storybook --debug-webpack which seems to include a loader for both jsx and js files. I'm not 100% sure if this is correct, but it looks roughly right from other docs I've read.

module: {
    rules: [
      {
        test: /\.(mjs|tsx?|jsx?)$/,
        use: [
          {
            loader: '/home/ian/src/cra-monorepo-demo/node_modules/babel-loader/lib/index.js',
            options: {
              sourceType: 'unambiguous',
              presets: [
                [
                  '/home/ian/src/cra-monorepo-demo/node_modules/@babel/preset-env/lib/index.js',
                  { shippedProposals: true, loose: true }
                ],
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/preset-typescript/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/preset-react/lib/index.js'
              ],
              plugins: [
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-shorthand-properties/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-block-scoping/lib/index.js',
                [
                  '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-decorators/lib/index.js',
                  { legacy: true }
                ],
                [
                  '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-class-properties/lib/index.js',
                  { loose: true }
                ],
                [
                  '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-private-methods/lib/index.js',
                  { loose: true }
                ],
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-export-default-from/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-syntax-dynamic-import/lib/index.js',
                [
                  '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-object-rest-spread/lib/index.js',
                  { loose: true, useBuiltIns: true }
                ],
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-classes/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-arrow-functions/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-parameters/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-destructuring/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-spread/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-for-of/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@storybook/core-common/node_modules/babel-plugin-macros/dist/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-optional-chaining/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/lib/index.js',
                [
                  '/home/ian/src/cra-monorepo-demo/node_modules/babel-plugin-polyfill-corejs3/lib/index.js',
                  {
                    method: 'usage-global',
                    absoluteImports: '/home/ian/src/cra-monorepo-demo/node_modules/core-js/index.js',
                    version: '3.16.1'
                  }
                ],
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-template-literals/lib/index.js'
              ]
            }
          }
        ],
        include: [ '/home/ian/src/cra-monorepo-demo' ],
        exclude: [ /node_modules/, /dist/ ]
      },
      {
        test: /\.js$/,
        use: [
          {
            loader: '/home/ian/src/cra-monorepo-demo/node_modules/babel-loader/lib/index.js',
            options: {
              sourceType: 'unambiguous',
              presets: [
                [
                  '/home/ian/src/cra-monorepo-demo/node_modules/@babel/preset-env/lib/index.js',
                  {
                    shippedProposals: true,
                    modules: false,
                    loose: true,
                    targets: 'defaults'
                  }
                ],
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/preset-react/lib/index.js'
              ],
              plugins: [
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-shorthand-properties/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-block-scoping/lib/index.js',
                [
                  '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-decorators/lib/index.js',
                  { legacy: true }
                ],
                [
                  '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-class-properties/lib/index.js',
                  { loose: true }
                ],
                [
                  '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-private-methods/lib/index.js',
                  { loose: true }
                ],
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-export-default-from/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-syntax-dynamic-import/lib/index.js',
                [
                  '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-object-rest-spread/lib/index.js',
                  { loose: true, useBuiltIns: true }
                ],
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-classes/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-arrow-functions/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-parameters/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-destructuring/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-spread/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-transform-for-of/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@storybook/core-common/node_modules/babel-plugin-macros/dist/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-optional-chaining/lib/index.js',
                '/home/ian/src/cra-monorepo-demo/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/lib/index.js',
                [
                  '/home/ian/src/cra-monorepo-demo/node_modules/babel-plugin-polyfill-corejs3/lib/index.js',
                  {
                    method: 'usage-global',
                    absoluteImports: '/home/ian/src/cra-monorepo-demo/node_modules/core-js/index.js',
                    version: '3.16.1'
                  }
                ]
              ]
            }
          }
        ],
        include: [Function: include]
      },
...

Can anyone see what I might be missing here, or what additional config is required?

like image 541
Ian Avatar asked Aug 13 '21 15:08

Ian


People also ask

How do I deploy storybook to server?

To deploy Storybook, we first need to export it as a static web app. This functionality is already built-in to Storybook and pre-configured. Running yarn build-storybook will output a static Storybook in the storybook-static directory, which can then be deployed to any static site hosting service.

How do I configure my Storybook project?

Storybook is configured via a folder, called.storybook which contains various configuration files. Note you can change the folder that Storybook uses by setting the -c flag to your start-storybook and build-storybook scripts. Configure your Storybook project The main configuration file is main.js.

What is the main configuration file of the storybook server?

The main configuration file is main.js. This file controls the behavior of the Storybook server, and so you must restart Storybook’s process when you change it. It contains the following:

How do I change the folder that storybook uses?

Note you can change the folder that Storybook uses by setting the -c flag to your start-storybook and build-storybook scripts. The main configuration file is main.js. This file controls the behavior of the Storybook server, and so you must restart Storybook’s process when you change it.

How do I change the default story in storybook?

Tip: Customize your default story by referencing it first in the `stories` array. By default, Storybook will load stories from your project based on a glob (pattern matching string) in .storybook/main.js that matches all files in your project with extension .stories.js. The intention is you colocate a story file with the component it documents.


Video Answer


1 Answers

The issue is probably with the Storybook project root. The default babel-loader defines an include that is equal to the project root. And the "project root" is usually the closest .git folder.

A workaround is to set the correct project root:

const path = require("path");

module.exports = {
  // ...

  webpackFinal: async (config, { configType }) => {
    const babelLoaderRule = config.module.rules.find(
      (rule) => rule.test.toString() === /\.(mjs|tsx?|jsx?)$/.toString()
    );
    // set correct project root
    babelLoaderRule.include = [path.resolve(__dirname, "../..")];

    return config;
  }
};

What "correct" path is, depends on your setup.

Check my post for a longer write-up.

like image 118
Darek Kay Avatar answered Sep 17 '22 16:09

Darek Kay