storybook icon indicating copy to clipboard operation
storybook copied to clipboard

Support other configuration files than .babelrc for babelModeV7

Open cjones26 opened this issue 1 year ago • 3 comments

Is your feature request related to a problem? Please describe

I have been absolutely going crazy trying to rid myself of the {loose: true} setting in lib/core-common/src/utils/babel.ts for the following:

  • @babel/preset-env
  • @babel/plugin-proposal-class-properties
  • @babel/plugin-private-property-in-object
  • @babel/plugin-proposal-private-methods
  • @babel/plugin-proposal-object-rest-spread

We recently upgraded to Webpack version 5 (including the Storybook builder), as well as Babel packages to the latest versions, and since had to remove the {loose: true} option from our babel.config.js file, and instead replace it with the following assumptions:

assumptions: {
  privateFieldsAsProperties: true,
  setPublicClassFields: true,
},

This is causing issues with Storybook, as every time we run the dev server or build we observe the following warnings:

[proposal-class-properties]: You are using the "loose: true" option and you are explicitly setting a value for the "setPublicClassFields" and "privateFieldsAsProperties" assumptions. The "loose" option can cause incompatibilities with the other class features plugins, so it's recommended that you replace it with the following top-level option: "assumptions": { "setPublicClassFields": true, "privateFieldsAsProperties": true } [proposal-private-methods]: You are using the "loose: true" option and you are explicitly setting a value for the "setPublicClassFields" and "privateFieldsAsProperties" assumptions. The "loose" option can cause incompatibilities with the other class features plugins, so it's recommended that you replace it with the following top-level option: "assumptions": { "setPublicClassFields": true, "privateFieldsAsProperties": true }

After hours of digging through documentation and code--including one of the first things I tried, which was enabling babelModeV7 (https://storybook.js.org/docs/react/configure/babel#v7-mode)--I simply could not understand why my Babel configuration would not load, even though I had a babel.config.js in my project root.

In a moment of anguish, I decided to rename my babel.config.js to .babelrc and boom, everything worked properly. Though the documentation does explicitly state:

In V7 mode, you are responsible for configuring Babel using your .babelrc file, and Storybook does not provide any default.

It's absolutely unclear that it only supports .babelrc and no other variation of the configuration. I find this incredibly odd, being that the lib/core-common/src/utils/load-custom-babel-config.ts does in fact support many variations of possible Babel configurations:

// Between versions 5.1.0 - 5.1.9 this loaded babel.config.js from the project
// root, which was an unintentional breaking change. We can add back project support
// in 6.0.
const babelConfig =
  loadFromPath(path.resolve(configDir, '.babelrc')) ||
  loadFromPath(path.resolve(configDir, '.babelrc.json')) ||
  loadFromPath(path.resolve(configDir, '.babelrc.js')) ||
  loadFromPath(path.resolve(configDir, 'babel.config.json')) ||
  loadFromPath(path.resolve(configDir, 'babel.config.js'));

Describe the solution you'd like

Allow the babelModeV7 feature flag to search for any and all other variations of a Babel configuration file, like above.

Describe alternatives you've considered

After being unable to get the babelModeV7 switch to work properly, I even went as far as writing a function to iterate down through the final webpack config and attempt to find any key loose and set it to false. Though it was a neat function, it definitely did not work:

const stopBeingLoose = (item) => {
  if (Array.isArray(item)) {
    return item.map((arrayItem) => stopBeingLoose(arrayItem));
  } else if (typeof item === 'object') {
    if (item.loose) {
      return { ...item, loose: false };
    }

    return Object.keys(item).reduce(
      (prev, key) => ({ ...prev, [key]: stopBeingLoose(item[key]) }),
      {}
    );
  }

  return item;
};

Unfortunately the above pissed off Webpack for some reason (even though the final config definitely did have a blank test: {}, so ?), and it would fail like so:

info => Using default Webpack5 setupig:load:flatten Completed in 1ms
<i> [webpack-dev-middleware] wait until bundle finishedpleted in 1ms
3% setup watch run/Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/rules/RuleSetCompiler.js:317
			throw this.error(
			^

Error: Compiling RuleSet failed: Expected condition, but got empty thing (at ruleSet[1].rules[0].test: [object Object])
    at RuleSetCompiler.error (/Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/rules/RuleSetCompiler.js:373:10)
    at RuleSetCompiler.compileCondition (/Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/rules/RuleSetCompiler.js:317:15)
    at /Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/rules/BasicMatcherRulePlugin.js:29:40
    at Hook.eval [as call] (eval at create (/Users/charlesjones/Work/web-project-bak/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:7:1)
    at RuleSetCompiler.compileRule (/Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/rules/RuleSetCompiler.js:177:19)
    at /Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/rules/RuleSetCompiler.js:154:9
    at Array.map (<anonymous>)
    at RuleSetCompiler.compileRules (/Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/rules/RuleSetCompiler.js:153:16)
    at RuleSetCompiler.compileRule (/Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/rules/RuleSetCompiler.js:184:30)
    at /Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/rules/RuleSetCompiler.js:154:9
    at Array.map (<anonymous>)
    at RuleSetCompiler.compileRules (/Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/rules/RuleSetCompiler.js:153:16)
    at RuleSetCompiler.compile (/Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/rules/RuleSetCompiler.js:68:22)
    at new NormalModuleFactory (/Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/NormalModuleFactory.js:237:34)
    at Compiler.createNormalModuleFactory (/Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/Compiler.js:1128:31)
    at Compiler.newCompilationParams (/Users/charlesjones/Work/web-project-bak/node_modules/webpack/lib/Compiler.js:1149:30)
npm ERR! Lifecycle script `storybook` failed with error:
npm ERR! Error: command failed
npm ERR!   in workspace: @project/[email protected]
npm ERR!   at location: /Users/charlesjones/Work/web-project-bak/Modules/bank-web

Are you able to assist to bring the feature to reality?

Yes, I can, if I know where in the codebase .babelrc is being picked up from. It's really unclear from the few hours I spent looking into it.

Additional context

N/A

cjones26 avatar Jul 08 '22 19:07 cjones26

My project has its babel config inside of the package.json and this is causing me pain with Storybook as well. Isn't there a way for Storybook to use the exact same search path code that babel itself uses rather than making up its own?

heath-freenome avatar Mar 13 '23 22:03 heath-freenome

@heath-freenome Is this still the case in SB7? I believe we're trying to use the built-in babel resolution now

Migration guide: https://storybook.js.org/migration-guides/7.0

shilman avatar Mar 14 '23 16:03 shilman

@shilman We haven't migrated to SB7 yet. Its on our roadmap

heath-freenome avatar Mar 14 '23 19:03 heath-freenome

Ok, closing this as fixed in 7.0, but please feel free to reopen or open a separate issue if it's not working for you. Thanks!

shilman avatar Mar 22 '23 08:03 shilman