@storybook/builder-vite 0.1.24 → 0.1.27

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
@@ -21,6 +21,7 @@ To manually migrate:
21
21
  Requirements:
22
22
 
23
23
  - Vite 2.5 or newer
24
+ - Storybook 6.4.0 or newer (for storybook 6.3, use `storybook-builder-vite@0.1.16`)
24
25
 
25
26
  ```bash
26
27
  npm install @storybook/builder-vite --save-dev
@@ -58,13 +59,18 @@ In `.storybook/main.js` (or whatever your Storybook config file is named)
58
59
  you can override the Vite config:
59
60
 
60
61
  ```javascript
62
+ // use `mergeConfig` to recursively merge Vite options
63
+ const { mergeConfig } = require('vite');
64
+
61
65
  module.exports = {
62
66
  async viteFinal(config, { configType }) {
63
- // customize the Vite config here
64
- config.resolve.alias.foo = 'bar';
65
-
66
67
  // return the customized config
67
- return config;
68
+ return mergeConfig(config, {
69
+ // customize the Vite config here
70
+ resolve: {
71
+ alias: { foo: 'bar' },
72
+ },
73
+ });
68
74
  },
69
75
  // ... other options here
70
76
  };
@@ -15,6 +15,7 @@ import { virtualAddonSetupFile, virtualFileId, virtualPreviewFile, virtualStorie
15
15
  export function codeGeneratorPlugin(options: ExtendedOptions): Plugin {
16
16
  const iframePath = path.resolve(__dirname, '..', 'input', 'iframe.html');
17
17
  let iframeId: string;
18
+ let projRoot: string;
18
19
 
19
20
  // noinspection JSUnusedGlobalSymbols
20
21
  return {
@@ -50,6 +51,7 @@ export function codeGeneratorPlugin(options: ExtendedOptions): Plugin {
50
51
  }
51
52
  },
52
53
  configResolved(config) {
54
+ projRoot = config.root;
53
55
  iframeId = `${config.root}/iframe.html`;
54
56
  },
55
57
  resolveId(source) {
@@ -63,6 +65,14 @@ export function codeGeneratorPlugin(options: ExtendedOptions): Plugin {
63
65
  return virtualPreviewFile;
64
66
  } else if (source === virtualAddonSetupFile) {
65
67
  return virtualAddonSetupFile;
68
+ // Avoid error in react < 18 projects
69
+ } else if (source === 'react-dom/client') {
70
+ try {
71
+ return require.resolve('react-dom/client', { paths: [projRoot] });
72
+ } catch (e) {
73
+ // This is not a react 18 project, need to stub out to avoid error
74
+ return path.resolve(__dirname, '..', 'input', 'react-dom-client-placeholder.js');
75
+ }
66
76
  }
67
77
  },
68
78
  async load(id) {
@@ -9,17 +9,14 @@ const absoluteFilesToImport = (files: string[], name: string) =>
9
9
  files.map((el, i) => `import ${name ? `* as ${name}_${i} from ` : ''}'/@fs/${normalizePath(el)}'`).join('\n');
10
10
 
11
11
  export async function generateVirtualStoryEntryCode(options: ExtendedOptions) {
12
- const { frameworkPath, framework } = options;
13
12
  const storyEntries = await listStories(options);
14
13
  const resolveMap = storyEntries.reduce<Record<string, string>>(
15
14
  (prev, entry) => ({ ...prev, [entry]: entry.replace(slash(process.cwd()), '.') }),
16
15
  {}
17
16
  );
18
17
  const modules = storyEntries.map((entry, i) => `${JSON.stringify(entry)}: story_${i}`).join(',');
19
- const frameworkImportPath = frameworkPath || `@storybook/${framework}`;
20
18
 
21
19
  return `
22
- import { configure } from '${frameworkImportPath}';
23
20
  ${absoluteFilesToImport(storyEntries, 'story')}
24
21
 
25
22
  function loadable(key) {
@@ -31,7 +28,7 @@ export async function generateVirtualStoryEntryCode(options: ExtendedOptions) {
31
28
  resolve: (key) => (${JSON.stringify(resolveMap)}[key])
32
29
  });
33
30
 
34
- export function configStories() {
31
+ export function configStories(configure) {
35
32
  configure(loadable, { hot: import.meta.hot }, false);
36
33
  }
37
34
  `.trim();
@@ -1,16 +1,27 @@
1
+ import path from 'path';
1
2
  import { normalizePath } from 'vite';
2
- import { virtualPreviewFile, virtualStoriesFile, virtualAddonSetupFile } from './virtual-file-names';
3
+ import { virtualPreviewFile, virtualStoriesFile } from './virtual-file-names';
3
4
 
4
5
  import type { ExtendedOptions } from './types';
5
6
 
7
+ // We need to convert from an absolute path, to a traditional node module import path,
8
+ // so that vite can correctly pre-bundle/optimize
9
+ function transformPath(absPath: string) {
10
+ const splits = absPath.split(`node_modules${path.sep}`);
11
+ // Return everything after the final "node_modules/"
12
+ const module = normalizePath(splits[splits.length - 1]);
13
+ return module;
14
+ }
15
+
6
16
  export async function generateIframeScriptCode(options: ExtendedOptions) {
7
- const { presets } = options;
17
+ const { presets, frameworkPath, framework } = options;
18
+ const frameworkImportPath = frameworkPath || `@storybook/${framework}`;
8
19
 
9
20
  const presetEntries = await presets.apply('config', [], options);
10
21
  const configEntries = [...presetEntries].filter(Boolean);
11
22
 
12
23
  const absoluteFilesToImport = (files: string[], name: string) =>
13
- files.map((el, i) => `import ${name ? `* as ${name}_${i} from ` : ''}'/@fs/${normalizePath(el)}'`).join('\n');
24
+ files.map((el, i) => `import ${name ? `* as ${name}_${i} from ` : ''}'${transformPath(el)}'`).join('\n');
14
25
 
15
26
  const importArray = (name: string, length: number) => new Array(length).fill(0).map((_, i) => `${name}_${i}`);
16
27
 
@@ -18,18 +29,21 @@ export async function generateIframeScriptCode(options: ExtendedOptions) {
18
29
  /** @todo Inline variable and remove `noinspection` */
19
30
  // language=JavaScript
20
31
  const code = `
21
- import '${virtualAddonSetupFile}';
32
+ // Ensure that the client API is initialized by the framework before any other iframe code
33
+ // is loaded. That way our client-apis can assume the existence of the API+store
34
+ import { configure } from '${frameworkImportPath}';
35
+
22
36
  import {
23
37
  addDecorator,
24
38
  addParameters,
25
39
  addLoader,
26
40
  addArgTypesEnhancer,
27
- addArgsEnhancer
41
+ addArgsEnhancer,
42
+ setGlobalRender
28
43
  } from '@storybook/client-api';
29
44
  import { logger } from '@storybook/client-logger';
30
45
  ${absoluteFilesToImport(configEntries, 'config')}
31
46
  import * as preview from '${virtualPreviewFile}';
32
- // This import should occur after the config imports above
33
47
  import { configStories } from '${virtualStoriesFile}';
34
48
 
35
49
  const configs = [${importArray('config', configEntries.length).concat('preview.default').join(',')}].filter(Boolean)
@@ -57,6 +71,9 @@ export async function generateIframeScriptCode(options: ExtendedOptions) {
57
71
  case 'argsEnhancers': {
58
72
  return value.forEach((enhancer) => addArgsEnhancer(enhancer))
59
73
  }
74
+ case 'render': {
75
+ return setGlobalRender(value)
76
+ }
60
77
  case 'globals':
61
78
  case 'globalTypes': {
62
79
  const v = {};
@@ -81,7 +98,7 @@ export async function generateIframeScriptCode(options: ExtendedOptions) {
81
98
  }
82
99
  */
83
100
 
84
- configStories();
101
+ configStories(configure);
85
102
  `.trim();
86
103
  return code;
87
104
  }
@@ -32,6 +32,7 @@ const virtual_file_names_1 = require("./virtual-file-names");
32
32
  function codeGeneratorPlugin(options) {
33
33
  const iframePath = path.resolve(__dirname, '..', 'input', 'iframe.html');
34
34
  let iframeId;
35
+ let projRoot;
35
36
  // noinspection JSUnusedGlobalSymbols
36
37
  return {
37
38
  name: 'storybook-vite-code-generator-plugin',
@@ -66,6 +67,7 @@ function codeGeneratorPlugin(options) {
66
67
  }
67
68
  },
68
69
  configResolved(config) {
70
+ projRoot = config.root;
69
71
  iframeId = `${config.root}/iframe.html`;
70
72
  },
71
73
  resolveId(source) {
@@ -83,6 +85,16 @@ function codeGeneratorPlugin(options) {
83
85
  }
84
86
  else if (source === virtual_file_names_1.virtualAddonSetupFile) {
85
87
  return virtual_file_names_1.virtualAddonSetupFile;
88
+ // Avoid error in react < 18 projects
89
+ }
90
+ else if (source === 'react-dom/client') {
91
+ try {
92
+ return require.resolve('react-dom/client', { paths: [projRoot] });
93
+ }
94
+ catch (e) {
95
+ // This is not a react 18 project, need to stub out to avoid error
96
+ return path.resolve(__dirname, '..', 'input', 'react-dom-client-placeholder.js');
97
+ }
86
98
  }
87
99
  },
88
100
  async load(id) {
@@ -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';\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
+ {"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 let projRoot: 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 projRoot = config.root;\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 // Avoid error in react < 18 projects\n } else if (source === 'react-dom/client') {\n try {\n return require.resolve('react-dom/client', { paths: [projRoot] });\n } catch (e) {\n // This is not a react 18 project, need to stub out to avoid error\n return path.resolve(__dirname, '..', 'input', 'react-dom-client-placeholder.js');\n }\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"]}
@@ -10,13 +10,10 @@ const vite_1 = require("vite");
10
10
  const list_stories_1 = require("./list-stories");
11
11
  const absoluteFilesToImport = (files, name) => files.map((el, i) => `import ${name ? `* as ${name}_${i} from ` : ''}'/@fs/${(0, vite_1.normalizePath)(el)}'`).join('\n');
12
12
  async function generateVirtualStoryEntryCode(options) {
13
- const { frameworkPath, framework } = options;
14
13
  const storyEntries = await (0, list_stories_1.listStories)(options);
15
14
  const resolveMap = storyEntries.reduce((prev, entry) => ({ ...prev, [entry]: entry.replace((0, slash_1.default)(process.cwd()), '.') }), {});
16
15
  const modules = storyEntries.map((entry, i) => `${JSON.stringify(entry)}: story_${i}`).join(',');
17
- const frameworkImportPath = frameworkPath || `@storybook/${framework}`;
18
16
  return `
19
- import { configure } from '${frameworkImportPath}';
20
17
  ${absoluteFilesToImport(storyEntries, 'story')}
21
18
 
22
19
  function loadable(key) {
@@ -28,7 +25,7 @@ async function generateVirtualStoryEntryCode(options) {
28
25
  resolve: (key) => (${JSON.stringify(resolveMap)}[key])
29
26
  });
30
27
 
31
- export function configStories() {
28
+ export function configStories(configure) {
32
29
  configure(loadable, { hot: import.meta.hot }, false);
33
30
  }
34
31
  `.trim();
@@ -1 +1 @@
1
- {"version":3,"file":"codegen-entries.js","sourceRoot":"","sources":["../codegen-entries.ts"],"names":[],"mappings":";;;;;;AAAA,wDAAiE;AAEjE,kDAA0B;AAC1B,+BAAqC;AAErC,iDAA6C;AAE7C,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;AAEzG,KAAK,UAAU,6BAA6B,CAAC,OAAwB;IAC1E,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC7C,MAAM,YAAY,GAAG,MAAM,IAAA,0BAAW,EAAC,OAAO,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CACpC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,IAAA,eAAK,EAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,EACjF,EAAE,CACH,CAAC;IACF,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjG,MAAM,mBAAmB,GAAG,aAAa,IAAI,cAAc,SAAS,EAAE,CAAC;IAEvE,OAAO;iCACwB,mBAAmB;MAC9C,qBAAqB,CAAC,YAAY,EAAE,OAAO,CAAC;;;gBAGlC,OAAO;;;;qBAIF,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;2BACjC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;;;;;;GAMlD,CAAC,IAAI,EAAE,CAAC;AACX,CAAC;AA3BD,sEA2BC;AAEM,KAAK,UAAU,wBAAwB,CAAC,EAAE,SAAS,EAAW;IACnE,MAAM,WAAW,GAAG,IAAA,qCAAuB,EAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IAC3D,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,CAAC;IAE5B,OAAO,6BAA6B,IAAA,eAAK,EAAC,WAAW,CAAC;0BAC9B,CAAC;AAC3B,CAAC;AAND,4DAMC","sourcesContent":["import { loadPreviewOrConfigFile } from '@storybook/core-common';\nimport type { Options } from '@storybook/core-common';\nimport slash from 'slash';\nimport { normalizePath } from 'vite';\nimport type { ExtendedOptions } from './types';\nimport { listStories } from './list-stories';\n\nconst absoluteFilesToImport = (files: string[], name: string) =>\n files.map((el, i) => `import ${name ? `* as ${name}_${i} from ` : ''}'/@fs/${normalizePath(el)}'`).join('\\n');\n\nexport async function generateVirtualStoryEntryCode(options: ExtendedOptions) {\n const { frameworkPath, framework } = options;\n const storyEntries = await listStories(options);\n const resolveMap = storyEntries.reduce<Record<string, string>>(\n (prev, entry) => ({ ...prev, [entry]: entry.replace(slash(process.cwd()), '.') }),\n {}\n );\n const modules = storyEntries.map((entry, i) => `${JSON.stringify(entry)}: story_${i}`).join(',');\n const frameworkImportPath = frameworkPath || `@storybook/${framework}`;\n\n return `\n import { configure } from '${frameworkImportPath}';\n ${absoluteFilesToImport(storyEntries, 'story')}\n\n function loadable(key) {\n return {${modules}}[key];\n }\n \n Object.assign(loadable, {\n keys: () => (${JSON.stringify(Object.keys(resolveMap))}),\n resolve: (key) => (${JSON.stringify(resolveMap)}[key])\n });\n\n export function configStories() {\n configure(loadable, { hot: import.meta.hot }, false);\n }\n `.trim();\n}\n\nexport async function generatePreviewEntryCode({ configDir }: Options) {\n const previewFile = loadPreviewOrConfigFile({ configDir });\n if (!previewFile) return '';\n\n return `import * as preview from '${slash(previewFile)}';\n export default preview;`;\n}\n"]}
1
+ {"version":3,"file":"codegen-entries.js","sourceRoot":"","sources":["../codegen-entries.ts"],"names":[],"mappings":";;;;;;AAAA,wDAAiE;AAEjE,kDAA0B;AAC1B,+BAAqC;AAErC,iDAA6C;AAE7C,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;AAEzG,KAAK,UAAU,6BAA6B,CAAC,OAAwB;IAC1E,MAAM,YAAY,GAAG,MAAM,IAAA,0BAAW,EAAC,OAAO,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CACpC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,IAAA,eAAK,EAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,EACjF,EAAE,CACH,CAAC;IACF,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEjG,OAAO;MACH,qBAAqB,CAAC,YAAY,EAAE,OAAO,CAAC;;;gBAGlC,OAAO;;;;qBAIF,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;2BACjC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;;;;;;GAMlD,CAAC,IAAI,EAAE,CAAC;AACX,CAAC;AAxBD,sEAwBC;AAEM,KAAK,UAAU,wBAAwB,CAAC,EAAE,SAAS,EAAW;IACnE,MAAM,WAAW,GAAG,IAAA,qCAAuB,EAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IAC3D,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,CAAC;IAE5B,OAAO,6BAA6B,IAAA,eAAK,EAAC,WAAW,CAAC;0BAC9B,CAAC;AAC3B,CAAC;AAND,4DAMC","sourcesContent":["import { loadPreviewOrConfigFile } from '@storybook/core-common';\nimport type { Options } from '@storybook/core-common';\nimport slash from 'slash';\nimport { normalizePath } from 'vite';\nimport type { ExtendedOptions } from './types';\nimport { listStories } from './list-stories';\n\nconst absoluteFilesToImport = (files: string[], name: string) =>\n files.map((el, i) => `import ${name ? `* as ${name}_${i} from ` : ''}'/@fs/${normalizePath(el)}'`).join('\\n');\n\nexport async function generateVirtualStoryEntryCode(options: ExtendedOptions) {\n const storyEntries = await listStories(options);\n const resolveMap = storyEntries.reduce<Record<string, string>>(\n (prev, entry) => ({ ...prev, [entry]: entry.replace(slash(process.cwd()), '.') }),\n {}\n );\n const modules = storyEntries.map((entry, i) => `${JSON.stringify(entry)}: story_${i}`).join(',');\n\n return `\n ${absoluteFilesToImport(storyEntries, 'story')}\n\n function loadable(key) {\n return {${modules}}[key];\n }\n \n Object.assign(loadable, {\n keys: () => (${JSON.stringify(Object.keys(resolveMap))}),\n resolve: (key) => (${JSON.stringify(resolveMap)}[key])\n });\n\n export function configStories(configure) {\n configure(loadable, { hot: import.meta.hot }, false);\n }\n `.trim();\n}\n\nexport async function generatePreviewEntryCode({ configDir }: Options) {\n const previewFile = loadPreviewOrConfigFile({ configDir });\n if (!previewFile) return '';\n\n return `import * as preview from '${slash(previewFile)}';\n export default preview;`;\n}\n"]}
@@ -1,30 +1,46 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.generateIframeScriptCode = void 0;
7
+ const path_1 = __importDefault(require("path"));
4
8
  const vite_1 = require("vite");
5
9
  const virtual_file_names_1 = require("./virtual-file-names");
10
+ // We need to convert from an absolute path, to a traditional node module import path,
11
+ // so that vite can correctly pre-bundle/optimize
12
+ function transformPath(absPath) {
13
+ const splits = absPath.split(`node_modules${path_1.default.sep}`);
14
+ // Return everything after the final "node_modules/"
15
+ const module = (0, vite_1.normalizePath)(splits[splits.length - 1]);
16
+ return module;
17
+ }
6
18
  async function generateIframeScriptCode(options) {
7
- const { presets } = options;
19
+ const { presets, frameworkPath, framework } = options;
20
+ const frameworkImportPath = frameworkPath || `@storybook/${framework}`;
8
21
  const presetEntries = await presets.apply('config', [], options);
9
22
  const configEntries = [...presetEntries].filter(Boolean);
10
- const absoluteFilesToImport = (files, name) => files.map((el, i) => `import ${name ? `* as ${name}_${i} from ` : ''}'/@fs/${(0, vite_1.normalizePath)(el)}'`).join('\n');
23
+ const absoluteFilesToImport = (files, name) => files.map((el, i) => `import ${name ? `* as ${name}_${i} from ` : ''}'${transformPath(el)}'`).join('\n');
11
24
  const importArray = (name, length) => new Array(length).fill(0).map((_, i) => `${name}_${i}`);
12
25
  // noinspection UnnecessaryLocalVariableJS
13
26
  /** @todo Inline variable and remove `noinspection` */
14
27
  // language=JavaScript
15
28
  const code = `
16
- import '${virtual_file_names_1.virtualAddonSetupFile}';
29
+ // Ensure that the client API is initialized by the framework before any other iframe code
30
+ // is loaded. That way our client-apis can assume the existence of the API+store
31
+ import { configure } from '${frameworkImportPath}';
32
+
17
33
  import {
18
34
  addDecorator,
19
35
  addParameters,
20
36
  addLoader,
21
37
  addArgTypesEnhancer,
22
- addArgsEnhancer
38
+ addArgsEnhancer,
39
+ setGlobalRender
23
40
  } from '@storybook/client-api';
24
41
  import { logger } from '@storybook/client-logger';
25
42
  ${absoluteFilesToImport(configEntries, 'config')}
26
43
  import * as preview from '${virtual_file_names_1.virtualPreviewFile}';
27
- // This import should occur after the config imports above
28
44
  import { configStories } from '${virtual_file_names_1.virtualStoriesFile}';
29
45
 
30
46
  const configs = [${importArray('config', configEntries.length).concat('preview.default').join(',')}].filter(Boolean)
@@ -52,6 +68,9 @@ async function generateIframeScriptCode(options) {
52
68
  case 'argsEnhancers': {
53
69
  return value.forEach((enhancer) => addArgsEnhancer(enhancer))
54
70
  }
71
+ case 'render': {
72
+ return setGlobalRender(value)
73
+ }
55
74
  case 'globals':
56
75
  case 'globalTypes': {
57
76
  const v = {};
@@ -76,7 +95,7 @@ async function generateIframeScriptCode(options) {
76
95
  }
77
96
  */
78
97
 
79
- configStories();
98
+ configStories(configure);
80
99
  `.trim();
81
100
  return code;
82
101
  }
@@ -1 +1 @@
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
+ {"version":3,"file":"codegen-iframe-script.js","sourceRoot":"","sources":["../codegen-iframe-script.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AACxB,+BAAqC;AACrC,6DAA8E;AAI9E,sFAAsF;AACtF,iDAAiD;AACjD,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,cAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACxD,oDAAoD;IACpD,MAAM,MAAM,GAAG,IAAA,oBAAa,EAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IACxD,OAAO,MAAM,CAAC;AAChB,CAAC;AAEM,KAAK,UAAU,wBAAwB,CAAC,OAAwB;IACrE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACtD,MAAM,mBAAmB,GAAG,aAAa,IAAI,cAAc,SAAS,EAAE,CAAC;IAEvE,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,IAAI,aAAa,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE3G,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;;;iCAGkB,mBAAmB;;;;;;;;;;;MAW9C,qBAAqB,CAAC,aAAa,EAAE,QAAQ,CAAC;gCACpB,uCAAkB;qCACb,uCAAkB;;uBAEhC,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqDjG,CAAC,IAAI,EAAE,CAAC;IACX,OAAO,IAAI,CAAC;AACd,CAAC;AAxFD,4DAwFC","sourcesContent":["import path from 'path';\nimport { normalizePath } from 'vite';\nimport { virtualPreviewFile, virtualStoriesFile } from './virtual-file-names';\n\nimport type { ExtendedOptions } from './types';\n\n// We need to convert from an absolute path, to a traditional node module import path,\n// so that vite can correctly pre-bundle/optimize\nfunction transformPath(absPath: string) {\n const splits = absPath.split(`node_modules${path.sep}`);\n // Return everything after the final \"node_modules/\"\n const module = normalizePath(splits[splits.length - 1]);\n return module;\n}\n\nexport async function generateIframeScriptCode(options: ExtendedOptions) {\n const { presets, frameworkPath, framework } = options;\n const frameworkImportPath = frameworkPath || `@storybook/${framework}`;\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 ` : ''}'${transformPath(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 // Ensure that the client API is initialized by the framework before any other iframe code\n // is loaded. That way our client-apis can assume the existence of the API+store\n import { configure } from '${frameworkImportPath}';\n\n import {\n addDecorator,\n addParameters,\n addLoader,\n addArgTypesEnhancer,\n addArgsEnhancer,\n setGlobalRender\n } from '@storybook/client-api';\n import { logger } from '@storybook/client-logger';\n ${absoluteFilesToImport(configEntries, 'config')}\n import * as preview from '${virtualPreviewFile}';\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 'render': {\n return setGlobalRender(value)\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(configure);\n `.trim();\n return code;\n}\n"]}
@@ -1,2 +1,2 @@
1
1
  import type { Options } from '@storybook/core-common';
2
- export declare function listStories({ presets, configDir }: Options): Promise<string[]>;
2
+ export declare function listStories(options: Options): Promise<string[]>;
@@ -22,14 +22,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
22
22
  exports.listStories = void 0;
23
23
  const path = __importStar(require("path"));
24
24
  const glob_promise_1 = require("glob-promise");
25
- // TODO: Merge with https://github.com/storybookjs/builder-vite/pull/182
26
- async function listStories({ presets, configDir }) {
27
- return (await Promise.all((await presets.apply('stories')).map((storiesEntry) => {
28
- const files = typeof storiesEntry === 'string' ? storiesEntry : storiesEntry.files;
29
- if (!files) {
30
- return [];
31
- }
32
- return (0, glob_promise_1.promise)(path.isAbsolute(files) ? files : path.join(configDir, files));
25
+ const core_common_1 = require("@storybook/core-common");
26
+ async function listStories(options) {
27
+ return (await Promise.all((0, core_common_1.normalizeStories)(await options.presets.apply('stories', [], options), {
28
+ configDir: options.configDir,
29
+ workingDir: options.configDir,
30
+ }).map(({ directory, files }) => {
31
+ const pattern = path.join(directory, files);
32
+ return (0, glob_promise_1.promise)(path.isAbsolute(pattern) ? pattern : path.join(options.configDir, pattern));
33
33
  }))).reduce((carry, stories) => carry.concat(stories), []);
34
34
  }
35
35
  exports.listStories = listStories;
@@ -1 +1 @@
1
- {"version":3,"file":"list-stories.js","sourceRoot":"","sources":["../list-stories.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAC7B,+CAA+C;AAI/C,wEAAwE;AACjE,KAAK,UAAU,WAAW,CAAC,EAAE,OAAO,EAAE,SAAS,EAAW;IAC/D,OAAO,CACL,MAAM,OAAO,CAAC,GAAG,CACf,CACE,MAAM,OAAO,CAAC,KAAK,CAA0B,SAAS,CAAC,CACxD,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE;QACrB,MAAM,KAAK,GAAG,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC;QACnF,IAAI,CAAC,KAAK,EAAE;YACV,OAAO,EAAc,CAAC;SACvB;QACD,OAAO,IAAA,sBAAI,EAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;IAC5E,CAAC,CAAC,CACH,CACF,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC;AAdD,kCAcC","sourcesContent":["import * as path from 'path';\nimport { promise as glob } from 'glob-promise';\n\nimport type { Options, StoriesEntry } from '@storybook/core-common';\n\n// TODO: Merge with https://github.com/storybookjs/builder-vite/pull/182\nexport async function listStories({ presets, configDir }: Options) {\n return (\n await Promise.all(\n (\n await presets.apply<Promise<StoriesEntry[]>>('stories')\n ).map((storiesEntry) => {\n const files = typeof storiesEntry === 'string' ? storiesEntry : storiesEntry.files;\n if (!files) {\n return [] as string[];\n }\n return glob(path.isAbsolute(files) ? files : path.join(configDir, files));\n })\n )\n ).reduce((carry, stories) => carry.concat(stories), []);\n}\n"]}
1
+ {"version":3,"file":"list-stories.js","sourceRoot":"","sources":["../list-stories.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAC7B,+CAA+C;AAC/C,wDAA0D;AAInD,KAAK,UAAU,WAAW,CAAC,OAAgB;IAChD,OAAO,CACL,MAAM,OAAO,CAAC,GAAG,CACf,IAAA,8BAAgB,EAAC,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE;QACpE,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,UAAU,EAAE,OAAO,CAAC,SAAS;KAC9B,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAE5C,OAAO,IAAA,sBAAI,EAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1F,CAAC,CAAC,CACH,CACF,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC;AAbD,kCAaC","sourcesContent":["import * as path from 'path';\nimport { promise as glob } from 'glob-promise';\nimport { normalizeStories } from '@storybook/core-common';\n\nimport type { Options } from '@storybook/core-common';\n\nexport async function listStories(options: Options) {\n return (\n await Promise.all(\n normalizeStories(await options.presets.apply('stories', [], options), {\n configDir: options.configDir,\n workingDir: options.configDir,\n }).map(({ directory, files }) => {\n const pattern = path.join(directory, files);\n\n return glob(path.isAbsolute(pattern) ? pattern : path.join(options.configDir, pattern));\n })\n )\n ).reduce((carry, stories) => carry.concat(stories), []);\n}\n"]}
@@ -6,4 +6,5 @@ export declare function getOptimizeDeps(config: UserConfig & {
6
6
  }, options: ExtendedOptions): Promise<{
7
7
  entries: string[];
8
8
  include: string[];
9
+ exclude: string[];
9
10
  }>;
@@ -82,6 +82,7 @@ const INCLUDE_CANDIDATES = [
82
82
  'prop-types',
83
83
  'qs',
84
84
  'react-dom',
85
+ 'react-dom/client',
85
86
  'react-fast-compare',
86
87
  'react-is',
87
88
  'react-textarea-autosize',
@@ -120,6 +121,17 @@ async function getOptimizeDeps(config, options) {
120
121
  const absoluteStories = await (0, list_stories_1.listStories)(options);
121
122
  const stories = absoluteStories.map((storyPath) => (0, vite_1.normalizePath)(path.relative(root, storyPath)));
122
123
  const resolvedConfig = await (0, vite_1.resolveConfig)(config, 'serve', 'development');
124
+ const exclude = [];
125
+ // This is necessary to support react < 18 with new versions of @storybook/react that support react 18.
126
+ // TODO: narrow this down to just framework === 'react'. But causes a vue dev start problem in this monorepo.
127
+ try {
128
+ require.resolve('react-dom/client', { paths: [config.root] });
129
+ }
130
+ catch (e) {
131
+ if (isNodeError(e) && e.code === 'MODULE_NOT_FOUND') {
132
+ exclude.push('react-dom/client');
133
+ }
134
+ }
123
135
  // This function converts ids which might include ` > ` to a real path, if it exists on disk.
124
136
  // See https://github.com/vitejs/vite/blob/67d164392e8e9081dc3f0338c4b4b8eea6c5f7da/packages/vite/src/node/optimizer/index.ts#L182-L199
125
137
  const resolve = resolvedConfig.createResolver({ asSrc: false });
@@ -130,7 +142,11 @@ async function getOptimizeDeps(config, options) {
130
142
  // We need Vite to precompile these dependencies, because they contain non-ESM code that would break
131
143
  // if we served it directly to the browser.
132
144
  include,
145
+ // In some cases we need to prevent deps from being pre-bundled
146
+ exclude,
133
147
  };
134
148
  }
135
149
  exports.getOptimizeDeps = getOptimizeDeps;
150
+ // Refines an error received from 'catch' to be a NodeJS exception
151
+ const isNodeError = (error) => error instanceof Error;
136
152
  //# sourceMappingURL=optimizeDeps.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"optimizeDeps.js","sourceRoot":"","sources":["../optimizeDeps.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\nimport { normalizePath, resolveConfig, UserConfig } from 'vite';\nimport { listStories } from './list-stories';\n\nimport type { ExtendedOptions } from './types';\n\nconst INCLUDE_CANDIDATES = [\n '@base2/pretty-print-object',\n '@emotion/core',\n '@emotion/is-prop-valid',\n '@emotion/styled',\n '@mdx-js/react',\n '@storybook/addon-docs > acorn-jsx',\n '@storybook/addon-docs',\n '@storybook/addons',\n '@storybook/channel-postmessage',\n '@storybook/channel-websocket',\n '@storybook/client-api',\n '@storybook/client-logger',\n '@storybook/core/client',\n '@storybook/csf',\n '@storybook/preview-web',\n '@storybook/react > acorn-jsx',\n '@storybook/react',\n '@storybook/svelte',\n '@storybook/vue3',\n 'acorn-jsx',\n 'acorn-walk',\n 'acorn',\n 'airbnb-js-shims',\n 'ansi-to-html',\n 'axe-core',\n 'color-convert',\n 'deep-object-diff',\n 'doctrine',\n 'emotion-theming',\n 'escodegen',\n 'estraverse',\n 'fast-deep-equal',\n 'global',\n 'html-tags',\n 'isobject',\n 'jest-mock',\n 'loader-utils',\n 'lodash/cloneDeep',\n 'lodash/isFunction',\n 'lodash/isPlainObject',\n 'lodash/isString',\n 'lodash/mapKeys',\n 'lodash/mapValues',\n 'lodash/pick',\n 'lodash/pickBy',\n 'lodash/startCase',\n 'lodash/throttle',\n 'lodash/uniq',\n 'markdown-to-jsx',\n 'memoizerific',\n 'overlayscrollbars',\n 'polished',\n 'prettier/parser-babel',\n 'prettier/parser-flow',\n 'prettier/parser-typescript',\n 'prop-types',\n 'qs',\n 'react-dom',\n 'react-fast-compare',\n 'react-is',\n 'react-textarea-autosize',\n 'react',\n 'refractor/core',\n 'refractor/lang/bash.js',\n 'refractor/lang/css.js',\n 'refractor/lang/graphql.js',\n 'refractor/lang/js-extras.js',\n 'refractor/lang/json.js',\n 'refractor/lang/jsx.js',\n 'refractor/lang/markdown.js',\n 'refractor/lang/markup.js',\n 'refractor/lang/tsx.js',\n 'refractor/lang/typescript.js',\n 'refractor/lang/yaml.js',\n 'regenerator-runtime/runtime.js',\n 'slash',\n 'stable',\n 'store2',\n 'synchronous-promise',\n 'telejson',\n 'ts-dedent',\n 'unfetch',\n 'util-deprecate',\n 'uuid-browser/v4',\n 'vue',\n 'warning',\n];\n\n/**\n * Helper function which allows us to `filter` with an async predicate. Uses Promise.all for performance.\n */\nconst asyncFilter = async (arr: string[], predicate: (val: string) => Promise<boolean>) =>\n Promise.all(arr.map(predicate)).then((results) => arr.filter((_v, index) => results[index]));\n\nexport async function getOptimizeDeps(\n config: UserConfig & { configFile: false; root: string },\n options: ExtendedOptions\n) {\n const { root } = config;\n const absoluteStories = await listStories(options);\n const stories = absoluteStories.map((storyPath) => normalizePath(path.relative(root, storyPath)));\n const resolvedConfig = await resolveConfig(config, 'serve', 'development');\n\n // This function converts ids which might include ` > ` to a real path, if it exists on disk.\n // See https://github.com/vitejs/vite/blob/67d164392e8e9081dc3f0338c4b4b8eea6c5f7da/packages/vite/src/node/optimizer/index.ts#L182-L199\n const resolve = resolvedConfig.createResolver({ asSrc: false });\n const include = await asyncFilter(INCLUDE_CANDIDATES, async (id) => Boolean(await resolve(id)));\n\n return {\n // We don't need to resolve the glob since vite supports globs for entries.\n entries: stories,\n // We need Vite to precompile these dependencies, because they contain non-ESM code that would break\n // if we served it directly to the browser.\n include,\n };\n}\n"]}
1
+ {"version":3,"file":"optimizeDeps.js","sourceRoot":"","sources":["../optimizeDeps.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\nimport { normalizePath, resolveConfig, UserConfig } from 'vite';\nimport { listStories } from './list-stories';\n\nimport type { ExtendedOptions } from './types';\n\nconst INCLUDE_CANDIDATES = [\n '@base2/pretty-print-object',\n '@emotion/core',\n '@emotion/is-prop-valid',\n '@emotion/styled',\n '@mdx-js/react',\n '@storybook/addon-docs > acorn-jsx',\n '@storybook/addon-docs',\n '@storybook/addons',\n '@storybook/channel-postmessage',\n '@storybook/channel-websocket',\n '@storybook/client-api',\n '@storybook/client-logger',\n '@storybook/core/client',\n '@storybook/csf',\n '@storybook/preview-web',\n '@storybook/react > acorn-jsx',\n '@storybook/react',\n '@storybook/svelte',\n '@storybook/vue3',\n 'acorn-jsx',\n 'acorn-walk',\n 'acorn',\n 'airbnb-js-shims',\n 'ansi-to-html',\n 'axe-core',\n 'color-convert',\n 'deep-object-diff',\n 'doctrine',\n 'emotion-theming',\n 'escodegen',\n 'estraverse',\n 'fast-deep-equal',\n 'global',\n 'html-tags',\n 'isobject',\n 'jest-mock',\n 'loader-utils',\n 'lodash/cloneDeep',\n 'lodash/isFunction',\n 'lodash/isPlainObject',\n 'lodash/isString',\n 'lodash/mapKeys',\n 'lodash/mapValues',\n 'lodash/pick',\n 'lodash/pickBy',\n 'lodash/startCase',\n 'lodash/throttle',\n 'lodash/uniq',\n 'markdown-to-jsx',\n 'memoizerific',\n 'overlayscrollbars',\n 'polished',\n 'prettier/parser-babel',\n 'prettier/parser-flow',\n 'prettier/parser-typescript',\n 'prop-types',\n 'qs',\n 'react-dom',\n 'react-dom/client',\n 'react-fast-compare',\n 'react-is',\n 'react-textarea-autosize',\n 'react',\n 'refractor/core',\n 'refractor/lang/bash.js',\n 'refractor/lang/css.js',\n 'refractor/lang/graphql.js',\n 'refractor/lang/js-extras.js',\n 'refractor/lang/json.js',\n 'refractor/lang/jsx.js',\n 'refractor/lang/markdown.js',\n 'refractor/lang/markup.js',\n 'refractor/lang/tsx.js',\n 'refractor/lang/typescript.js',\n 'refractor/lang/yaml.js',\n 'regenerator-runtime/runtime.js',\n 'slash',\n 'stable',\n 'store2',\n 'synchronous-promise',\n 'telejson',\n 'ts-dedent',\n 'unfetch',\n 'util-deprecate',\n 'uuid-browser/v4',\n 'vue',\n 'warning',\n];\n\n/**\n * Helper function which allows us to `filter` with an async predicate. Uses Promise.all for performance.\n */\nconst asyncFilter = async (arr: string[], predicate: (val: string) => Promise<boolean>) =>\n Promise.all(arr.map(predicate)).then((results) => arr.filter((_v, index) => results[index]));\n\nexport async function getOptimizeDeps(\n config: UserConfig & { configFile: false; root: string },\n options: ExtendedOptions\n) {\n const { root } = config;\n const absoluteStories = await listStories(options);\n const stories = absoluteStories.map((storyPath) => normalizePath(path.relative(root, storyPath)));\n const resolvedConfig = await resolveConfig(config, 'serve', 'development');\n\n const exclude = [];\n // This is necessary to support react < 18 with new versions of @storybook/react that support react 18.\n // TODO: narrow this down to just framework === 'react'. But causes a vue dev start problem in this monorepo.\n try {\n require.resolve('react-dom/client', { paths: [config.root] });\n } catch (e) {\n if (isNodeError(e) && e.code === 'MODULE_NOT_FOUND') {\n exclude.push('react-dom/client');\n }\n }\n\n // This function converts ids which might include ` > ` to a real path, if it exists on disk.\n // See https://github.com/vitejs/vite/blob/67d164392e8e9081dc3f0338c4b4b8eea6c5f7da/packages/vite/src/node/optimizer/index.ts#L182-L199\n const resolve = resolvedConfig.createResolver({ asSrc: false });\n const include = await asyncFilter(INCLUDE_CANDIDATES, async (id) => Boolean(await resolve(id)));\n\n return {\n // We don't need to resolve the glob since vite supports globs for entries.\n entries: stories,\n // We need Vite to precompile these dependencies, because they contain non-ESM code that would break\n // if we served it directly to the browser.\n include,\n // In some cases we need to prevent deps from being pre-bundled\n exclude,\n };\n}\n\n// Refines an error received from 'catch' to be a NodeJS exception\nconst isNodeError = (error: unknown): error is NodeJS.ErrnoException => error instanceof Error;\n"]}
@@ -2,6 +2,7 @@ import { Plugin } from 'vite';
2
2
  import type { UserConfig } from 'vite';
3
3
  import type { ExtendedOptions } from './types';
4
4
  export declare type PluginConfigType = 'build' | 'development';
5
+ export declare function readPackageJson(): Record<string, any> | false;
5
6
  export declare function commonConfig(options: ExtendedOptions, _type: PluginConfigType): Promise<UserConfig & {
6
7
  configFile: false;
7
8
  root: string;
@@ -18,15 +18,28 @@ var __importStar = (this && this.__importStar) || function (mod) {
18
18
  __setModuleDefault(result, mod);
19
19
  return result;
20
20
  };
21
+ var __importDefault = (this && this.__importDefault) || function (mod) {
22
+ return (mod && mod.__esModule) ? mod : { "default": mod };
23
+ };
21
24
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.pluginConfig = exports.commonConfig = void 0;
25
+ exports.pluginConfig = exports.commonConfig = exports.readPackageJson = void 0;
23
26
  const path = __importStar(require("path"));
27
+ const fs_1 = __importDefault(require("fs"));
24
28
  const envs_1 = require("./envs");
25
29
  const mock_core_js_1 = require("./mock-core-js");
26
30
  const code_generator_plugin_1 = require("./code-generator-plugin");
27
31
  const inject_export_order_plugin_1 = require("./inject-export-order-plugin");
28
32
  const mdx_plugin_1 = require("./mdx-plugin");
29
33
  const source_loader_plugin_1 = require("./source-loader-plugin");
34
+ function readPackageJson() {
35
+ const packageJsonPath = path.resolve('package.json');
36
+ if (!fs_1.default.existsSync(packageJsonPath)) {
37
+ return false;
38
+ }
39
+ const jsonContent = fs_1.default.readFileSync(packageJsonPath, 'utf8');
40
+ return JSON.parse(jsonContent);
41
+ }
42
+ exports.readPackageJson = readPackageJson;
30
43
  // Vite config that is common to development and production mode
31
44
  async function commonConfig(options, _type) {
32
45
  const { framework } = options;
@@ -48,6 +61,7 @@ async function commonConfig(options, _type) {
48
61
  }
49
62
  exports.commonConfig = commonConfig;
50
63
  async function pluginConfig(options, _type) {
64
+ var _a, _b;
51
65
  const { framework, presets } = options;
52
66
  const svelteOptions = await presets.apply('svelteOptions', {}, options);
53
67
  const plugins = [
@@ -106,8 +120,8 @@ async function pluginConfig(options, _type) {
106
120
  const { reactDocgen, reactDocgenTypescriptOptions } = await presets.apply('typescript', {});
107
121
  let typescriptPresent;
108
122
  try {
109
- require.resolve('typescript');
110
- typescriptPresent = true;
123
+ const pkgJson = readPackageJson();
124
+ typescriptPresent = pkgJson && (((_a = pkgJson === null || pkgJson === void 0 ? void 0 : pkgJson.devDependencies) === null || _a === void 0 ? void 0 : _a.typescript) || ((_b = pkgJson === null || pkgJson === void 0 ? void 0 : pkgJson.dependencies) === null || _b === void 0 ? void 0 : _b.typescript));
111
125
  }
112
126
  catch (e) {
113
127
  typescriptPresent = false;
@@ -1 +1 @@
1
- {"version":3,"file":"vite-config.js","sourceRoot":"","sources":["../vite-config.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\nimport { Plugin } from 'vite';\nimport { allowedEnvPrefix as envPrefix } from './envs';\nimport { TypescriptConfig } from '@storybook/core-common';\nimport { mockCoreJs } from './mock-core-js';\nimport { codeGeneratorPlugin } from './code-generator-plugin';\nimport { injectExportOrderPlugin } from './inject-export-order-plugin';\nimport { mdxPlugin } from './mdx-plugin';\nimport { sourceLoaderPlugin } from './source-loader-plugin';\n\nimport type { UserConfig } from 'vite';\nimport type { ExtendedOptions } from './types';\n\nexport type PluginConfigType = 'build' | 'development';\n\n// Vite config that is common to development and production mode\nexport async function commonConfig(\n options: ExtendedOptions,\n _type: PluginConfigType\n): Promise<UserConfig & { configFile: false; root: string }> {\n const { framework } = options;\n\n return {\n configFile: false,\n root: path.resolve(options.configDir, '..'),\n cacheDir: 'node_modules/.vite-storybook',\n envPrefix,\n define: {},\n resolve:\n framework === 'vue3'\n ? {\n alias: {\n vue: 'vue/dist/vue.esm-bundler.js',\n },\n }\n : {},\n plugins: await pluginConfig(options, _type),\n };\n}\n\nexport async function pluginConfig(options: ExtendedOptions, _type: PluginConfigType) {\n const { framework, presets } = options;\n const svelteOptions = await presets.apply('svelteOptions', {}, options);\n\n const plugins = [\n codeGeneratorPlugin(options),\n mockCoreJs(),\n sourceLoaderPlugin(),\n mdxPlugin(),\n injectExportOrderPlugin,\n ] as Plugin[];\n if (framework === 'vue' || framework === 'vue3') {\n try {\n const vuePlugin = require('@vitejs/plugin-vue');\n plugins.push(vuePlugin());\n const { vueDocgen } = await import('./plugins/vue-docgen');\n plugins.push(vueDocgen());\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'MODULE_NOT_FOUND') {\n throw new Error(\n '@storybook/builder-vite requires @vitejs/plugin-vue to be installed ' +\n 'when using @storybook/vue or @storybook/vue3.' +\n ' Please install it and start storybook again.'\n );\n }\n throw err;\n }\n }\n if (framework === 'svelte') {\n try {\n const sveltePlugin = require('@sveltejs/vite-plugin-svelte').svelte;\n plugins.push(sveltePlugin(svelteOptions));\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'MODULE_NOT_FOUND') {\n throw new Error(\n '@storybook/builder-vite requires @sveltejs/vite-plugin-svelte to be installed' +\n ' when using @storybook/svelte.' +\n ' Please install it and start storybook again.'\n );\n }\n throw err;\n }\n\n try {\n const csfPlugin = require('./svelte/csf-plugin').default;\n plugins.push(csfPlugin(svelteOptions));\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'MODULE_NOT_FOUND') {\n throw new Error(\n '@storybook/builder-vite requires @storybook/addon-svelte-csf to be installed when using @storybook/svelte.' +\n ' Please install it and start storybook again.'\n );\n }\n throw err;\n }\n }\n\n if (framework === 'react') {\n plugins.push(\n require('@vitejs/plugin-react')({\n // Do not treat story files as HMR boundaries, storybook itself needs to handle them.\n exclude: [/\\.stories\\.([tj])sx?$/, /node_modules/],\n })\n );\n\n const { reactDocgen, reactDocgenTypescriptOptions } = await presets.apply('typescript', {} as TypescriptConfig);\n\n let typescriptPresent;\n\n try {\n require.resolve('typescript');\n typescriptPresent = true;\n } catch (e) {\n typescriptPresent = false;\n }\n\n if (reactDocgen === 'react-docgen-typescript' && typescriptPresent) {\n plugins.push(require('@joshwooding/vite-plugin-react-docgen-typescript').default(reactDocgenTypescriptOptions));\n } else if (reactDocgen) {\n const { reactDocgen } = await import('./plugins/react-docgen');\n // Needs to run before the react plugin, so add to the front\n plugins.unshift(reactDocgen());\n }\n }\n\n if (framework === 'glimmerx') {\n const plugin = require('vite-plugin-glimmerx/index.cjs');\n plugins.push(plugin.default());\n }\n\n return plugins;\n}\n"]}
1
+ {"version":3,"file":"vite-config.js","sourceRoot":"","sources":["../vite-config.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\nimport fs from 'fs';\nimport { Plugin } from 'vite';\nimport { allowedEnvPrefix as envPrefix } from './envs';\nimport { TypescriptConfig } from '@storybook/core-common';\nimport { mockCoreJs } from './mock-core-js';\nimport { codeGeneratorPlugin } from './code-generator-plugin';\nimport { injectExportOrderPlugin } from './inject-export-order-plugin';\nimport { mdxPlugin } from './mdx-plugin';\nimport { sourceLoaderPlugin } from './source-loader-plugin';\n\nimport type { UserConfig } from 'vite';\nimport type { ExtendedOptions } from './types';\n\nexport type PluginConfigType = 'build' | 'development';\n\nexport function readPackageJson(): Record<string, any> | false {\n const packageJsonPath = path.resolve('package.json');\n if (!fs.existsSync(packageJsonPath)) {\n return false;\n }\n\n const jsonContent = fs.readFileSync(packageJsonPath, 'utf8');\n return JSON.parse(jsonContent);\n}\n\n// Vite config that is common to development and production mode\nexport async function commonConfig(\n options: ExtendedOptions,\n _type: PluginConfigType\n): Promise<UserConfig & { configFile: false; root: string }> {\n const { framework } = options;\n\n return {\n configFile: false,\n root: path.resolve(options.configDir, '..'),\n cacheDir: 'node_modules/.vite-storybook',\n envPrefix,\n define: {},\n resolve:\n framework === 'vue3'\n ? {\n alias: {\n vue: 'vue/dist/vue.esm-bundler.js',\n },\n }\n : {},\n plugins: await pluginConfig(options, _type),\n };\n}\n\nexport async function pluginConfig(options: ExtendedOptions, _type: PluginConfigType) {\n const { framework, presets } = options;\n const svelteOptions = await presets.apply('svelteOptions', {}, options);\n\n const plugins = [\n codeGeneratorPlugin(options),\n mockCoreJs(),\n sourceLoaderPlugin(),\n mdxPlugin(),\n injectExportOrderPlugin,\n ] as Plugin[];\n if (framework === 'vue' || framework === 'vue3') {\n try {\n const vuePlugin = require('@vitejs/plugin-vue');\n plugins.push(vuePlugin());\n const { vueDocgen } = await import('./plugins/vue-docgen');\n plugins.push(vueDocgen());\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'MODULE_NOT_FOUND') {\n throw new Error(\n '@storybook/builder-vite requires @vitejs/plugin-vue to be installed ' +\n 'when using @storybook/vue or @storybook/vue3.' +\n ' Please install it and start storybook again.'\n );\n }\n throw err;\n }\n }\n if (framework === 'svelte') {\n try {\n const sveltePlugin = require('@sveltejs/vite-plugin-svelte').svelte;\n plugins.push(sveltePlugin(svelteOptions));\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'MODULE_NOT_FOUND') {\n throw new Error(\n '@storybook/builder-vite requires @sveltejs/vite-plugin-svelte to be installed' +\n ' when using @storybook/svelte.' +\n ' Please install it and start storybook again.'\n );\n }\n throw err;\n }\n\n try {\n const csfPlugin = require('./svelte/csf-plugin').default;\n plugins.push(csfPlugin(svelteOptions));\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'MODULE_NOT_FOUND') {\n throw new Error(\n '@storybook/builder-vite requires @storybook/addon-svelte-csf to be installed when using @storybook/svelte.' +\n ' Please install it and start storybook again.'\n );\n }\n throw err;\n }\n }\n\n if (framework === 'react') {\n plugins.push(\n require('@vitejs/plugin-react')({\n // Do not treat story files as HMR boundaries, storybook itself needs to handle them.\n exclude: [/\\.stories\\.([tj])sx?$/, /node_modules/],\n })\n );\n\n const { reactDocgen, reactDocgenTypescriptOptions } = await presets.apply('typescript', {} as TypescriptConfig);\n\n let typescriptPresent;\n\n try {\n const pkgJson = readPackageJson();\n typescriptPresent = pkgJson && (pkgJson?.devDependencies?.typescript || pkgJson?.dependencies?.typescript);\n } catch (e) {\n typescriptPresent = false;\n }\n\n if (reactDocgen === 'react-docgen-typescript' && typescriptPresent) {\n plugins.push(require('@joshwooding/vite-plugin-react-docgen-typescript').default(reactDocgenTypescriptOptions));\n } else if (reactDocgen) {\n const { reactDocgen } = await import('./plugins/react-docgen');\n // Needs to run before the react plugin, so add to the front\n plugins.unshift(reactDocgen());\n }\n }\n\n if (framework === 'glimmerx') {\n const plugin = require('vite-plugin-glimmerx/index.cjs');\n plugins.push(plugin.default());\n }\n\n return plugins;\n}\n"]}
@@ -0,0 +1,3 @@
1
+ // This file is to work around https://github.com/vitejs/vite/issues/6007
2
+ // For react < 18 projects, where `react-dom/client` does not exist, yet is
3
+ // conditionally imported by @storybook/react.
package/list-stories.ts CHANGED
@@ -1,20 +1,19 @@
1
1
  import * as path from 'path';
2
2
  import { promise as glob } from 'glob-promise';
3
+ import { normalizeStories } from '@storybook/core-common';
3
4
 
4
- import type { Options, StoriesEntry } from '@storybook/core-common';
5
+ import type { Options } from '@storybook/core-common';
5
6
 
6
- // TODO: Merge with https://github.com/storybookjs/builder-vite/pull/182
7
- export async function listStories({ presets, configDir }: Options) {
7
+ export async function listStories(options: Options) {
8
8
  return (
9
9
  await Promise.all(
10
- (
11
- await presets.apply<Promise<StoriesEntry[]>>('stories')
12
- ).map((storiesEntry) => {
13
- const files = typeof storiesEntry === 'string' ? storiesEntry : storiesEntry.files;
14
- if (!files) {
15
- return [] as string[];
16
- }
17
- return glob(path.isAbsolute(files) ? files : path.join(configDir, files));
10
+ normalizeStories(await options.presets.apply('stories', [], options), {
11
+ configDir: options.configDir,
12
+ workingDir: options.configDir,
13
+ }).map(({ directory, files }) => {
14
+ const pattern = path.join(directory, files);
15
+
16
+ return glob(path.isAbsolute(pattern) ? pattern : path.join(options.configDir, pattern));
18
17
  })
19
18
  )
20
19
  ).reduce((carry, stories) => carry.concat(stories), []);
package/optimizeDeps.ts CHANGED
@@ -63,6 +63,7 @@ const INCLUDE_CANDIDATES = [
63
63
  'prop-types',
64
64
  'qs',
65
65
  'react-dom',
66
+ 'react-dom/client',
66
67
  'react-fast-compare',
67
68
  'react-is',
68
69
  'react-textarea-autosize',
@@ -108,6 +109,17 @@ export async function getOptimizeDeps(
108
109
  const stories = absoluteStories.map((storyPath) => normalizePath(path.relative(root, storyPath)));
109
110
  const resolvedConfig = await resolveConfig(config, 'serve', 'development');
110
111
 
112
+ const exclude = [];
113
+ // This is necessary to support react < 18 with new versions of @storybook/react that support react 18.
114
+ // TODO: narrow this down to just framework === 'react'. But causes a vue dev start problem in this monorepo.
115
+ try {
116
+ require.resolve('react-dom/client', { paths: [config.root] });
117
+ } catch (e) {
118
+ if (isNodeError(e) && e.code === 'MODULE_NOT_FOUND') {
119
+ exclude.push('react-dom/client');
120
+ }
121
+ }
122
+
111
123
  // This function converts ids which might include ` > ` to a real path, if it exists on disk.
112
124
  // See https://github.com/vitejs/vite/blob/67d164392e8e9081dc3f0338c4b4b8eea6c5f7da/packages/vite/src/node/optimizer/index.ts#L182-L199
113
125
  const resolve = resolvedConfig.createResolver({ asSrc: false });
@@ -119,5 +131,10 @@ export async function getOptimizeDeps(
119
131
  // We need Vite to precompile these dependencies, because they contain non-ESM code that would break
120
132
  // if we served it directly to the browser.
121
133
  include,
134
+ // In some cases we need to prevent deps from being pre-bundled
135
+ exclude,
122
136
  };
123
137
  }
138
+
139
+ // Refines an error received from 'catch' to be a NodeJS exception
140
+ const isNodeError = (error: unknown): error is NodeJS.ErrnoException => error instanceof Error;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/builder-vite",
3
- "version": "0.1.24",
3
+ "version": "0.1.27",
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",
@@ -15,8 +15,8 @@
15
15
  "dependencies": {
16
16
  "@joshwooding/vite-plugin-react-docgen-typescript": "0.0.4",
17
17
  "@mdx-js/mdx": "^1.6.22",
18
- "@storybook/csf-tools": "^6.3.3",
19
- "@storybook/source-loader": "^6.3.12",
18
+ "@storybook/csf-tools": "^6.4.3",
19
+ "@storybook/source-loader": "^6.4.3",
20
20
  "@vitejs/plugin-react": "^1.0.8",
21
21
  "ast-types": "^0.14.2",
22
22
  "es-module-lexer": "^0.9.3",
@@ -29,6 +29,7 @@
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/express": "^4.17.13",
32
+ "@types/node": "^17.0.23",
32
33
  "vue-docgen-api": "^4.40.0"
33
34
  },
34
35
  "peerDependencies": {
package/vite-config.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as path from 'path';
2
+ import fs from 'fs';
2
3
  import { Plugin } from 'vite';
3
4
  import { allowedEnvPrefix as envPrefix } from './envs';
4
5
  import { TypescriptConfig } from '@storybook/core-common';
@@ -13,6 +14,16 @@ import type { ExtendedOptions } from './types';
13
14
 
14
15
  export type PluginConfigType = 'build' | 'development';
15
16
 
17
+ export function readPackageJson(): Record<string, any> | false {
18
+ const packageJsonPath = path.resolve('package.json');
19
+ if (!fs.existsSync(packageJsonPath)) {
20
+ return false;
21
+ }
22
+
23
+ const jsonContent = fs.readFileSync(packageJsonPath, 'utf8');
24
+ return JSON.parse(jsonContent);
25
+ }
26
+
16
27
  // Vite config that is common to development and production mode
17
28
  export async function commonConfig(
18
29
  options: ExtendedOptions,
@@ -108,8 +119,8 @@ export async function pluginConfig(options: ExtendedOptions, _type: PluginConfig
108
119
  let typescriptPresent;
109
120
 
110
121
  try {
111
- require.resolve('typescript');
112
- typescriptPresent = true;
122
+ const pkgJson = readPackageJson();
123
+ typescriptPresent = pkgJson && (pkgJson?.devDependencies?.typescript || pkgJson?.dependencies?.typescript);
113
124
  } catch (e) {
114
125
  typescriptPresent = false;
115
126
  }