storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.27k stars 9.27k forks source link

Composition API only works if host storybook starts after external storybooks are built #17696

Open passbyval opened 2 years ago

passbyval commented 2 years ago

Summary

I was at first first experiencing what seemed like a cors issue when trying to load stories.json:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at ‘http://localhost:6006/stories.json’. (Reason: Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’).

Upon further inspection, I noticed that my ref was being set to unknown in manager-webpack5/src/manager-config.ts.

I was starting my host storybook and referenced storybook locally in parallel, so when checkRef was called, it was not available because the referenced/external storybook was still building. My setup works if I start my referenced storybook first, wait until it builds, then start my host storybook.

Setting credentials to omit in modules/refs.ts also fixes my issue. i.e. storybook startup order does not matter and I do not have to restart my host storybook even if it initially couldn't access http://localhost:6006/iframe.html. I think it makes more sense if the reference type is determined on page load rather than being stuck in memory.

To Reproduce

The referenced storybooks cannot load now unless you restart the host storybook entirely.

Further Information

Storybook version: 6.5.0-alpha.47

Host storybook main.js:

const path = require("path");

module.exports = {
  core: {
    builder: "webpack5"
  },
  stories: ["../stories/**/*.stories.@(js|mdx)"],
  addons: ["@storybook/addon-docs", "@storybook/preset-scss"],
  framework: "@storybook/react",
  staticDirs: ["./assets"],
  refs: (_, { configType }) => {
    const isDev = configType === "DEVELOPMENT";

    return {
      next: {
        title: isDev ? "Next (Dev)" : "Next",
        url: isDev ? "http://localhost:6006" : "http://my-production-url.com"
      }
    };
  }
};

Npm scripts:

"start:sb:host": "start-storybook --port 7006"
passbyval commented 2 years ago

https://github.com/storybookjs/storybook/issues/13650 seems related.

JSMike commented 2 years ago

FYI, another way to get past this cors issue while doing local dev is to set the host for all locally hosted storybooks to '0.0.0.0' instead of 'localhost'

sarahquigley commented 1 year ago

We're also experiencing this issue on a project.

divisnotabutton commented 1 year ago

FYI, another way to get past this cors issue while doing local dev is to set the host for all locally hosted storybooks to '0.0.0.0' instead of 'localhost'

Doesn't help as we still get an error related to "type": "server-checked" from https://github.com/storybookjs/storybook/issues/13650

mcrider commented 1 year ago

This is an issue for us in a monorepo project (Turborepo) where all of the storybooks get run at once (using Storybook 7.0.2). Setting the child storybooks to run first as a dependency of the host storybook isn't an option there since they are persistent processes that don't return a status code, so hoping there is a solution with CORS.

benhodgson87 commented 1 year ago

Also experiencing this issue with Turborepo. Starting the child followed by the parent as standalone processes works fine, however attempting to run both synchronously via turbo fails with CORS errors. None of the linked workarounds seems to resolve this currently.

mcrider commented 1 year ago

I ended up using wait-on to load the host storybook last, e.g.

pnpm wait-on http://localhost:6007 http://localhost:6008 http://localhost:6009 && storybook dev --ci -p 6006

-- Seems to be working pretty well.

scottnath commented 1 year ago

I wrote this article to break down how to use concurrently and wait-on to run a multi-framework composed storybook locally https://dev.to/scottnath/running-a-local-multi-framework-composition-storybook-506l

Same as @mcrider mentions above, but article details out how/why. You start the child-storybooks individually and the wait-on script blocks the main composed storybook until all children can be queried via wait-on.

each child has it's own config dir

npm run storybook -- --config-dir .framework-storybooks/.storybook-preact --port 6001

// package.json
...
    "sbook-children": "npx concurrently \"npm run storybook -- --config-dir .framework-storybooks/.storybook-preact --port 6001 --no-open\"  \"npm run storybook -- --config-dir .framework-storybooks/.storybook-react --port 6002 --no-open\" \"npm run storybook -- --config-dir .framework-storybooks/.storybook-svelte --port 6003 --no-open\" \"npm run storybook -- --config-dir .framework-storybooks/.storybook-vue --port 6004 --no-open\"",
    "sbook-parent": "npx wait-on http://localhost:6001 && npx wait-on http://localhost:6002 && npx wait-on http://localhost:6003  && npx wait-on http://localhost:6004 && npm run storybook",
    "sbook": "npx concurrently \"npm run sbook-children\" \"npm run sbook-parent\""