@storybook/builder-vite 0.1.22 → 0.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,23 +1,27 @@
1
1
  # Storybook builder for Vite
2
2
 
3
- Requirements:
4
-
5
- - Vite 2.5 or newer
3
+ Build your stories with [vite](https://vitejs.dev/) for fast startup times and near-instant HMR.
6
4
 
7
- Have a look at the GitHub issues for known bugs. If you find any new bugs,
8
- feel free to create an issue or send a pull request!
5
+ ## Project has been renamed
9
6
 
10
- ## More maintainers needed!
7
+ This project has moved from `storybook-builder-vite` to `@storybook/builder-vite` as part of a larger effort to improve Vite support in Storybook. To automatically migrate your existing project, you can run
11
8
 
12
- The Vite builder cannot build itself.
13
- Are you willing to contribute?
9
+ ```bash
10
+ npx sb@next automigrate
11
+ ```
14
12
 
15
- https://github.com/storybookjs/builder-vite/issues/11
13
+ To manually migrate:
16
14
 
17
- Please read the [How to contribute](/CONTRIBUTING.md) guide.
15
+ 1. Remove `storybook-builder-vite` from your `package.json` dependencies
16
+ 2. Install `@storybook/builder-vite`
17
+ 3. Update your `core.builder` setting in `.storybook/main.js` to `@storybook/builder-vite`.
18
18
 
19
19
  ### Installation
20
20
 
21
+ Requirements:
22
+
23
+ - Vite 2.5 or newer
24
+
21
25
  ```bash
22
26
  npm install @storybook/builder-vite --save-dev
23
27
  ```
@@ -28,12 +32,20 @@ or
28
32
  yarn add --dev @storybook/builder-vite
29
33
  ```
30
34
 
35
+ or
36
+
37
+ ```bash
38
+ pnpm add --save-dev @storybook/builder-vite
39
+ ```
40
+
41
+ Note: when using `pnpm`, you may need to enable [shamefully-hoist](https://pnpm.io/npmrc#shamefully-hoist), until https://github.com/storybookjs/builder-vite/issues/55 can be fixed.
42
+
31
43
  ### Usage
32
44
 
33
45
  In your `main.js` configuration file,
34
46
  set `core: { builder: "@storybook/builder-vite" }`.
35
47
 
36
- > For autoreload of stories to work, they need to have `.stories.tsx` file suffix.
48
+ > For autoreload of react stories to work, they need to have a `.stories.tsx` or `.stories.jsx` file suffix.
37
49
  > See also [#53](https://github.com/storybookjs/builder-vite/pull/53)
38
50
 
39
51
  The builder supports both development mode in Storybook, and building a static production version.
@@ -92,29 +104,37 @@ The builder will by default enable Vite's [server.fs.strict](https://vitejs.dev/
92
104
  option, for increased security. The default project `root` is set to the parent directory of the
93
105
  storybook configuration directory. This can be overridden in viteFinal.
94
106
 
95
- ### Getting started with React, Vite and Storybook (on a new project)
107
+ ### Getting started with Vite and Storybook (on a new project)
108
+
109
+ See https://vitejs.dev/guide/#scaffolding-your-first-vite-project,
96
110
 
97
111
  ```
98
- npm init @vitejs/app vite-react-app --template react && cd vite-react-app
99
- npm install # or yarn
100
- npx sb@next init --builder @storybook/builder-vite && npm run storybook
112
+ npm create vite@latest # follow the prompts
113
+ npx sb init --builder @storybook/builder-vite && npm run storybook
101
114
  ```
102
115
 
103
116
  ## Known issues
104
117
 
105
- - HMR: saving a story file does not hot-module-reload. In svelte, the page is not reloaded either (https://github.com/storybookjs/builder-vite/issues/209). HMR should work when saving component files.
106
- - Prebundling: Vite restarts if it detects new dependencies which it did not know about and needs to pre-bundle. This breaks within storybook, with confusing error messages. If you see a message in your terminal like `[vite] new dependencies found:`, please add those dependencies to your `optimizeDeps.include` in `viteFinal`. E.g. `config.optimizeDeps.include = [...(config.optimizeDeps?.include ?? []), "storybook-dark-mode"],`.
107
- - MDX pages are broken when emotion 11 is installed: Adding the configuration [here](https://github.com/storybookjs/builder-vite/issues/219#issuecomment-1023666193) should fix this.
118
+ - HMR: saving a story file does not hot-module-reload, a full reload happens instead. HMR works correctly when saving component files.
119
+ - Prebundling: Vite restarts if it detects new dependencies which it did not know about and needs to pre-bundle. This breaks within storybook, with confusing error messages. If you see a message in your terminal like `[vite] new dependencies found:`, please add those dependencies to your `optimizeDeps.include` in `viteFinal`. E.g. `config.optimizeDeps.include = [...(config.optimizeDeps?.include ?? []), "storybook-dark-mode"],`. Vite 2.9.0 may improve this behavior.
108
120
 
109
121
  ## Contributing
110
122
 
111
- Contributions are welcome!
123
+ The Vite builder cannot build itself.
124
+ Are you willing to contribute?
125
+
126
+ https://github.com/storybookjs/builder-vite/issues/11
127
+
128
+ Have a look at the GitHub issues for known bugs. If you find any new bugs,
129
+ feel free to create an issue or send a pull request!
130
+
131
+ Please read the [How to contribute](/CONTRIBUTING.md) guide.
112
132
 
113
133
  ### About this codebase
114
134
 
115
135
  The code is a monorepo with the core `@storybook/builder-vite` package,
116
- and examples (like `packages/example-react`) to test the builder implementation with.
136
+ and examples (like `examples/react`) to test the builder implementation.
117
137
 
118
- Similar to the main storybook monorepo, you need yarn , because the project is organized as yarn workspaces.
138
+ Similar to the main storybook monorepo, you need yarn to develop this builder, because the project is organized as yarn workspaces.
119
139
  This lets you write new code in the core builder package, and instantly use them from
120
140
  the example packages.
@@ -5,14 +5,14 @@ import { generateIframeScriptCode } from './codegen-iframe-script';
5
5
  import { generateModernIframeScriptCode } from './codegen-modern-iframe-script';
6
6
  import { generateImportFnScriptCode } from './codegen-importfn-script';
7
7
  import { generateVirtualStoryEntryCode, generatePreviewEntryCode } from './codegen-entries';
8
+ import { generateAddonSetupCode } from './codegen-set-addon-channel';
8
9
 
9
10
  import type { Plugin } from 'vite';
10
11
  import type { ExtendedOptions } from './types';
11
12
 
13
+ import { virtualAddonSetupFile, virtualFileId, virtualPreviewFile, virtualStoriesFile } from './virtual-file-names';
14
+
12
15
  export function codeGeneratorPlugin(options: ExtendedOptions): Plugin {
13
- const virtualFileId = '/virtual:/@storybook/builder-vite/vite-app.js';
14
- const virtualStoriesFile = '/virtual:/@storybook/builder-vite/storybook-stories.js';
15
- const virtualPreviewFile = '/virtual:/@storybook/builder-vite/preview-entry.js';
16
16
  const iframePath = path.resolve(__dirname, '..', 'input', 'iframe.html');
17
17
  let iframeId: string;
18
18
 
@@ -61,6 +61,8 @@ export function codeGeneratorPlugin(options: ExtendedOptions): Plugin {
61
61
  return virtualStoriesFile;
62
62
  } else if (source === virtualPreviewFile) {
63
63
  return virtualPreviewFile;
64
+ } else if (source === virtualAddonSetupFile) {
65
+ return virtualAddonSetupFile;
64
66
  }
65
67
  },
66
68
  async load(id) {
@@ -73,18 +75,19 @@ export function codeGeneratorPlugin(options: ExtendedOptions): Plugin {
73
75
  }
74
76
  }
75
77
 
78
+ if (id === virtualAddonSetupFile) {
79
+ return generateAddonSetupCode();
80
+ }
81
+
76
82
  if (id === virtualPreviewFile && !storyStoreV7) {
77
83
  return generatePreviewEntryCode(options);
78
84
  }
79
85
 
80
86
  if (id === virtualFileId) {
81
87
  if (storyStoreV7) {
82
- return generateModernIframeScriptCode(options, { storiesFilename: virtualStoriesFile });
88
+ return generateModernIframeScriptCode(options);
83
89
  } else {
84
- return generateIframeScriptCode(options, {
85
- storiesFilename: virtualStoriesFile,
86
- previewFilename: virtualPreviewFile,
87
- });
90
+ return generateIframeScriptCode(options);
88
91
  }
89
92
  }
90
93
 
@@ -1,16 +1,9 @@
1
1
  import { normalizePath } from 'vite';
2
+ import { virtualPreviewFile, virtualStoriesFile, virtualAddonSetupFile } from './virtual-file-names';
2
3
 
3
4
  import type { ExtendedOptions } from './types';
4
5
 
5
- interface GenerateIframeScriptCodeOptions {
6
- storiesFilename: string;
7
- previewFilename: string;
8
- }
9
-
10
- export async function generateIframeScriptCode(
11
- options: ExtendedOptions,
12
- { storiesFilename, previewFilename }: GenerateIframeScriptCodeOptions
13
- ) {
6
+ export async function generateIframeScriptCode(options: ExtendedOptions) {
14
7
  const { presets } = options;
15
8
 
16
9
  const presetEntries = await presets.apply('config', [], options);
@@ -25,6 +18,7 @@ export async function generateIframeScriptCode(
25
18
  /** @todo Inline variable and remove `noinspection` */
26
19
  // language=JavaScript
27
20
  const code = `
21
+ import '${virtualAddonSetupFile}';
28
22
  import {
29
23
  addDecorator,
30
24
  addParameters,
@@ -34,9 +28,9 @@ export async function generateIframeScriptCode(
34
28
  } from '@storybook/client-api';
35
29
  import { logger } from '@storybook/client-logger';
36
30
  ${absoluteFilesToImport(configEntries, 'config')}
37
- import * as preview from '${previewFilename}';
31
+ import * as preview from '${virtualPreviewFile}';
38
32
  // This import should occur after the config imports above
39
- import { configStories } from '${storiesFilename}';
33
+ import { configStories } from '${virtualStoriesFile}';
40
34
 
41
35
  const configs = [${importArray('config', configEntries.length).concat('preview.default').join(',')}].filter(Boolean)
42
36
 
@@ -1,16 +1,9 @@
1
1
  import { loadPreviewOrConfigFile } from '@storybook/core-common';
2
2
  import { normalizePath } from 'vite';
3
-
3
+ import { virtualStoriesFile, virtualAddonSetupFile } from './virtual-file-names';
4
4
  import type { ExtendedOptions } from './types';
5
5
 
6
- interface GenerateModernIframeScriptCodeOptions {
7
- storiesFilename: string;
8
- }
9
-
10
- export async function generateModernIframeScriptCode(
11
- options: ExtendedOptions,
12
- { storiesFilename }: GenerateModernIframeScriptCodeOptions
13
- ) {
6
+ export async function generateModernIframeScriptCode(options: ExtendedOptions) {
14
7
  const { presets, configDir } = options;
15
8
 
16
9
  const previewOrConfigFile = loadPreviewOrConfigFile({ configDir });
@@ -28,43 +21,26 @@ export async function generateModernIframeScriptCode(
28
21
  */
29
22
  // language=JavaScript
30
23
  const code = `
31
- import global from 'global';
32
-
33
24
  import { composeConfigs, PreviewWeb } from '@storybook/preview-web';
34
25
  import { ClientApi } from '@storybook/client-api';
35
- import { addons } from '@storybook/addons';
36
- import createPostMessageChannel from '@storybook/channel-postmessage';
37
- import createWebSocketChannel from '@storybook/channel-websocket';
38
-
39
- import { importFn } from '${storiesFilename}';
40
-
41
- const { SERVER_CHANNEL_URL } = global;
26
+ import '${virtualAddonSetupFile}';
27
+ import { importFn } from '${virtualStoriesFile}';
42
28
 
43
29
  const getProjectAnnotations = async () =>
44
30
  composeConfigs(await Promise.all([${configEntries
45
31
  .map((configEntry) => `import('${configEntry}')`)
46
32
  .join(',\n')}]));
47
33
 
48
- const channel = createPostMessageChannel({ page: 'preview' });
49
- addons.setChannel(channel);
50
-
51
- if (SERVER_CHANNEL_URL) {
52
- const serverChannel = createWebSocketChannel({ url: SERVER_CHANNEL_URL });
53
- addons.setServerChannel(serverChannel);
54
- window.__STORYBOOK_SERVER_CHANNEL__ = serverChannel;
55
- }
56
-
57
34
  const preview = new PreviewWeb();
58
35
 
59
36
  window.__STORYBOOK_PREVIEW__ = preview;
60
37
  window.__STORYBOOK_STORY_STORE__ = preview.storyStore;
61
- window.__STORYBOOK_ADDONS_CHANNEL__ = channel;
62
38
  window.__STORYBOOK_CLIENT_API__ = new ClientApi({ storyStore: preview.storyStore });
63
39
 
64
40
  preview.initialize({ importFn, getProjectAnnotations });
65
41
 
66
42
  if (import.meta.hot) {
67
- import.meta.hot.accept('${storiesFilename}', (newModule) => {
43
+ import.meta.hot.accept('${virtualStoriesFile}', (newModule) => {
68
44
 
69
45
  // importFn has changed so we need to patch the new one in
70
46
  preview.onStoriesChanged({ importFn: newModule.importFn });
@@ -0,0 +1,19 @@
1
+ export function generateAddonSetupCode() {
2
+ return `
3
+ import global from 'global';
4
+ import createPostMessageChannel from '@storybook/channel-postmessage';
5
+ import createWebSocketChannel from '@storybook/channel-websocket';
6
+ import { addons } from '@storybook/addons';
7
+
8
+ const channel = createPostMessageChannel({ page: 'preview' });
9
+ addons.setChannel(channel);
10
+ window.__STORYBOOK_ADDONS_CHANNEL__ = channel;
11
+
12
+ const { SERVER_CHANNEL_URL } = global;
13
+ if (SERVER_CHANNEL_URL) {
14
+ const serverChannel = createWebSocketChannel({ url: SERVER_CHANNEL_URL });
15
+ addons.setServerChannel(serverChannel);
16
+ window.__STORYBOOK_SERVER_CHANNEL__ = serverChannel;
17
+ }
18
+ `.trim();
19
+ }
@@ -27,10 +27,9 @@ const codegen_iframe_script_1 = require("./codegen-iframe-script");
27
27
  const codegen_modern_iframe_script_1 = require("./codegen-modern-iframe-script");
28
28
  const codegen_importfn_script_1 = require("./codegen-importfn-script");
29
29
  const codegen_entries_1 = require("./codegen-entries");
30
+ const codegen_set_addon_channel_1 = require("./codegen-set-addon-channel");
31
+ const virtual_file_names_1 = require("./virtual-file-names");
30
32
  function codeGeneratorPlugin(options) {
31
- const virtualFileId = '/virtual:/@storybook/builder-vite/vite-app.js';
32
- const virtualStoriesFile = '/virtual:/@storybook/builder-vite/storybook-stories.js';
33
- const virtualPreviewFile = '/virtual:/@storybook/builder-vite/preview-entry.js';
34
33
  const iframePath = path.resolve(__dirname, '..', 'input', 'iframe.html');
35
34
  let iframeId;
36
35
  // noinspection JSUnusedGlobalSymbols
@@ -42,11 +41,11 @@ function codeGeneratorPlugin(options) {
42
41
  // (this might be a little too aggressive?)
43
42
  server.watcher.on('change', (_e) => {
44
43
  const { moduleGraph } = server;
45
- const appModule = moduleGraph.getModuleById(virtualFileId);
44
+ const appModule = moduleGraph.getModuleById(virtual_file_names_1.virtualFileId);
46
45
  if (appModule) {
47
46
  server.moduleGraph.invalidateModule(appModule);
48
47
  }
49
- const storiesModule = moduleGraph.getModuleById(virtualStoriesFile);
48
+ const storiesModule = moduleGraph.getModuleById(virtual_file_names_1.virtualStoriesFile);
50
49
  if (storiesModule) {
51
50
  server.moduleGraph.invalidateModule(storiesModule);
52
51
  }
@@ -70,23 +69,26 @@ function codeGeneratorPlugin(options) {
70
69
  iframeId = `${config.root}/iframe.html`;
71
70
  },
72
71
  resolveId(source) {
73
- if (source === virtualFileId) {
74
- return virtualFileId;
72
+ if (source === virtual_file_names_1.virtualFileId) {
73
+ return virtual_file_names_1.virtualFileId;
75
74
  }
76
75
  else if (source === iframePath) {
77
76
  return iframeId;
78
77
  }
79
- else if (source === virtualStoriesFile) {
80
- return virtualStoriesFile;
78
+ else if (source === virtual_file_names_1.virtualStoriesFile) {
79
+ return virtual_file_names_1.virtualStoriesFile;
81
80
  }
82
- else if (source === virtualPreviewFile) {
83
- return virtualPreviewFile;
81
+ else if (source === virtual_file_names_1.virtualPreviewFile) {
82
+ return virtual_file_names_1.virtualPreviewFile;
83
+ }
84
+ else if (source === virtual_file_names_1.virtualAddonSetupFile) {
85
+ return virtual_file_names_1.virtualAddonSetupFile;
84
86
  }
85
87
  },
86
88
  async load(id) {
87
89
  var _a;
88
90
  const storyStoreV7 = (_a = options.features) === null || _a === void 0 ? void 0 : _a.storyStoreV7;
89
- if (id === virtualStoriesFile) {
91
+ if (id === virtual_file_names_1.virtualStoriesFile) {
90
92
  if (storyStoreV7) {
91
93
  return (0, codegen_importfn_script_1.generateImportFnScriptCode)(options);
92
94
  }
@@ -94,18 +96,18 @@ function codeGeneratorPlugin(options) {
94
96
  return (0, codegen_entries_1.generateVirtualStoryEntryCode)(options);
95
97
  }
96
98
  }
97
- if (id === virtualPreviewFile && !storyStoreV7) {
99
+ if (id === virtual_file_names_1.virtualAddonSetupFile) {
100
+ return (0, codegen_set_addon_channel_1.generateAddonSetupCode)();
101
+ }
102
+ if (id === virtual_file_names_1.virtualPreviewFile && !storyStoreV7) {
98
103
  return (0, codegen_entries_1.generatePreviewEntryCode)(options);
99
104
  }
100
- if (id === virtualFileId) {
105
+ if (id === virtual_file_names_1.virtualFileId) {
101
106
  if (storyStoreV7) {
102
- return (0, codegen_modern_iframe_script_1.generateModernIframeScriptCode)(options, { storiesFilename: virtualStoriesFile });
107
+ return (0, codegen_modern_iframe_script_1.generateModernIframeScriptCode)(options);
103
108
  }
104
109
  else {
105
- return (0, codegen_iframe_script_1.generateIframeScriptCode)(options, {
106
- storiesFilename: virtualStoriesFile,
107
- previewFilename: virtualPreviewFile,
108
- });
110
+ return (0, codegen_iframe_script_1.generateIframeScriptCode)(options);
109
111
  }
110
112
  }
111
113
  if (id === iframeId) {
@@ -1 +1 @@
1
- {"version":3,"file":"code-generator-plugin.js","sourceRoot":"","sources":["../code-generator-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { transformIframeHtml } from './transform-iframe-html';\nimport { generateIframeScriptCode } from './codegen-iframe-script';\nimport { generateModernIframeScriptCode } from './codegen-modern-iframe-script';\nimport { generateImportFnScriptCode } from './codegen-importfn-script';\nimport { generateVirtualStoryEntryCode, generatePreviewEntryCode } from './codegen-entries';\n\nimport type { Plugin } from 'vite';\nimport type { ExtendedOptions } from './types';\n\nexport function codeGeneratorPlugin(options: ExtendedOptions): Plugin {\n const virtualFileId = '/virtual:/@storybook/builder-vite/vite-app.js';\n const virtualStoriesFile = '/virtual:/@storybook/builder-vite/storybook-stories.js';\n const virtualPreviewFile = '/virtual:/@storybook/builder-vite/preview-entry.js';\n const iframePath = path.resolve(__dirname, '..', 'input', 'iframe.html');\n let iframeId: string;\n\n // noinspection JSUnusedGlobalSymbols\n return {\n name: 'storybook-vite-code-generator-plugin',\n enforce: 'pre',\n configureServer(server) {\n // invalidate the whole vite-app.js script on every file change.\n // (this might be a little too aggressive?)\n server.watcher.on('change', (_e) => {\n const { moduleGraph } = server;\n const appModule = moduleGraph.getModuleById(virtualFileId);\n if (appModule) {\n server.moduleGraph.invalidateModule(appModule);\n }\n const storiesModule = moduleGraph.getModuleById(virtualStoriesFile);\n if (storiesModule) {\n server.moduleGraph.invalidateModule(storiesModule);\n }\n });\n },\n config(config, { command }) {\n // If we are building the static distribution, add iframe.html as an entry.\n // In development mode, it's not an entry - instead, we use an express middleware\n // to serve iframe.html. The reason is that Vite's dev server (at the time of writing)\n // does not support virtual files as entry points.\n if (command === 'build') {\n if (!config.build) {\n config.build = {};\n }\n config.build.rollupOptions = {\n input: iframePath,\n };\n }\n },\n configResolved(config) {\n iframeId = `${config.root}/iframe.html`;\n },\n resolveId(source) {\n if (source === virtualFileId) {\n return virtualFileId;\n } else if (source === iframePath) {\n return iframeId;\n } else if (source === virtualStoriesFile) {\n return virtualStoriesFile;\n } else if (source === virtualPreviewFile) {\n return virtualPreviewFile;\n }\n },\n async load(id) {\n const storyStoreV7 = options.features?.storyStoreV7;\n if (id === virtualStoriesFile) {\n if (storyStoreV7) {\n return generateImportFnScriptCode(options);\n } else {\n return generateVirtualStoryEntryCode(options);\n }\n }\n\n if (id === virtualPreviewFile && !storyStoreV7) {\n return generatePreviewEntryCode(options);\n }\n\n if (id === virtualFileId) {\n if (storyStoreV7) {\n return generateModernIframeScriptCode(options, { storiesFilename: virtualStoriesFile });\n } else {\n return generateIframeScriptCode(options, {\n storiesFilename: virtualStoriesFile,\n previewFilename: virtualPreviewFile,\n });\n }\n }\n\n if (id === iframeId) {\n return fs.readFileSync(path.resolve(__dirname, '..', 'input', 'iframe.html'), 'utf-8');\n }\n },\n async transformIndexHtml(html, ctx) {\n if (ctx.path !== '/iframe.html') {\n return;\n }\n return transformIframeHtml(html, options);\n },\n };\n}\n"]}
1
+ {"version":3,"file":"code-generator-plugin.js","sourceRoot":"","sources":["../code-generator-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { transformIframeHtml } from './transform-iframe-html';\nimport { generateIframeScriptCode } from './codegen-iframe-script';\nimport { generateModernIframeScriptCode } from './codegen-modern-iframe-script';\nimport { generateImportFnScriptCode } from './codegen-importfn-script';\nimport { generateVirtualStoryEntryCode, generatePreviewEntryCode } from './codegen-entries';\nimport { generateAddonSetupCode } from './codegen-set-addon-channel';\n\nimport type { Plugin } from 'vite';\nimport type { ExtendedOptions } from './types';\n\nimport { virtualAddonSetupFile, virtualFileId, virtualPreviewFile, virtualStoriesFile } from './virtual-file-names';\n\nexport function codeGeneratorPlugin(options: ExtendedOptions): Plugin {\n const iframePath = path.resolve(__dirname, '..', 'input', 'iframe.html');\n let iframeId: string;\n\n // noinspection JSUnusedGlobalSymbols\n return {\n name: 'storybook-vite-code-generator-plugin',\n enforce: 'pre',\n configureServer(server) {\n // invalidate the whole vite-app.js script on every file change.\n // (this might be a little too aggressive?)\n server.watcher.on('change', (_e) => {\n const { moduleGraph } = server;\n const appModule = moduleGraph.getModuleById(virtualFileId);\n if (appModule) {\n server.moduleGraph.invalidateModule(appModule);\n }\n const storiesModule = moduleGraph.getModuleById(virtualStoriesFile);\n if (storiesModule) {\n server.moduleGraph.invalidateModule(storiesModule);\n }\n });\n },\n config(config, { command }) {\n // If we are building the static distribution, add iframe.html as an entry.\n // In development mode, it's not an entry - instead, we use an express middleware\n // to serve iframe.html. The reason is that Vite's dev server (at the time of writing)\n // does not support virtual files as entry points.\n if (command === 'build') {\n if (!config.build) {\n config.build = {};\n }\n config.build.rollupOptions = {\n input: iframePath,\n };\n }\n },\n configResolved(config) {\n iframeId = `${config.root}/iframe.html`;\n },\n resolveId(source) {\n if (source === virtualFileId) {\n return virtualFileId;\n } else if (source === iframePath) {\n return iframeId;\n } else if (source === virtualStoriesFile) {\n return virtualStoriesFile;\n } else if (source === virtualPreviewFile) {\n return virtualPreviewFile;\n } else if (source === virtualAddonSetupFile) {\n return virtualAddonSetupFile;\n }\n },\n async load(id) {\n const storyStoreV7 = options.features?.storyStoreV7;\n if (id === virtualStoriesFile) {\n if (storyStoreV7) {\n return generateImportFnScriptCode(options);\n } else {\n return generateVirtualStoryEntryCode(options);\n }\n }\n\n if (id === virtualAddonSetupFile) {\n return generateAddonSetupCode();\n }\n\n if (id === virtualPreviewFile && !storyStoreV7) {\n return generatePreviewEntryCode(options);\n }\n\n if (id === virtualFileId) {\n if (storyStoreV7) {\n return generateModernIframeScriptCode(options);\n } else {\n return generateIframeScriptCode(options);\n }\n }\n\n if (id === iframeId) {\n return fs.readFileSync(path.resolve(__dirname, '..', 'input', 'iframe.html'), 'utf-8');\n }\n },\n async transformIndexHtml(html, ctx) {\n if (ctx.path !== '/iframe.html') {\n return;\n }\n return transformIframeHtml(html, options);\n },\n };\n}\n"]}
@@ -1,7 +1,2 @@
1
1
  import type { ExtendedOptions } from './types';
2
- interface GenerateIframeScriptCodeOptions {
3
- storiesFilename: string;
4
- previewFilename: string;
5
- }
6
- export declare function generateIframeScriptCode(options: ExtendedOptions, { storiesFilename, previewFilename }: GenerateIframeScriptCodeOptions): Promise<string>;
7
- export {};
2
+ export declare function generateIframeScriptCode(options: ExtendedOptions): Promise<string>;
@@ -2,7 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateIframeScriptCode = void 0;
4
4
  const vite_1 = require("vite");
5
- async function generateIframeScriptCode(options, { storiesFilename, previewFilename }) {
5
+ const virtual_file_names_1 = require("./virtual-file-names");
6
+ async function generateIframeScriptCode(options) {
6
7
  const { presets } = options;
7
8
  const presetEntries = await presets.apply('config', [], options);
8
9
  const configEntries = [...presetEntries].filter(Boolean);
@@ -12,6 +13,7 @@ async function generateIframeScriptCode(options, { storiesFilename, previewFilen
12
13
  /** @todo Inline variable and remove `noinspection` */
13
14
  // language=JavaScript
14
15
  const code = `
16
+ import '${virtual_file_names_1.virtualAddonSetupFile}';
15
17
  import {
16
18
  addDecorator,
17
19
  addParameters,
@@ -21,9 +23,9 @@ async function generateIframeScriptCode(options, { storiesFilename, previewFilen
21
23
  } from '@storybook/client-api';
22
24
  import { logger } from '@storybook/client-logger';
23
25
  ${absoluteFilesToImport(configEntries, 'config')}
24
- import * as preview from '${previewFilename}';
26
+ import * as preview from '${virtual_file_names_1.virtualPreviewFile}';
25
27
  // This import should occur after the config imports above
26
- import { configStories } from '${storiesFilename}';
28
+ import { configStories } from '${virtual_file_names_1.virtualStoriesFile}';
27
29
 
28
30
  const configs = [${importArray('config', configEntries.length).concat('preview.default').join(',')}].filter(Boolean)
29
31
 
@@ -1 +1 @@
1
- {"version":3,"file":"codegen-iframe-script.js","sourceRoot":"","sources":["../codegen-iframe-script.ts"],"names":[],"mappings":";;;AAAA,+BAAqC;AAS9B,KAAK,UAAU,wBAAwB,CAC5C,OAAwB,EACxB,EAAE,eAAe,EAAE,eAAe,EAAmC;IAErE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE5B,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IACjE,MAAM,aAAa,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEzD,MAAM,qBAAqB,GAAG,CAAC,KAAe,EAAE,IAAY,EAAE,EAAE,CAC9D,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,IAAA,oBAAa,EAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEhH,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,MAAc,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;IAE9G,0CAA0C;IAC1C,sDAAsD;IACtD,sBAAsB;IACtB,MAAM,IAAI,GAAG;;;;;;;;;MAST,qBAAqB,CAAC,aAAa,EAAE,QAAQ,CAAC;gCACpB,eAAe;;qCAEV,eAAe;;uBAE7B,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkDjG,CAAC,IAAI,EAAE,CAAC;IACX,OAAO,IAAI,CAAC;AACd,CAAC;AAnFD,4DAmFC","sourcesContent":["import { normalizePath } from 'vite';\n\nimport type { ExtendedOptions } from './types';\n\ninterface GenerateIframeScriptCodeOptions {\n storiesFilename: string;\n previewFilename: string;\n}\n\nexport async function generateIframeScriptCode(\n options: ExtendedOptions,\n { storiesFilename, previewFilename }: GenerateIframeScriptCodeOptions\n) {\n const { presets } = options;\n\n const presetEntries = await presets.apply('config', [], options);\n const configEntries = [...presetEntries].filter(Boolean);\n\n const absoluteFilesToImport = (files: string[], name: string) =>\n files.map((el, i) => `import ${name ? `* as ${name}_${i} from ` : ''}'/@fs/${normalizePath(el)}'`).join('\\n');\n\n const importArray = (name: string, length: number) => new Array(length).fill(0).map((_, i) => `${name}_${i}`);\n\n // noinspection UnnecessaryLocalVariableJS\n /** @todo Inline variable and remove `noinspection` */\n // language=JavaScript\n const code = `\n import {\n addDecorator,\n addParameters,\n addLoader,\n addArgTypesEnhancer,\n addArgsEnhancer\n } from '@storybook/client-api';\n import { logger } from '@storybook/client-logger';\n ${absoluteFilesToImport(configEntries, 'config')}\n import * as preview from '${previewFilename}';\n // This import should occur after the config imports above\n import { configStories } from '${storiesFilename}';\n\n const configs = [${importArray('config', configEntries.length).concat('preview.default').join(',')}].filter(Boolean)\n\n configs.forEach(config => {\n Object.keys(config).forEach((key) => {\n const value = config[key];\n switch (key) {\n case 'args':\n case 'argTypes': {\n return logger.warn('Invalid args/argTypes in config, ignoring.', JSON.stringify(value));\n }\n case 'decorators': {\n return value.forEach((decorator) => addDecorator(decorator, false));\n }\n case 'loaders': {\n return value.forEach((loader) => addLoader(loader, false));\n }\n case 'parameters': {\n return addParameters({ ...value }, false);\n }\n case 'argTypesEnhancers': {\n return value.forEach((enhancer) => addArgTypesEnhancer(enhancer));\n }\n case 'argsEnhancers': {\n return value.forEach((enhancer) => addArgsEnhancer(enhancer))\n }\n case 'globals':\n case 'globalTypes': {\n const v = {};\n v[key] = value;\n return addParameters(v, false);\n }\n case 'decorateStory':\n case 'renderToDOM': {\n return null; // This key is not handled directly in v6 mode.\n }\n default: {\n // eslint-disable-next-line prefer-template\n return console.log(key + ' was not supported :( !');\n }\n }\n });\n })\n \n /* TODO: not quite sure what to do with this, to fix HMR\n if (import.meta.hot) {\n import.meta.hot.accept(); \n }\n */\n\n configStories();\n `.trim();\n return code;\n}\n"]}
1
+ {"version":3,"file":"codegen-iframe-script.js","sourceRoot":"","sources":["../codegen-iframe-script.ts"],"names":[],"mappings":";;;AAAA,+BAAqC;AACrC,6DAAqG;AAI9F,KAAK,UAAU,wBAAwB,CAAC,OAAwB;IACrE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE5B,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IACjE,MAAM,aAAa,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEzD,MAAM,qBAAqB,GAAG,CAAC,KAAe,EAAE,IAAY,EAAE,EAAE,CAC9D,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,IAAA,oBAAa,EAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEhH,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,MAAc,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;IAE9G,0CAA0C;IAC1C,sDAAsD;IACtD,sBAAsB;IACtB,MAAM,IAAI,GAAG;cACD,0CAAqB;;;;;;;;;MAS7B,qBAAqB,CAAC,aAAa,EAAE,QAAQ,CAAC;gCACpB,uCAAkB;;qCAEb,uCAAkB;;uBAEhC,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkDjG,CAAC,IAAI,EAAE,CAAC;IACX,OAAO,IAAI,CAAC;AACd,CAAC;AAjFD,4DAiFC","sourcesContent":["import { normalizePath } from 'vite';\nimport { virtualPreviewFile, virtualStoriesFile, virtualAddonSetupFile } from './virtual-file-names';\n\nimport type { ExtendedOptions } from './types';\n\nexport async function generateIframeScriptCode(options: ExtendedOptions) {\n const { presets } = options;\n\n const presetEntries = await presets.apply('config', [], options);\n const configEntries = [...presetEntries].filter(Boolean);\n\n const absoluteFilesToImport = (files: string[], name: string) =>\n files.map((el, i) => `import ${name ? `* as ${name}_${i} from ` : ''}'/@fs/${normalizePath(el)}'`).join('\\n');\n\n const importArray = (name: string, length: number) => new Array(length).fill(0).map((_, i) => `${name}_${i}`);\n\n // noinspection UnnecessaryLocalVariableJS\n /** @todo Inline variable and remove `noinspection` */\n // language=JavaScript\n const code = `\n import '${virtualAddonSetupFile}';\n import {\n addDecorator,\n addParameters,\n addLoader,\n addArgTypesEnhancer,\n addArgsEnhancer\n } from '@storybook/client-api';\n import { logger } from '@storybook/client-logger';\n ${absoluteFilesToImport(configEntries, 'config')}\n import * as preview from '${virtualPreviewFile}';\n // This import should occur after the config imports above\n import { configStories } from '${virtualStoriesFile}';\n\n const configs = [${importArray('config', configEntries.length).concat('preview.default').join(',')}].filter(Boolean)\n\n configs.forEach(config => {\n Object.keys(config).forEach((key) => {\n const value = config[key];\n switch (key) {\n case 'args':\n case 'argTypes': {\n return logger.warn('Invalid args/argTypes in config, ignoring.', JSON.stringify(value));\n }\n case 'decorators': {\n return value.forEach((decorator) => addDecorator(decorator, false));\n }\n case 'loaders': {\n return value.forEach((loader) => addLoader(loader, false));\n }\n case 'parameters': {\n return addParameters({ ...value }, false);\n }\n case 'argTypesEnhancers': {\n return value.forEach((enhancer) => addArgTypesEnhancer(enhancer));\n }\n case 'argsEnhancers': {\n return value.forEach((enhancer) => addArgsEnhancer(enhancer))\n }\n case 'globals':\n case 'globalTypes': {\n const v = {};\n v[key] = value;\n return addParameters(v, false);\n }\n case 'decorateStory':\n case 'renderToDOM': {\n return null; // This key is not handled directly in v6 mode.\n }\n default: {\n // eslint-disable-next-line prefer-template\n return console.log(key + ' was not supported :( !');\n }\n }\n });\n })\n \n /* TODO: not quite sure what to do with this, to fix HMR\n if (import.meta.hot) {\n import.meta.hot.accept(); \n }\n */\n\n configStories();\n `.trim();\n return code;\n}\n"]}
@@ -1,6 +1,2 @@
1
1
  import type { ExtendedOptions } from './types';
2
- interface GenerateModernIframeScriptCodeOptions {
3
- storiesFilename: string;
4
- }
5
- export declare function generateModernIframeScriptCode(options: ExtendedOptions, { storiesFilename }: GenerateModernIframeScriptCodeOptions): Promise<string>;
6
- export {};
2
+ export declare function generateModernIframeScriptCode(options: ExtendedOptions): Promise<string>;
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateModernIframeScriptCode = void 0;
4
4
  const core_common_1 = require("@storybook/core-common");
5
5
  const vite_1 = require("vite");
6
- async function generateModernIframeScriptCode(options, { storiesFilename }) {
6
+ const virtual_file_names_1 = require("./virtual-file-names");
7
+ async function generateModernIframeScriptCode(options) {
7
8
  const { presets, configDir } = options;
8
9
  const previewOrConfigFile = (0, core_common_1.loadPreviewOrConfigFile)({ configDir });
9
10
  const presetEntries = await presets.apply('config', [], options);
@@ -19,43 +20,26 @@ async function generateModernIframeScriptCode(options, { storiesFilename }) {
19
20
  */
20
21
  // language=JavaScript
21
22
  const code = `
22
- import global from 'global';
23
-
24
23
  import { composeConfigs, PreviewWeb } from '@storybook/preview-web';
25
24
  import { ClientApi } from '@storybook/client-api';
26
- import { addons } from '@storybook/addons';
27
- import createPostMessageChannel from '@storybook/channel-postmessage';
28
- import createWebSocketChannel from '@storybook/channel-websocket';
29
-
30
- import { importFn } from '${storiesFilename}';
31
-
32
- const { SERVER_CHANNEL_URL } = global;
25
+ import '${virtual_file_names_1.virtualAddonSetupFile}';
26
+ import { importFn } from '${virtual_file_names_1.virtualStoriesFile}';
33
27
 
34
28
  const getProjectAnnotations = async () =>
35
29
  composeConfigs(await Promise.all([${configEntries
36
30
  .map((configEntry) => `import('${configEntry}')`)
37
31
  .join(',\n')}]));
38
32
 
39
- const channel = createPostMessageChannel({ page: 'preview' });
40
- addons.setChannel(channel);
41
-
42
- if (SERVER_CHANNEL_URL) {
43
- const serverChannel = createWebSocketChannel({ url: SERVER_CHANNEL_URL });
44
- addons.setServerChannel(serverChannel);
45
- window.__STORYBOOK_SERVER_CHANNEL__ = serverChannel;
46
- }
47
-
48
33
  const preview = new PreviewWeb();
49
34
 
50
35
  window.__STORYBOOK_PREVIEW__ = preview;
51
36
  window.__STORYBOOK_STORY_STORE__ = preview.storyStore;
52
- window.__STORYBOOK_ADDONS_CHANNEL__ = channel;
53
37
  window.__STORYBOOK_CLIENT_API__ = new ClientApi({ storyStore: preview.storyStore });
54
38
 
55
39
  preview.initialize({ importFn, getProjectAnnotations });
56
40
 
57
41
  if (import.meta.hot) {
58
- import.meta.hot.accept('${storiesFilename}', (newModule) => {
42
+ import.meta.hot.accept('${virtual_file_names_1.virtualStoriesFile}', (newModule) => {
59
43
 
60
44
  // importFn has changed so we need to patch the new one in
61
45
  preview.onStoriesChanged({ importFn: newModule.importFn });
@@ -1 +1 @@
1
- {"version":3,"file":"codegen-modern-iframe-script.js","sourceRoot":"","sources":["../codegen-modern-iframe-script.ts"],"names":[],"mappings":";;;AAAA,wDAAiE;AACjE,+BAAqC;AAQ9B,KAAK,UAAU,8BAA8B,CAClD,OAAwB,EACxB,EAAE,eAAe,EAAyC;IAE1D,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAEvC,MAAM,mBAAmB,GAAG,IAAA,qCAAuB,EAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IACnE,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IACjE,MAAM,aAAa,GAAG,CAAC,GAAG,aAAa,EAAE,mBAAmB,CAAC;SAC1D,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,QAAQ,IAAA,oBAAa,EAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAE9D,0CAA0C;IAC1C;;;;;OAKG;IACH,sBAAsB;IACtB,MAAM,IAAI,GAAG;;;;;;;;;gCASiB,eAAe;;;;;0CAKL,aAAa;SAC9C,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,WAAW,IAAI,CAAC;SAChD,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;kCAqBc,eAAe;;;;;;+BAMlB,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;;;;;;;KAOvD,CAAC,IAAI,EAAE,CAAC;IACX,OAAO,IAAI,CAAC;AACd,CAAC;AAxED,wEAwEC","sourcesContent":["import { loadPreviewOrConfigFile } from '@storybook/core-common';\nimport { normalizePath } from 'vite';\n\nimport type { ExtendedOptions } from './types';\n\ninterface GenerateModernIframeScriptCodeOptions {\n storiesFilename: string;\n}\n\nexport async function generateModernIframeScriptCode(\n options: ExtendedOptions,\n { storiesFilename }: GenerateModernIframeScriptCodeOptions\n) {\n const { presets, configDir } = options;\n\n const previewOrConfigFile = loadPreviewOrConfigFile({ configDir });\n const presetEntries = await presets.apply('config', [], options);\n const configEntries = [...presetEntries, previewOrConfigFile]\n .filter(Boolean)\n .map((configEntry) => `/@fs/${normalizePath(configEntry)}`);\n\n // noinspection UnnecessaryLocalVariableJS\n /**\n * This code is largely taken from https://github.com/storybookjs/storybook/blob/d1195cbd0c61687f1720fefdb772e2f490a46584/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars\n * Some small tweaks were made to `getProjectAnnotations` (since `import()` needs to be resolved asynchronously)\n * and the HMR implementation has been tweaked to work with Vite.\n * @todo Inline variable and remove `noinspection`\n */\n // language=JavaScript\n const code = `\n import global from 'global';\n\n import { composeConfigs, PreviewWeb } from '@storybook/preview-web';\n import { ClientApi } from '@storybook/client-api';\n import { addons } from '@storybook/addons';\n import createPostMessageChannel from '@storybook/channel-postmessage';\n import createWebSocketChannel from '@storybook/channel-websocket';\n\n import { importFn } from '${storiesFilename}';\n\n const { SERVER_CHANNEL_URL } = global;\n\n const getProjectAnnotations = async () =>\n composeConfigs(await Promise.all([${configEntries\n .map((configEntry) => `import('${configEntry}')`)\n .join(',\\n')}]));\n\n const channel = createPostMessageChannel({ page: 'preview' });\n addons.setChannel(channel);\n\n if (SERVER_CHANNEL_URL) {\n const serverChannel = createWebSocketChannel({ url: SERVER_CHANNEL_URL });\n addons.setServerChannel(serverChannel);\n window.__STORYBOOK_SERVER_CHANNEL__ = serverChannel;\n }\n\n const preview = new PreviewWeb();\n\n window.__STORYBOOK_PREVIEW__ = preview;\n window.__STORYBOOK_STORY_STORE__ = preview.storyStore;\n window.__STORYBOOK_ADDONS_CHANNEL__ = channel;\n window.__STORYBOOK_CLIENT_API__ = new ClientApi({ storyStore: preview.storyStore });\n\n preview.initialize({ importFn, getProjectAnnotations });\n\n if (import.meta.hot) {\n import.meta.hot.accept('${storiesFilename}', (newModule) => {\n\n // importFn has changed so we need to patch the new one in\n preview.onStoriesChanged({ importFn: newModule.importFn });\n });\n\n import.meta.hot.accept(${JSON.stringify(configEntries)}, ([...newConfigEntries]) => {\n const newGetProjectAnnotations = () => composeConfigs(newConfigEntries);\n\n // getProjectAnnotations has changed so we need to patch the new one in\n preview.onGetProjectAnnotationsChanged({ getProjectAnnotations: newGetProjectAnnotations });\n });\n }\n `.trim();\n return code;\n}\n"]}
1
+ {"version":3,"file":"codegen-modern-iframe-script.js","sourceRoot":"","sources":["../codegen-modern-iframe-script.ts"],"names":[],"mappings":";;;AAAA,wDAAiE;AACjE,+BAAqC;AACrC,6DAAiF;AAG1E,KAAK,UAAU,8BAA8B,CAAC,OAAwB;IAC3E,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAEvC,MAAM,mBAAmB,GAAG,IAAA,qCAAuB,EAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IACnE,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IACjE,MAAM,aAAa,GAAG,CAAC,GAAG,aAAa,EAAE,mBAAmB,CAAC;SAC1D,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,QAAQ,IAAA,oBAAa,EAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAE9D,0CAA0C;IAC1C;;;;;OAKG;IACH,sBAAsB;IACtB,MAAM,IAAI,GAAG;;;cAGD,0CAAqB;gCACH,uCAAkB;;;0CAGR,aAAa;SAC9C,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,WAAW,IAAI,CAAC;SAChD,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;kCAWc,uCAAkB;;;;;;+BAMrB,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;;;;;;;KAOvD,CAAC,IAAI,EAAE,CAAC;IACX,OAAO,IAAI,CAAC;AACd,CAAC;AApDD,wEAoDC","sourcesContent":["import { loadPreviewOrConfigFile } from '@storybook/core-common';\nimport { normalizePath } from 'vite';\nimport { virtualStoriesFile, virtualAddonSetupFile } from './virtual-file-names';\nimport type { ExtendedOptions } from './types';\n\nexport async function generateModernIframeScriptCode(options: ExtendedOptions) {\n const { presets, configDir } = options;\n\n const previewOrConfigFile = loadPreviewOrConfigFile({ configDir });\n const presetEntries = await presets.apply('config', [], options);\n const configEntries = [...presetEntries, previewOrConfigFile]\n .filter(Boolean)\n .map((configEntry) => `/@fs/${normalizePath(configEntry)}`);\n\n // noinspection UnnecessaryLocalVariableJS\n /**\n * This code is largely taken from https://github.com/storybookjs/storybook/blob/d1195cbd0c61687f1720fefdb772e2f490a46584/lib/builder-webpack4/src/preview/virtualModuleModernEntry.js.handlebars\n * Some small tweaks were made to `getProjectAnnotations` (since `import()` needs to be resolved asynchronously)\n * and the HMR implementation has been tweaked to work with Vite.\n * @todo Inline variable and remove `noinspection`\n */\n // language=JavaScript\n const code = `\n import { composeConfigs, PreviewWeb } from '@storybook/preview-web';\n import { ClientApi } from '@storybook/client-api';\n import '${virtualAddonSetupFile}';\n import { importFn } from '${virtualStoriesFile}';\n\n const getProjectAnnotations = async () =>\n composeConfigs(await Promise.all([${configEntries\n .map((configEntry) => `import('${configEntry}')`)\n .join(',\\n')}]));\n\n const preview = new PreviewWeb();\n\n window.__STORYBOOK_PREVIEW__ = preview;\n window.__STORYBOOK_STORY_STORE__ = preview.storyStore;\n window.__STORYBOOK_CLIENT_API__ = new ClientApi({ storyStore: preview.storyStore });\n\n preview.initialize({ importFn, getProjectAnnotations });\n\n if (import.meta.hot) {\n import.meta.hot.accept('${virtualStoriesFile}', (newModule) => {\n\n // importFn has changed so we need to patch the new one in\n preview.onStoriesChanged({ importFn: newModule.importFn });\n });\n\n import.meta.hot.accept(${JSON.stringify(configEntries)}, ([...newConfigEntries]) => {\n const newGetProjectAnnotations = () => composeConfigs(newConfigEntries);\n\n // getProjectAnnotations has changed so we need to patch the new one in\n preview.onGetProjectAnnotationsChanged({ getProjectAnnotations: newGetProjectAnnotations });\n });\n }\n `.trim();\n return code;\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function generateAddonSetupCode(): string;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateAddonSetupCode = void 0;
4
+ function generateAddonSetupCode() {
5
+ return `
6
+ import global from 'global';
7
+ import createPostMessageChannel from '@storybook/channel-postmessage';
8
+ import createWebSocketChannel from '@storybook/channel-websocket';
9
+ import { addons } from '@storybook/addons';
10
+
11
+ const channel = createPostMessageChannel({ page: 'preview' });
12
+ addons.setChannel(channel);
13
+ window.__STORYBOOK_ADDONS_CHANNEL__ = channel;
14
+
15
+ const { SERVER_CHANNEL_URL } = global;
16
+ if (SERVER_CHANNEL_URL) {
17
+ const serverChannel = createWebSocketChannel({ url: SERVER_CHANNEL_URL });
18
+ addons.setServerChannel(serverChannel);
19
+ window.__STORYBOOK_SERVER_CHANNEL__ = serverChannel;
20
+ }
21
+ `.trim();
22
+ }
23
+ exports.generateAddonSetupCode = generateAddonSetupCode;
24
+ //# sourceMappingURL=codegen-set-addon-channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen-set-addon-channel.js","sourceRoot":"","sources":["../codegen-set-addon-channel.ts"],"names":[],"mappings":";;;AAAA,SAAgB,sBAAsB;IACpC,OAAO;;;;;;;;;;;;;;;;GAgBN,CAAC,IAAI,EAAE,CAAC;AACX,CAAC;AAlBD,wDAkBC","sourcesContent":["export function generateAddonSetupCode() {\n return `\n import global from 'global';\n import createPostMessageChannel from '@storybook/channel-postmessage';\n import createWebSocketChannel from '@storybook/channel-websocket';\n import { addons } from '@storybook/addons';\n\n const channel = createPostMessageChannel({ page: 'preview' });\n addons.setChannel(channel);\n window.__STORYBOOK_ADDONS_CHANNEL__ = channel;\n\n const { SERVER_CHANNEL_URL } = global;\n if (SERVER_CHANNEL_URL) {\n const serverChannel = createWebSocketChannel({ url: SERVER_CHANNEL_URL });\n addons.setServerChannel(serverChannel);\n window.__STORYBOOK_SERVER_CHANNEL__ = serverChannel;\n }\n `.trim();\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export declare const virtualFileId = "/virtual:/@storybook/builder-vite/vite-app.js";
2
+ export declare const virtualStoriesFile = "/virtual:/@storybook/builder-vite/storybook-stories.js";
3
+ export declare const virtualPreviewFile = "/virtual:/@storybook/builder-vite/preview-entry.js";
4
+ export declare const virtualAddonSetupFile = "/virtual:/@storybook/builder-vite/setup-addons.js";
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.virtualAddonSetupFile = exports.virtualPreviewFile = exports.virtualStoriesFile = exports.virtualFileId = void 0;
4
+ exports.virtualFileId = '/virtual:/@storybook/builder-vite/vite-app.js';
5
+ exports.virtualStoriesFile = '/virtual:/@storybook/builder-vite/storybook-stories.js';
6
+ exports.virtualPreviewFile = '/virtual:/@storybook/builder-vite/preview-entry.js';
7
+ exports.virtualAddonSetupFile = '/virtual:/@storybook/builder-vite/setup-addons.js';
8
+ //# sourceMappingURL=virtual-file-names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtual-file-names.js","sourceRoot":"","sources":["../virtual-file-names.ts"],"names":[],"mappings":";;;AAAa,QAAA,aAAa,GAAG,+CAA+C,CAAC;AAChE,QAAA,kBAAkB,GAAG,wDAAwD,CAAC;AAC9E,QAAA,kBAAkB,GAAG,oDAAoD,CAAC;AAC1E,QAAA,qBAAqB,GAAG,mDAAmD,CAAC","sourcesContent":["export const virtualFileId = '/virtual:/@storybook/builder-vite/vite-app.js';\nexport const virtualStoriesFile = '/virtual:/@storybook/builder-vite/storybook-stories.js';\nexport const virtualPreviewFile = '/virtual:/@storybook/builder-vite/preview-entry.js';\nexport const virtualAddonSetupFile = '/virtual:/@storybook/builder-vite/setup-addons.js';\n"]}
package/input/iframe.html CHANGED
@@ -31,7 +31,6 @@
31
31
  <!-- [BODY HTML SNIPPET HERE] -->
32
32
  <div id="root"></div>
33
33
  <div id="docs-root"></div>
34
-
35
34
  <script type="module" src="/virtual:/@storybook/builder-vite/vite-app.js"></script>
36
35
  </body>
37
36
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/builder-vite",
3
- "version": "0.1.22",
3
+ "version": "0.1.23",
4
4
  "description": "An experimental plugin to run and build Storybooks with Vite",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1,4 @@
1
+ export const virtualFileId = '/virtual:/@storybook/builder-vite/vite-app.js';
2
+ export const virtualStoriesFile = '/virtual:/@storybook/builder-vite/storybook-stories.js';
3
+ export const virtualPreviewFile = '/virtual:/@storybook/builder-vite/preview-entry.js';
4
+ export const virtualAddonSetupFile = '/virtual:/@storybook/builder-vite/setup-addons.js';