Skip to content

Instantly share code, notes, and snippets.

@shilman
Last active June 26, 2023 12:56
Show Gist options
  • Save shilman/8856ea1786dcd247139b47b270912324 to your computer and use it in GitHub Desktop.
Save shilman/8856ea1786dcd247139b47b270912324 to your computer and use it in GitHub Desktop.
Storybook Webpack 5

⚠️ Warning: this document is out of date.

For the most recent webpack5 instructions see MIGRATION.md.

Storybook experimental Webpack 5 support

Storybook 6.2 includes experimental Webpack 5 support. Webpack 5 brings a variety of performance improvements, as well as exciting new features like module federation. Here's a quick guide to get you going.

Intro

Storybook uses webpack to bundle its UI ("manager") and also user code in an iframe ("preview"). In Storybook 6.2, the manager is bundled in Webpack 4, and the preview can either be bundled in Webpack 4 (default) or Webpack 5 (opt-in). In Storybook 6.3, the manager is also bundled in Webpack 5 when the preview is bundled with Webpack 5.

Installation

NOTE: Before you try out Storybook's webpack5 support, make sure your project works with Webpack 5. For example, create-react-app v4 (CRA v4) is not webpack5-compatible, so if you have a CRA project, you'll need to upgrade to CRA v5 which uses webpack5. Once you've verified webpack5 in your project, you can either do a clean install or an upgrade.

Upgrading from Webpack 4

If you're upgrading an existing Storybook installation:

npx sb@next upgrade --prerelease

Then add dependencies:

npm i -D @storybook/builder-webpack5@next @storybook/manager-webpack5@next webpack@5

Note that the webpack@5 dev dependency forces webpack5 to be hoisted, since SB also contains a webpack4 dependency

Then update your .storybook/main.js:

module.exports = {
  core: {
    builder: "webpack5",
  },
};

Upgrading from 6.2 Webpack 5

If you were using Webpack 5 in 6.2, and have upgraded to 6.3, you probably need to add @storybook/manager-webpack5 as a dependency:

npm i -D @storybook/manager-webpack5@next

Clean install

If your project doesn't have Storybook installed:

npx sb@next init --builder webpack5

This adds storybook and automatically performs the extra steps descripted in the "Upgrade from Webpack 4" section.

Troubleshooting

Currently all storybook addons assume webpack 4. If you run into issues, try disabling addons and see if that fixes it. If you find an addon that needs to be upgraded to support Webpack 5, please file an issue and let us know!

Webpack 5 support is still experimental. If you run into problems, please check to see if somebody's already filed an issue Storybook repo and upvote it if there's an existing issue. If there's no existing issue, please file one and title it Webpack5: (problem summary).

Yarn resolutions

Some webpack5 projects are using Yarn resolutions to force a specific version of webpack across the entire project. We don't recommend this because it causes problems for Storybook which still uses webpack4 to build its "manager" UI (not user code). However, if you must use resolutions including all of the following packages is a workaround seems to patch over the issue:

{
  "resolutions": {
    "webpack": "^5.0.0",
    "css-loader": "^5.0.0",
    "dotenv-webpack": "^6.0.0",
    "html-webpack-plugin": "^5.0.0",
    "style-loader": "^2.0.0",
    "terser-webpack-plugin": "^5.0.0",
    "webpack-dev-middleware": "^4.1.0",
    "webpack-virtual-modules": "^0.4.2"
  }
}

We're considering a proper solution in #14044.

@AlexandreKilian
Copy link

I'm getting the error
ERR! Error: For the selected environment is no default script chunk format available:
only with webpack 5 in storybook, webpack for my electron setup works just fine… Anyone else resolved this?

@mrcrumpy
Copy link

I'm stumbling into the same error:
ERR! Error: For the selected environment is no default script chunk format available: ERR! JSONP Array push can be chosen when 'document' or 'importScripts' is available. ERR! CommonJs exports can be chosen when 'require' or node builtins are available. ERR! Make sure that your 'browserslist' includes only platforms that support these features or select an appropriate 'target' to allow selecting a chunk format by default. Alternatively specify the 'output.chunkFormat' directly.

I tried setting the target and tried setting the chunkFormat in a custom webpack config

@elodszopos
Copy link

I finally got this to work.

Key takeaways:

 "devDependencies": {
    "@babel/core": "7.15.0",
    "@babel/preset-env": "7.15.0",
    "@storybook/addon-actions": "6.4.0-alpha.30",
    "@storybook/addon-controls": "6.4.0-alpha.30",
    "@storybook/addon-docs": "6.4.0-alpha.30",
    "@storybook/addon-postcss": "2.0.0",
    "@storybook/addon-viewport": "6.4.0-alpha.30",
    "@storybook/addons": "6.4.0-alpha.30",
    "@storybook/builder-webpack5": "6.4.0-alpha.30",
    "@storybook/manager-webpack5": "6.4.0-alpha.30",
    "@storybook/preset-scss": "1.0.3",
    "@storybook/react": "6.4.0-alpha.30",
    "@svgr/webpack": "5.5.0",
    ...
    "@types/webpack": "5.28.0",
    "@types/dotenv-webpack": "7.0.3",
    ...
    "dotenv-webpack": "7.0.3",
    ...
    "webpack": "5.51.1",

The above dependencies got me past the 99% blocker. Afterwards, any story that contained an imported svg failed to load .. because storybook was trying to load svg using file loader, with the base loader that it has for assets.

To get past that blocker and to have stories that contained icons working too, I had to make the base file loader on the storybook webpack config ignore svgs, and I provided loader rules for svgs instead.

Inside webpackFinal under main.js:

const fileLoaderRule = rules.find(rule => rule.test && rule.test.test('.svg'));

fileLoaderRule.exclude = /\.svg$/;

rules.push({
  test: /\.svg$/,
  issuer: /\.(js|ts)x?$/,
  use: ['@svgr/webpack', 'url-loader'],
});
    

Just push the rule - no loader order problem if svgs don't go through file loader at all. Load them as urls to resolve imports and then load them using svgr.

Et voila, storybook with webpack 5 FINALLY working.

@vikashruhilgit
Copy link

Hi,

it's been several days since i stuck with the issue,

i tried all the solution but no luck.

will be please help me out.

issue is :

start-storybook works but build-storybook fails

start-storybook works smooth with add-ons as well.

but build-storybook fails, if i add any of the addons in .storybook.main.ts

error is:

yarn build-storybook yarn run v1.22.11 $ build-storybook (node:43478) UnhandledPromiseRejectionWarning: Error: [@web/dev-server-storybook] Official storybook addons are not es modules, and cannot be loaded from this storybook implementation. at Object.createError (/Users/vikashruhil/Documents/work/UI/firstech-ui/node_modules/@web/dev-server-storybook/dist/shared/utils.js:10:12) at validateMainJs (/Users/vikashruhil/Documents/work/UI/firstech-ui/node_modules/@web/dev-server-storybook/dist/shared/config/readStorybookConfig.js:26:27) at Object.readStorybookConfig (/Users/vikashruhil/Documents/work/UI/firstech-ui/node_modules/@web/dev-server-storybook/dist/shared/config/readStorybookConfig.js:56:20)

and also if i remove addons then also its fails and throw an error:

yarn build-storybook yarn run v1.22.11 $ build-storybook (node:43347) UnhandledPromiseRejectionWarning: Error: The keyword 'interface' is reserved (Note that you need plugins to import files that are not JavaScript) at error (/Users/vikashruhil/Documents/work/UI/firstech-ui/node_modules/rollup/dist/shared/rollup.js:151:30) at Module.error (/Users/vikashruhil/Documents/work/UI/firstech-ui/node_modules/rollup/dist/shared/rollup.js:10059:16) at Module.tryParse (/Users/vikashruhil/Documents/work/UI/firstech-ui/node_modules/rollup/dist/shared/rollup.js:10462:25) at Module.setSource (/Users/vikashruhil/Documents/work/UI/firstech-ui/node_modules/rollup/dist/shared/rollup.js:10365:24) at ModuleLoader.addModuleSource (/Users/vikashruhil/Documents/work/UI/firstech-ui/node_modules/rollup/dist/shared/rollup.js:19708:20) at async ModuleLoader.fetchModule (/Users/vikashruhil/Documents/work/UI/firstech-ui/node_modules/rollup/dist/shared/rollup.js:19764:9) at async Promise.all (index 2) at async ModuleLoader.fetchStaticDependencies (/Users/vikashruhil/Documents/work/UI/firstech-ui/node_modules/rollup/dist/shared/rollup.js:19790:34) at async Promise.all (index 0) at async ModuleLoader.fetchModule (/Users/vikashruhil/Documents/work/UI/firstech-ui/node_modules/rollup/dist/shared/rollup.js:19766:9) (Use node --trace-warnings ...to show where the warning was created) (node:43347) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag--unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1) (node:43347) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

my configurations are:

its a web component package library by open-wc generator.

then i upgraded that to latest storybook for sass support. everything is working except build-storybook

project dependencies and dev-dependencies are:

"dependencies": { "lit-element": "^2.5.1", "lit-html": "^1.4.1", }, "devDependencies": { "@open-wc/eslint-config": "^4.3.0", "@open-wc/testing": "^2.5.33", "@storybook/addon-essentials": "^6.3.7", "@storybook/addons": "^6.3.7", "@storybook/builder-webpack5": "^6.2.9", "@storybook/manager-webpack5": "^6.2.9", "@storybook/web-components": "^6.3.7", "@types/webpack": "^5.0.0", "@typescript-eslint/eslint-plugin": "^4.28.0", "@typescript-eslint/parser": "^4.28.0", "@web/dev-server": "^0.1.17", "@web/dev-server-storybook": "^0.3.5", "@web/test-runner": "^0.12.20", "babel-loader": "^8.2.2", "clean-webpack-plugin": "^4.0.0-alpha.0", "concurrently": "^5.3.0", "css-loader": "^6.2.0", "eslint": "^7.29.0", "eslint-config-prettier": "^7.2.0", "extract-loader": "^5.1.0", "husky": "^4.3.8", "lint-staged": "^10.5.4", "lit": "^2.0.0-rc.2", "lit-scss-loader": "^1.1.0", "prettier": "^2.2.1", "sass": "^1.38.0", "sass-loader": "^12.1.0", "style-loader": "^3.2.1", "ts-loader": "^9.2.5", "tslib": "^2.3.0", "typescript": "^4.3.5", "webpack": "^5.51.1", "webpack-cli": "^4.8.0" },

and main.js is:

`const path = require('path');

module.exports = {
stories: [
'../stories/.stories.mdx',
'../stories/
.stories.@(js|jsx|ts|tsx)',
],
addons: [
path.resolve('./.storybook/my-preset'),
'@storybook/addon-essentials',
],
core: {
builder: 'webpack5',
},
};
`

and my-preset is:

`const path = require('path');

module.exports = {
managerWebpack: async (config, options) => {
// update config here
return config;
},
managerBabel: async (config, options) => {
// update config here
return config;
},
webpackFinal: async (config, { configType }) => {
// configType has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.

// Make whatever fine-grained changes you need

config.module.rules.push({
  test: /\.scss$/,
  use: ['lit-scss-loader', 'extract-loader', 'css-loader', 'sass-loader'],
  include: path.resolve(__dirname, '../'),
});
return config;

},
babel: async (config, options) => {
return config;
},
};
`

REPO is:
https://github.com/vikashruhilgit/UI/

@Jack-Works
Copy link

It seems like pmmmwh/react-refresh-webpack-plugin#308 has been closed, when can we re-enable react-refresh in webpack 5 storybooks?

@toughyear
Copy link

@shilman after following all the instructions I get the following error -

╰─      yarn storybook                                                                                           ─╯
yarn run v1.22.10
$ start-storybook -p 6006 -s public
/bin/sh: start-storybook: command not found
error Command failed with exit code 127.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

@gmirmand
Copy link

gmirmand commented Sep 16, 2022

@shilman after following all the instructions I get the following error -

╰─      yarn storybook                                                                                           ─╯
yarn run v1.22.10
$ start-storybook -p 6006 -s public
/bin/sh: start-storybook: command not found
error Command failed with exit code 127.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Same here.
I was using Webpack4 & Storybook6.5
I moved my project to webpack5 so i've done the migration steps for storybook

npx sb@next upgrade --prerelease
npm i -D @storybook/builder-webpack5@next @storybook/manager-webpack5@next webpack@5
and add

module.exports = {
  core: {
    builder: "webpack5",
  },
};

But when I npm run storybook (start-storybook -p 6006 --no-dll) i get sh: start-storybook: command not found

@gmirmand
Copy link

gmirmand commented Sep 16, 2022

Even based on a clean install it's doesn't work..

I run npx sb@next init --builder webpack5 in a empty folder
Choose vue (not vue3)

and on npm run storybook i get

> start-storybook -p 6006

info @storybook/vue v6.5.12
info 
info => Loading presets
ERR! Error: Cannot find module 'vue/dist/vue.esm.js'
ERR! Require stack:
ERR! - <project-path>/node_modules/@storybook/vue/dist/cjs/server/framework-preset-vue.js
ERR! - <project-path>/node_modules/@storybook/core-common/dist/cjs/presets.js
ERR! - <project-path>/node_modules/@storybook/core-common/dist/cjs/index.js
ERR! - <project-path>/node_modules/@storybook/core-server/dist/cjs/index.js
ERR! - <project-path>/node_modules/@storybook/core/dist/cjs/server.js
ERR! - <project-path>/node_modules/@storybook/core/server.js
ERR! - <project-path>/node_modules/@storybook/vue/dist/cjs/server/index.js
ERR! - <project-path>/node_modules/@storybook/vue/bin/index.js
ERR!     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15)
ERR!     at Function.resolve (internal/modules/cjs/helpers.js:99:19)
ERR!     at Object.webpack (<project-path>/node_modules/@storybook/vue/dist/cjs/server/framework-preset-vue.js:53:19)
ERR!     at async starterGeneratorFn (<project-path>/node_modules/@storybook/builder-webpack5/dist/cjs/index.js:116:16)
ERR!     at async Object.start (<project-path>/node_modules/@storybook/builder-webpack5/dist/cjs/index.js:272:14)
ERR!     at async Promise.all (index 0)
ERR!     at async storybookDevServer (<project-path>/node_modules/@storybook/core-server/dist/cjs/dev-server.js:207:28)
ERR!     at async buildDevStandalone (<project-path>/node_modules/@storybook/core-server/dist/cjs/build-dev.js:120:31)
ERR!     at async buildDev (<project-path>/node_modules/@storybook/core-server/dist/cjs/build-dev.js:174:5)
ERR!  Error: Cannot find module 'vue/dist/vue.esm.js'
ERR! Require stack:
ERR! - <project-path>/node_modules/@storybook/vue/dist/cjs/server/framework-preset-vue.js
ERR! - <project-path>/node_modules/@storybook/core-common/dist/cjs/presets.js
ERR! - <project-path>/node_modules/@storybook/core-common/dist/cjs/index.js
ERR! - <project-path>/node_modules/@storybook/core-server/dist/cjs/index.js
ERR! - <project-path>/node_modules/@storybook/core/dist/cjs/server.js
ERR! - <project-path>/node_modules/@storybook/core/server.js
ERR! - <project-path>/node_modules/@storybook/vue/dist/cjs/server/index.js
ERR! - <project-path>/node_modules/@storybook/vue/bin/index.js
ERR!     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15)
ERR!     at Function.resolve (internal/modules/cjs/helpers.js:99:19)
ERR!     at Object.webpack (<project-path>/node_modules/@storybook/vue/dist/cjs/server/framework-preset-vue.js:53:19)
ERR!     at async starterGeneratorFn (<project-path>/node_modules/@storybook/builder-webpack5/dist/cjs/index.js:116:16)
ERR!     at async Object.start (<project-path>/node_modules/@storybook/builder-webpack5/dist/cjs/index.js:272:14)
ERR!     at async Promise.all (index 0)
ERR!     at async storybookDevServer (<project-path>/node_modules/@storybook/core-server/dist/cjs/dev-server.js:207:28)
ERR!     at async buildDevStandalone (<project-path>/node_modules/@storybook/core-server/dist/cjs/build-dev.js:120:31)
ERR!     at async buildDev (<project-path>/node_modules/@storybook/core-server/dist/cjs/build-dev.js:174:5) {
ERR!   code: 'MODULE_NOT_FOUND',
ERR!   requireStack: [
ERR!     '<project-path>/node_modules/@storybook/vue/dist/cjs/server/framework-preset-vue.js',
ERR!     '<project-path>/node_modules/@storybook/core-common/dist/cjs/presets.js',
ERR!     '<project-path>/node_modules/@storybook/core-common/dist/cjs/index.js',
ERR!     '<project-path>/node_modules/@storybook/core-server/dist/cjs/index.js',
ERR!     '<project-path>/node_modules/@storybook/core/dist/cjs/server.js',
ERR!     '<project-path>/node_modules/@storybook/core/server.js',
ERR!     '<project-path>/node_modules/@storybook/vue/dist/cjs/server/index.js',
ERR!     '<project-path>/node_modules/@storybook/vue/bin/index.js'
ERR!   ]
ERR! }

@eladgoeuro
Copy link

eladgoeuro commented Jan 18, 2023

TypeScript code is not recognized after I did the upgrade (getting SyntaxError)

odule build failed (from ./.yarn/__virtual__/babel-loader-virtual-cf6f5f4d38/0/cache/babel-loader-npm-9.1.2-a76340cb80-f0edb8e157.zip/node_modules/babel-loader/lib/index.js):
ERR! SyntaxError: /Users/elcohen/prisma/ciem-jit-ui/src/components/ErrorPage/ErrorPage.stories.tsx: Unexpected token, expected "from" (2:12)
ERR!
ERR!   1 | // import { action } from "@storybook/addon-actions";
ERR! > 2 | import type { ReactElement } from "react";
ERR!     |             ^
ERR!   3 | import { ErrorPage } from "./ErrorPage";
ERR!   4 | export default {
ERR!   5 |   component: ErrorPage,
ERR!     at instantiate (/Users/elcohen/prisma/ciem-jit-ui/.yarn/cache/@babel-parser-npm-7.20.7-3710a9bc4f-25b5266e3b.zip/node_modules/@babel/parser/lib/index.js:66:32)
ERR!     at constructor (/Users/elcohen/prisma/ciem-jit-ui/.yarn/cache/@babel-parser-npm-7.20.7-3710a9bc4f-25b5266e3b.zip/node_modules/@babel/parser/lib/index.js:357:12)
ERR!     at JSXParserMixin.raise (/Users/elcohen/prisma/ciem-jit-ui/.yarn/cache/@babel-parser-npm-7.20.7-3710a9bc4f-25b5266e3b.zip/node_modules/@babel/parser/lib/index.js:3298:19)

@bigbunty
Copy link

hi

TypeScript code is not recognized after I did the upgrade (getting SyntaxError)

odule build failed (from ./.yarn/__virtual__/babel-loader-virtual-cf6f5f4d38/0/cache/babel-loader-npm-9.1.2-a76340cb80-f0edb8e157.zip/node_modules/babel-loader/lib/index.js):
ERR! SyntaxError: /Users/elcohen/prisma/ciem-jit-ui/src/components/ErrorPage/ErrorPage.stories.tsx: Unexpected token, expected "from" (2:12)
ERR!
ERR!   1 | // import { action } from "@storybook/addon-actions";
ERR! > 2 | import type { ReactElement } from "react";
ERR!     |             ^
ERR!   3 | import { ErrorPage } from "./ErrorPage";
ERR!   4 | export default {
ERR!   5 |   component: ErrorPage,
ERR!     at instantiate (/Users/elcohen/prisma/ciem-jit-ui/.yarn/cache/@babel-parser-npm-7.20.7-3710a9bc4f-25b5266e3b.zip/node_modules/@babel/parser/lib/index.js:66:32)
ERR!     at constructor (/Users/elcohen/prisma/ciem-jit-ui/.yarn/cache/@babel-parser-npm-7.20.7-3710a9bc4f-25b5266e3b.zip/node_modules/@babel/parser/lib/index.js:357:12)
ERR!     at JSXParserMixin.raise (/Users/elcohen/prisma/ciem-jit-ui/.yarn/cache/@babel-parser-npm-7.20.7-3710a9bc4f-25b5266e3b.zip/node_modules/@babel/parser/lib/index.js:3298:19)

I am also getting this error with Storybook 7 migration from v6. Any solution for this issue?

@azangru
Copy link

azangru commented Jun 26, 2023

Will a .babelrc in the .storybook folder with the following content help?

{
  "presets": [
    "@babel/react",
    "@babel/typescript"
  ]
}

(also, what's in your main.js inside .storybook)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment