Storybook: Root babel.config.js not loaded

Created on 25 Apr 2019  ·  20Comments  ·  Source: storybookjs/storybook

Describe the bug
Storybook does not load any babel.config.js files (in either root or .storybook). It only loads .storybook/.babelrc files.

To Reproduce
Steps to reproduce the behavior:

  1. Create a new storybook app
  2. Add a root-level babel.config.js file
  3. Run app
  4. See that config is not loaded

Expected behavior
Storybook should be able to load both babel config formats.

Code snippets
I believe this is the code responsible: https://github.com/storybooks/storybook/blob/fba0541a2bbbd3b51943b21d3f8d2282e33286d6/lib/core/src/server/utils/load-custom-babel-config.js#L62

System:

  • OS: MacOS
  • Device: Macbook Pro 2018
  • Framework: React
  • Version: 5.x

Additional context
https://github.com/emotion-js/emotion/issues/1306

babel / webpack bug help wanted in progress

Most helpful comment

@shilman I just tried 5.1.0-rc.0 with a root babel.config.js. I get this:

❯ build-storybook
info @storybook/react v5.1.0-rc.0
info 
info clean outputDir..
info => Copying prebuild dll's..
info => Building manager..
info => Loading manager config..
info => Loading presets
ERR! => Error parsing babel config file: JSON5: invalid character 'c' at 1:1
(node:8092) UnhandledPromiseRejectionWarning: SyntaxError: JSON5: invalid character 'c' at 1:1

A c is indeed the first character of the config.

const presetEnvOptions = {
  useBuiltIns: "usage",
  // To see which polyfills are used in which files:
  // debug: true,
};

const common = {
  presets: [["next/babel", { "preset-env": presetEnvOptions }]],
  plugins: ["lodash"],
};

module.exports = {
  env: {
    development: common,
    production: common,
    // Jest:
    test: {
      presets: [["next/babel", { "preset-env": { modules: "commonjs" } }]],
    },
  },
};

The problem comes from this line:

https://github.com/storybooks/storybook/commit/a08f44e4813ce19f9ff2670d9c1ccb312e94cb22#diff-cbcd9978dcfe6d6dafed0b1a16ee99f1R23

It checks if the entire file starts with module.exports. But the file might start with a comment, whitespace or some other code.

Workaround:

module.exports; // workaround

const presetEnvOptions = {
  useBuiltIns: "usage",
  // To see which polyfills are used in which files:
  // debug: true,
};

const common = {
  presets: [["next/babel", { "preset-env": presetEnvOptions }]],
  plugins: ["lodash"],
};

module.exports = {
  env: {
    development: common,
    production: common,
    // Jest:
    test: {
      presets: [["next/babel", { "preset-env": { modules: "commonjs" } }]],
    },
  },
};

All 20 comments

Boo-yah!! I just released https://github.com/storybooks/storybook/releases/tag/v5.1.0-rc.0 containing PR #6634 that references this issue. Upgrade today to try it out!

Because it's a pre-release you can find it on the @next NPM tag.

Closing this issue. Please re-open if you think there's still more to do.

@shilman I just tried 5.1.0-rc.0 with a root babel.config.js. I get this:

❯ build-storybook
info @storybook/react v5.1.0-rc.0
info 
info clean outputDir..
info => Copying prebuild dll's..
info => Building manager..
info => Loading manager config..
info => Loading presets
ERR! => Error parsing babel config file: JSON5: invalid character 'c' at 1:1
(node:8092) UnhandledPromiseRejectionWarning: SyntaxError: JSON5: invalid character 'c' at 1:1

A c is indeed the first character of the config.

const presetEnvOptions = {
  useBuiltIns: "usage",
  // To see which polyfills are used in which files:
  // debug: true,
};

const common = {
  presets: [["next/babel", { "preset-env": presetEnvOptions }]],
  plugins: ["lodash"],
};

module.exports = {
  env: {
    development: common,
    production: common,
    // Jest:
    test: {
      presets: [["next/babel", { "preset-env": { modules: "commonjs" } }]],
    },
  },
};

The problem comes from this line:

https://github.com/storybooks/storybook/commit/a08f44e4813ce19f9ff2670d9c1ccb312e94cb22#diff-cbcd9978dcfe6d6dafed0b1a16ee99f1R23

It checks if the entire file starts with module.exports. But the file might start with a comment, whitespace or some other code.

Workaround:

module.exports; // workaround

const presetEnvOptions = {
  useBuiltIns: "usage",
  // To see which polyfills are used in which files:
  // debug: true,
};

const common = {
  presets: [["next/babel", { "preset-env": presetEnvOptions }]],
  plugins: ["lodash"],
};

module.exports = {
  env: {
    development: common,
    production: common,
    // Jest:
    test: {
      presets: [["next/babel", { "preset-env": { modules: "commonjs" } }]],
    },
  },
};

Thank you for this very detailed feedback @lydell !

Perhaps instead of trying to detect what type of file it is, we just try-catch to load it with the 2 methods?

Isn’t .babelrc _always_ JSON5, and babel.config.js _always_ JS? If so, could loadFromPath take another parameter?

  const babelConfig =
    loadFromPath(path.resolve(configDir, '.babelrc'), 'JSON5') ||
    loadFromPath(path.resolve(projectRoot, 'babel.config.js'), 'JS')

Isn’t .babelrc _always_ JSON5, and babel.config.js _always_ JS? If so, could loadFromPath take another parameter?

That's correct according to babel docs: https://babeljs.io/docs/en/config-files#config-format

However, don't forget about .babelrc.js files -- those are valid too.

Is the fix of this issue rollback after 5.1.10?

Getting the same problem on 5.2.5. Storybook either won't load my .babelrc in the project root, or it doesn't like the 'env' options in it (e.g. production or development settings). When I duplicate the .babelrc file to my .storybook folder and remove the env stuff it works. I don't want 2 babelrc files though!

This issue is closed, so folks may not see the above. Please make a new issue referencing this one as a regression. (And if it's a regression, it's helpful if you can point out the version to which users need to downgrade in order to have the correct behavior.)

Automention: Hey @igor-dv, you've been tagged! Can you give a hand here?

Getting the same problem on 5.2.5. Storybook either won't load my .babelrc in the project root, or it doesn't like the 'env' options in it (e.g. production or development settings). When I duplicate the .babelrc file to my .storybook folder and remove the env stuff it works. I don't want 2 babelrc files though!

I use extends. I think it is a good workaround now.

{
    "extends": "/path/to/your/project/babel.config.js"
}

But I still wish this bug will be fixed.

@vipcxj That doesn't work for me. Only workaround is to change the root babel.config.js to .babelrc but this defeats the point of root configs with babel.

I created an empty .babelrc in the storybook config directory and it respects my root babel.config.js

For me .babelrc.js was not working when I was trying to apply it for a yarn workspace subpackage.
It was not even working when I tried babe.config.js. All babel config files (babelrc or babel.config.js) were being compiled when I tried to do console.log from those files, but none of them were making any effect.

I had to finally put it inside .storybook/webpack.config.js as mentioned here

My current solution is by adding rootMode options inside babel-loader webpack configuration. And it is working properly without need to create sub-package .babelrc file. :bowing_man:

StoryBook version: 5.3.6
Reference: https://babeljs.io/docs/en/config-files#webpack

// packages/ui/.storybook/main.js
module.exports = {
  stories: ['../src/**/*.stories.tsx'],
  webpackFinal: async config => {
    const newConfig = {
      ...config,
      module: {
        ...config.module,
        rules: [
          ...config.module.rules,
          {
            test: /\.tsx?$/,
            use: [
              {
                loader: require.resolve('babel-loader'),
                options: {
                  rootMode: 'upward'
                }
              },
              require.resolve('react-docgen-typescript-loader')
            ],
            include: path.resolve(__dirname, '../src')
          }
        ]
      },
      resolve: {
        ...config.resolve,
        extensions: [...(config.resolve.extensions || []), '.ts', '.tsx']
      }
    };

    return newConfig;
  }
};

We can do a breaking change in 6.0.0 and improve this behaviour.

@jeffryang24 @ashoksudani @jono-allen @lydell

Would you be interested in taking this on?

Sorry, I’m not interested but thanks for asking!

Sorry, I actually want to help but currently I still busy with my company's task. My current idea is just using rootMode: 'upward', so let babel find the babel-config until the root directory. :bowing_man:

My current idea is just using rootMode: 'upward', so let babel find the babel-config until the root directory

Would this work if the root babel config is in a sibling directory? Example:

+ /
|-- config
|--|-- babel.config.js
|--|-- webpack.config.js
|-- package.json
|-- src

Looks like with 5.2.6 this works:

/babel.config.js

console.log(`BABEL: ${module.id}`)

...

module.exports = {}

/tools/storybook/.babelrc.js

console.log(`BABEL: ${module.id}`)

const config = {
  'plugins': [
    'require-context-hook',
  ]
}

module.exports = config

output:

root@7af7153e7a85:/opt/app# tusk dev:storybook
dev:storybook $ npx start-storybook -p 9001 -c tools/storybook --ci
info @storybook/react v5.2.6
info 
info => Loading presets
info => Loading presets
info => Loading custom addons config.
info => Using default Webpack setup.
info => Using base config because react-scripts is not installed.
10% building 7/9 modules 2 active /opt/app/node_modules/@storybook/core/node_modules/webpack/buildin/module.jsBABEL: /opt/app/babel.config.js
BABEL: /opt/app/tools/storybook/.babelrc.js
webpack built c18ec05159cd4c98df88 in 7460ms

A different issue is that I'm still having problems getting require-context-hook to work though 🤕

I created an empty .babelrc in the storybook config directory and it respects my root babel.config.js

Hi there, I can also recreate this issue in Storybook v6. Albeit, I solely use babel.config.js files.
Likewise, my solution is to create an empty /.storybook/babel.config.js file. Afterwards, running start-storybook will respect /babel.config.js

Would love if we can get this issue patched. It would be great to not have to create an empty /.storybook/babel.config.js to get the /babel.config.js respected as desired

edit: As per this migration note from sb5, this seems intentional. Could we get this project level config back 😸

my specs:
os x
yarn 2.2.2 (berry)
[email protected]
"@storybook/addon-actions": "^6.0.12",
"@storybook/addon-knobs": "^6.0.12",
"@storybook/addons": "^6.0.12",
"@storybook/react": "^6.0.12",

Was this page helpful?
0 / 5 - 0 ratings

Related issues

arunoda picture arunoda  ·  3Comments

shilman picture shilman  ·  3Comments

zvictor picture zvictor  ·  3Comments

ZigGreen picture ZigGreen  ·  3Comments

tirli picture tirli  ·  3Comments