storybook-eol/addon-smart-knobs

Adding webpack.config.js breaks smart knobs

bradfrost opened this issue · 10 comments

Hi there,
I'm a big fan of smart knobs and dynamically building knobs based on PropTypes.

My issue is that adding a custom webpack.config.js to the .storybook directory results in the smart knobs not appearing.

Without custom webpack config file:

screen shot 2018-11-20 at 5 30 00 pm

And with custom webpack config file:

screenshot 2018-11-20 17 31 29

Here is the content of the webpack.config.js file, which I'm using to get SVG imports to play nicely with Storybook:

const path = require("path");
const fs = require("fs");
const appDirectory = fs.realpathSync(process.cwd());

module.exports = (baseConfig, env, defaultConfig) => {
  // Extend defaultConfig as you need.
  defaultConfig.module.rules.push({
	test: /\.(js|jsx)$/,
	include: path.resolve(appDirectory, "src"),
	loader: require.resolve("babel-loader"),
	options: {
		presets: [require.resolve("babel-preset-react-app")],
		plugins: [
			[
				require.resolve("babel-plugin-named-asset-import"),
				{
					loaderMap: {
						svg: {
							ReactComponent:
							"@svgr/webpack?-prettier,-svgo![path]"
							}
						}
					}
				]
			]
		}
	});

	return defaultConfig;
};

Any idea why the introduction of this config file would cause smart knobs to fail? Thanks very much!

Can you try using defaultConfig.module.rules.unshift instead of push?

With this webpack config, I believe you'll now be running the babel loader over your source files once and then a second time over the previously transpiled version.

This may work for some cases, but it's fundamentally not what you want and definitely incompatible with react-docgen which smart knobs uses under the hood.

If your only use case for modifying the default storybook webpack config is to add functionality to its babel loader, then I'd recommend manipulating the existing rule defaultConfig.module.rules.find((rule) => /babel-loader/.test(rule.loader)) instead of adding another babel rule to the config.

Thanks a bunch @transitive-bullshit!

If your only use case for modifying the default storybook webpack config is to add functionality to its babel loader, then I'd recommend manipulating the existing rule defaultConfig.module.rules.find((rule) => /babel-loader/.test(rule.loader)) instead of adding another babel rule to the config.

I'm pretty green with Webpack so I'm not quite sure what that means. Do you mean wiping out what I have with defaultConfig.module.rules.find((rule) => /babel-loader/.test(rule.loader)), or something else? Sorry for not understanding.

You can try putting a custom .babelrc with all these things into the .storybook dir instead of overriding the js rules.

Hey Brad, thanks for joining in and reporting this bug.

We're improving the CRA compatibility right now. I'm sorry if this caused a lot of inconvenience for you.

To assist with you current issue:

I think you need to change your webpack config to:

const path = require("path");
const fs = require("fs");
const appDirectory = fs.realpathSync(process.cwd());

module.exports = (baseConfig, env, defaultConfig) => {
  // Extend defaultConfig as you need.
  const babelRule = defaultConfig.module.rules.find(r => r.loader && r.loader.match(/babel-loader/));
  
  if (babelRule) {
    babelRule.options = {
      ...babelRule.options,
      presets: [...babelRule.options.presets, require.resolve("babel-preset-react-app")]
      plugins: [
        [
          ...babelRule.options.plugins,
          require.resolve("babel-plugin-named-asset-import"),
          {
            loaderMap: {
              svg: {
                ReactComponent:
                "@svgr/webpack?-prettier,-svgo![path]"
              }
            }
          }
        ]
      ]
    }
  }

	return defaultConfig;
};

We'll work on fixing the CRA incompatibility asap you you don't need this config at all.

What's happening is:

Storybook has configured a loader for js-files by default.
Your config is adding an additional one.

These 2 together make it so smart knobs isn't being provided with the correct data anymore.

What I did in my code example, was to find the config storybook has added, and modify that so it has the svg config you need.

This way there's only 1 loader for js files, and it should work.

Hope this helps to explain what's going on.

@bradfrost To add to what @ndelangen said: it looks like you are trying the workaround for storybookjs/storybook#4298. We're trying to get a fix ready for that pronto, so hopefully you won't need the workaround and won't need to mess with webpack config. Sorry for the hassle!

@bradfrost FYI we've released a fix to the inline SVG issue in https://github.com/storybooks/storybook/releases/tag/v4.1.0-alpha.8

Thanks so much @shilman!

Thanks again for the help everyone. I'm still unable to get the smart knobs to work properly, but will open another issue as the custom webpack config isn't relevant anymore.