@storybook/builder-vite 10.4.0-alpha.5 → 10.4.0-alpha.7

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.
@@ -1,10 +1,10 @@
1
- import CJS_COMPAT_NODE_URL_f83vzdyy5za from 'node:url';
2
- import CJS_COMPAT_NODE_PATH_f83vzdyy5za from 'node:path';
3
- import CJS_COMPAT_NODE_MODULE_f83vzdyy5za from "node:module";
1
+ import CJS_COMPAT_NODE_URL_wz9w23i4nmi from 'node:url';
2
+ import CJS_COMPAT_NODE_PATH_wz9w23i4nmi from 'node:path';
3
+ import CJS_COMPAT_NODE_MODULE_wz9w23i4nmi from "node:module";
4
4
 
5
- var __filename = CJS_COMPAT_NODE_URL_f83vzdyy5za.fileURLToPath(import.meta.url);
6
- var __dirname = CJS_COMPAT_NODE_PATH_f83vzdyy5za.dirname(__filename);
7
- var require = CJS_COMPAT_NODE_MODULE_f83vzdyy5za.createRequire(import.meta.url);
5
+ var __filename = CJS_COMPAT_NODE_URL_wz9w23i4nmi.fileURLToPath(import.meta.url);
6
+ var __dirname = CJS_COMPAT_NODE_PATH_wz9w23i4nmi.dirname(__filename);
7
+ var require = CJS_COMPAT_NODE_MODULE_wz9w23i4nmi.createRequire(import.meta.url);
8
8
 
9
9
  // ------------------------------------------------------------
10
10
  // end of CJS compatibility banner, injected by Storybook's esbuild configuration
@@ -522,9 +522,12 @@ var ENTRY_PATH = "/vite-inject-mocker-entry.js", viteInjectMockerRuntime = (opti
522
522
  });
523
523
  });
524
524
  },
525
- resolveId(source) {
526
- if (source === ENTRY_PATH)
527
- return mockerRuntimePath;
525
+ resolveId: {
526
+ filter: { id: /\/vite-inject-mocker-entry\.js/ },
527
+ handler(source) {
528
+ if (source === ENTRY_PATH)
529
+ return mockerRuntimePath;
530
+ }
528
531
  },
529
532
  transformIndexHtml(html) {
530
533
  let headTag = html.match(/<head[^>]*>/);
@@ -627,14 +630,17 @@ function viteMockPlugin(options) {
627
630
  },
628
631
  {
629
632
  name: "storybook:mock-loader-preview",
630
- transform(code, id) {
631
- if (id === normalizedPreviewConfigPath)
632
- try {
633
- return rewriteSbMockImportCalls(code);
634
- } catch (e) {
635
- return logger.debug(`Could not transform sb.mock(import(...)) calls in ${id}: ${e}`), null;
636
- }
637
- return null;
633
+ transform: {
634
+ filter: { id: normalizedPreviewConfigPath },
635
+ handler(code, id) {
636
+ if (id === normalizedPreviewConfigPath)
637
+ try {
638
+ return rewriteSbMockImportCalls(code);
639
+ } catch (e) {
640
+ return logger.debug(`Could not transform sb.mock(import(...)) calls in ${id}: ${e}`), null;
641
+ }
642
+ return null;
643
+ }
638
644
  }
639
645
  }
640
646
  ];
package/dist/index.d.ts CHANGED
@@ -24,8 +24,9 @@ declare const withoutVitePlugins: <TPlugin>(plugins: TPlugin[] | undefined, name
24
24
  declare function hasVitePlugins(plugins: PluginOption[], names: string[]): Promise<boolean>;
25
25
 
26
26
  declare function bail(): Promise<void>;
27
+ declare const onModuleGraphChange: NonNullable<Builder<Options>['onModuleGraphChange']>;
27
28
  declare const start: ViteBuilder['start'];
28
29
  declare const build: ViteBuilder['build'];
29
30
  declare const corePresets: string[];
30
31
 
31
- export { type BuilderOptions, type StorybookConfigVite, type ViteBuilder, type ViteFinal, bail, build, corePresets, hasVitePlugins, start, withoutVitePlugins };
32
+ export { type BuilderOptions, type StorybookConfigVite, type ViteBuilder, type ViteFinal, bail, build, corePresets, hasVitePlugins, onModuleGraphChange, start, withoutVitePlugins };
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import CJS_COMPAT_NODE_URL_f83vzdyy5za from 'node:url';
2
- import CJS_COMPAT_NODE_PATH_f83vzdyy5za from 'node:path';
3
- import CJS_COMPAT_NODE_MODULE_f83vzdyy5za from "node:module";
1
+ import CJS_COMPAT_NODE_URL_wz9w23i4nmi from 'node:url';
2
+ import CJS_COMPAT_NODE_PATH_wz9w23i4nmi from 'node:path';
3
+ import CJS_COMPAT_NODE_MODULE_wz9w23i4nmi from "node:module";
4
4
 
5
- var __filename = CJS_COMPAT_NODE_URL_f83vzdyy5za.fileURLToPath(import.meta.url);
6
- var __dirname = CJS_COMPAT_NODE_PATH_f83vzdyy5za.dirname(__filename);
7
- var require = CJS_COMPAT_NODE_MODULE_f83vzdyy5za.createRequire(import.meta.url);
5
+ var __filename = CJS_COMPAT_NODE_URL_wz9w23i4nmi.fileURLToPath(import.meta.url);
6
+ var __dirname = CJS_COMPAT_NODE_PATH_wz9w23i4nmi.dirname(__filename);
7
+ var require = CJS_COMPAT_NODE_MODULE_wz9w23i4nmi.createRequire(import.meta.url);
8
8
 
9
9
  // ------------------------------------------------------------
10
10
  // end of CJS compatibility banner, injected by Storybook's esbuild configuration
@@ -24,7 +24,7 @@ import {
24
24
  normalize,
25
25
  relative,
26
26
  viteCorePlugins
27
- } from "./_node-chunks/chunk-HCRZWB3B.js";
27
+ } from "./_node-chunks/chunk-7LGLSEOZ.js";
28
28
 
29
29
  // ../../../node_modules/picocolors/picocolors.js
30
30
  var require_picocolors = __commonJS({
@@ -93,7 +93,11 @@ var require_picocolors = __commonJS({
93
93
  // src/index.ts
94
94
  import { readFile } from "node:fs/promises";
95
95
  import { fileURLToPath as fileURLToPath3 } from "node:url";
96
- import { NoStatsForViteDevError } from "storybook/internal/server-errors";
96
+ import { logger as logger3 } from "storybook/internal/node-logger";
97
+ import {
98
+ NoStatsForViteDevError,
99
+ ViteModuleGraphSubscriptionError
100
+ } from "storybook/internal/server-errors";
97
101
 
98
102
  // src/build.ts
99
103
  import { logger as logger2 } from "storybook/internal/node-logger";
@@ -1151,40 +1155,46 @@ var wordRegex = /\w/, Mappings = class {
1151
1155
 
1152
1156
  // src/plugins/inject-export-order-plugin.ts
1153
1157
  async function injectExportOrderPlugin() {
1154
- let { createFilter } = await import("vite"), filter = createFilter([/\.stories\.([tj])sx?$/, /(stories|story).mdx$/]);
1158
+ let { createFilter } = await import("vite"), include = [/\.stories\.([tj])sx?$/, /(stories|story).mdx$/], filter = createFilter(include);
1155
1159
  return {
1156
1160
  name: "storybook:inject-export-order-plugin",
1157
1161
  // This should only run after the typescript has been transpiled
1158
1162
  enforce: "post",
1159
- async transform(code, id) {
1160
- if (!filter(id))
1161
- return;
1162
- let [, exports] = await parse(code), exportNames = exports.map((e) => code.substring(e.s, e.e));
1163
- if (exportNames.includes("__namedExportsOrder"))
1164
- return;
1165
- let s = new MagicString(code), orderedExports = exportNames.filter((e) => e !== "default");
1166
- return s.append(`;export const __namedExportsOrder = ${JSON.stringify(orderedExports)};`), {
1167
- code: s.toString(),
1168
- map: s.generateMap({ hires: !0, source: id })
1169
- };
1163
+ transform: {
1164
+ filter: { id: include },
1165
+ async handler(code, id) {
1166
+ if (!filter(id))
1167
+ return;
1168
+ let [, exports] = await parse(code), exportNames = exports.map((e) => code.substring(e.s, e.e));
1169
+ if (exportNames.includes("__namedExportsOrder"))
1170
+ return;
1171
+ let s = new MagicString(code), orderedExports = exportNames.filter((e) => e !== "default");
1172
+ return s.append(`;export const __namedExportsOrder = ${JSON.stringify(orderedExports)};`), {
1173
+ code: s.toString(),
1174
+ map: s.generateMap({ hires: !0, source: id })
1175
+ };
1176
+ }
1170
1177
  }
1171
1178
  };
1172
1179
  }
1173
1180
 
1174
1181
  // src/plugins/strip-story-hmr-boundaries.ts
1175
1182
  async function stripStoryHMRBoundary() {
1176
- let { createFilter } = await import("vite"), filter = createFilter(/\.stories\.(tsx?|jsx?|svelte|vue)$/);
1183
+ let { createFilter } = await import("vite"), include = /\.stories\.(tsx?|jsx?|svelte|vue)$/, filter = createFilter(include);
1177
1184
  return {
1178
1185
  name: "storybook:strip-hmr-boundary-plugin",
1179
1186
  enforce: "post",
1180
- async transform(src, id) {
1181
- if (!filter(id))
1182
- return;
1183
- let s = new MagicString(src);
1184
- return s.replace(/import\.meta\.hot\.accept\w*/, "(function hmrBoundaryNoop(){})"), {
1185
- code: s.toString(),
1186
- map: s.generateMap({ hires: !0, source: id })
1187
- };
1187
+ transform: {
1188
+ filter: { id: include },
1189
+ async handler(src, id) {
1190
+ if (!filter(id))
1191
+ return;
1192
+ let s = new MagicString(src);
1193
+ return s.replace(/import\.meta\.hot\.accept\w*/, "(function hmrBoundaryNoop(){})"), {
1194
+ code: s.toString(),
1195
+ map: s.generateMap({ hires: !0, source: id })
1196
+ };
1197
+ }
1188
1198
  }
1189
1199
  };
1190
1200
  }
@@ -1356,7 +1366,7 @@ var escapeKeys = (key) => key.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), defau
1356
1366
  async function storybookExternalGlobalsPlugin(options) {
1357
1367
  let build3 = await options.presets.apply("build"), externals = globalsNameReferenceMap;
1358
1368
  build3?.test?.disableBlocks && (externals["@storybook/addon-docs/blocks"] = "__STORYBOOK_BLOCKS_EMPTY_MODULE__"), await init;
1359
- let { mergeAlias } = await import("vite");
1369
+ let { mergeAlias } = await import("vite"), globalsList = Object.keys(externals), globalsCodeFilter = new RegExp(globalsList.map(escapeKeys).join("|"));
1360
1370
  return {
1361
1371
  name: "storybook:external-globals-plugin",
1362
1372
  enforce: "post",
@@ -1381,21 +1391,23 @@ async function storybookExternalGlobalsPlugin(options) {
1381
1391
  };
1382
1392
  },
1383
1393
  // Replace imports with variables destructured from global scope
1384
- async transform(code, id) {
1385
- let globalsList = Object.keys(externals);
1386
- if (globalsList.every((glob) => !code.includes(glob)))
1387
- return;
1388
- let [imports] = parse(code), src = new MagicString(code);
1389
- return imports.forEach(({ n: path, ss: startPosition, se: endPosition }) => {
1390
- let packageName = path;
1391
- if (packageName && globalsList.includes(packageName)) {
1392
- let importStatement = src.slice(startPosition, endPosition), transformedImport = rewriteImport(importStatement, externals, packageName);
1393
- src.update(startPosition, endPosition, transformedImport);
1394
- }
1395
- }), {
1396
- code: src.toString(),
1397
- map: null
1398
- };
1394
+ transform: {
1395
+ filter: { code: globalsCodeFilter },
1396
+ async handler(code, id) {
1397
+ if (globalsList.every((glob) => !code.includes(glob)))
1398
+ return;
1399
+ let [imports] = parse(code), src = new MagicString(code);
1400
+ return imports.forEach(({ n: path, ss: startPosition, se: endPosition }) => {
1401
+ let packageName = path;
1402
+ if (packageName && globalsList.includes(packageName)) {
1403
+ let importStatement = src.slice(startPosition, endPosition), transformedImport = rewriteImport(importStatement, externals, packageName);
1404
+ src.update(startPosition, endPosition, transformedImport);
1405
+ }
1406
+ }), {
1407
+ code: src.toString(),
1408
+ map: null
1409
+ };
1410
+ }
1399
1411
  }
1400
1412
  };
1401
1413
  }
@@ -1533,6 +1545,43 @@ async function createViteServer(options, devServer) {
1533
1545
  return finalConfig.customLogger ??= await createViteLogger(), createServer(finalConfig);
1534
1546
  }
1535
1547
 
1548
+ // src/utils/build-module-graph.ts
1549
+ function buildModuleGraph(fileToModulesMap) {
1550
+ let moduleGraph = /* @__PURE__ */ new Map(), moduleNodeMap = /* @__PURE__ */ new WeakMap(), getModuleFileFromMap = (viteModuleNode) => {
1551
+ for (let [filePath, viteModuleSet] of fileToModulesMap.entries())
1552
+ if (viteModuleSet.has(viteModuleNode))
1553
+ return filePath;
1554
+ }, getOrCreateModuleNode = (viteModuleNode, fallbackFile) => {
1555
+ let file = viteModuleNode.file ?? fallbackFile;
1556
+ if (!file)
1557
+ return;
1558
+ let existingNode = moduleNodeMap.get(viteModuleNode);
1559
+ if (existingNode)
1560
+ return existingNode;
1561
+ let moduleNode = {
1562
+ file,
1563
+ type: viteModuleNode.type,
1564
+ importers: /* @__PURE__ */ new Set(),
1565
+ importedModules: /* @__PURE__ */ new Set()
1566
+ };
1567
+ moduleNodeMap.set(viteModuleNode, moduleNode);
1568
+ let moduleSet = moduleGraph.get(file) ?? /* @__PURE__ */ new Set();
1569
+ return moduleSet.add(moduleNode), moduleGraph.set(file, moduleSet), moduleNode;
1570
+ };
1571
+ return fileToModulesMap.forEach((viteModuleSet, filePath) => {
1572
+ viteModuleSet.forEach((viteModuleNode) => {
1573
+ let moduleNode = getOrCreateModuleNode(viteModuleNode, filePath);
1574
+ moduleNode && (viteModuleNode.importers.forEach((importer) => {
1575
+ let importerNode = getOrCreateModuleNode(importer) ?? getOrCreateModuleNode(importer, getModuleFileFromMap(importer));
1576
+ importerNode && moduleNode.importers.add(importerNode);
1577
+ }), viteModuleNode.importedModules.forEach((importedModule) => {
1578
+ let importedModuleNode = getOrCreateModuleNode(importedModule) ?? getOrCreateModuleNode(importedModule, getModuleFileFromMap(importedModule));
1579
+ importedModuleNode && moduleNode.importedModules.add(importedModuleNode);
1580
+ }));
1581
+ });
1582
+ }), moduleGraph;
1583
+ }
1584
+
1536
1585
  // src/index.ts
1537
1586
  function iframeHandler(options, server2) {
1538
1587
  return async (req, res) => {
@@ -1545,16 +1594,78 @@ function iframeHandler(options, server2) {
1545
1594
  res.setHeader("Content-Type", "text/html"), res.statusCode = 200, res.write(transformed), res.end();
1546
1595
  };
1547
1596
  }
1548
- var server;
1597
+ var server, listeners = /* @__PURE__ */ new Set(), debounce, watcherChangeHandler, waitForModuleGraph, moduleGraphRegistrationClosed = !1;
1598
+ function clearModuleGraphPolling() {
1599
+ waitForModuleGraph && (clearInterval(waitForModuleGraph), waitForModuleGraph = void 0);
1600
+ }
1601
+ function notifyListeners(moduleGraph) {
1602
+ listeners.forEach((listener) => {
1603
+ listener({ type: "moduleGraph", moduleGraph });
1604
+ });
1605
+ }
1606
+ function notifyListenersOfStartupFailure(event) {
1607
+ listeners.forEach((listener) => {
1608
+ listener(event);
1609
+ });
1610
+ }
1549
1611
  async function bail() {
1550
- return server?.close();
1612
+ return watcherChangeHandler && (server?.watcher.off("all", watcherChangeHandler), watcherChangeHandler = void 0), clearModuleGraphPolling(), debounce && (clearTimeout(debounce), debounce = void 0), moduleGraphRegistrationClosed = !1, listeners.clear(), server?.close();
1551
1613
  }
1552
- var start = async ({
1614
+ var onModuleGraphChange = (cb) => {
1615
+ if (moduleGraphRegistrationClosed)
1616
+ throw new ViteModuleGraphSubscriptionError();
1617
+ return listeners.add(cb), () => {
1618
+ listeners.delete(cb);
1619
+ };
1620
+ }, startChangeDetection = async (options) => {
1621
+ let startTime = process.hrtime(), storyIndex = await (await options.presets.apply("storyIndexGenerator")).getIndex(), importPaths = new Set(Object.values(storyIndex.entries).map((entry) => entry.importPath));
1622
+ await Promise.all(Array.from(importPaths, (importPath) => server.warmupRequest(importPath))), waitForModuleGraph = setInterval(() => {
1623
+ (async () => {
1624
+ try {
1625
+ if (!watcherChangeHandler) {
1626
+ clearModuleGraphPolling();
1627
+ return;
1628
+ }
1629
+ if (process.hrtime(startTime)[0] > 30) {
1630
+ clearModuleGraphPolling();
1631
+ let error = new Error(
1632
+ "Timed out while waiting for the Vite module graph to initialize"
1633
+ );
1634
+ logger3.error("Failed to complete Vite change detection startup"), logger3.error(error), notifyListenersOfStartupFailure({
1635
+ type: "unavailable",
1636
+ reason: error.message,
1637
+ error
1638
+ });
1639
+ return;
1640
+ }
1641
+ if (server.moduleGraph.fileToModulesMap.size > 0) {
1642
+ if (clearModuleGraphPolling(), await server.waitForRequestsIdle(), !watcherChangeHandler)
1643
+ return;
1644
+ server.watcher.on("all", watcherChangeHandler), watcherChangeHandler();
1645
+ }
1646
+ } catch (error) {
1647
+ clearModuleGraphPolling(), logger3.error("Failed to complete Vite change detection startup"), logger3.error(error instanceof Error ? error : String(error)), notifyListenersOfStartupFailure({
1648
+ type: "error",
1649
+ error: error instanceof Error ? error : new Error(String(error))
1650
+ });
1651
+ }
1652
+ })();
1653
+ }, 1e3);
1654
+ }, start = async ({
1553
1655
  startTime,
1554
1656
  options,
1555
1657
  router,
1556
1658
  server: devServer
1557
- }) => (server = await createViteServer(options, devServer), router.get("/iframe.html", iframeHandler(options, server)), router.use(server.middlewares), {
1659
+ }) => (moduleGraphRegistrationClosed = !0, server = await createViteServer(options, devServer), router.get("/iframe.html", iframeHandler(options, server)), router.use(server.middlewares), listeners.size > 0 && (watcherChangeHandler = () => {
1660
+ clearTimeout(debounce), debounce = setTimeout(() => {
1661
+ notifyListeners(buildModuleGraph(server.moduleGraph.fileToModulesMap));
1662
+ }, 100);
1663
+ }, startChangeDetection(options).catch((error) => {
1664
+ clearModuleGraphPolling(), logger3.error("Failed to initialize Vite change detection"), logger3.error(error instanceof Error ? error : String(error)), notifyListenersOfStartupFailure({
1665
+ type: "error",
1666
+ error: error instanceof Error ? error : new Error(String(error))
1667
+ });
1668
+ })), {
1558
1669
  bail,
1559
1670
  stats: {
1560
1671
  toJson: () => {
@@ -1568,6 +1679,7 @@ export {
1568
1679
  build2 as build,
1569
1680
  corePresets,
1570
1681
  hasVitePlugins,
1682
+ onModuleGraphChange,
1571
1683
  start,
1572
1684
  withoutVitePlugins
1573
1685
  };
package/dist/preset.js CHANGED
@@ -1,10 +1,10 @@
1
- import CJS_COMPAT_NODE_URL_f83vzdyy5za from 'node:url';
2
- import CJS_COMPAT_NODE_PATH_f83vzdyy5za from 'node:path';
3
- import CJS_COMPAT_NODE_MODULE_f83vzdyy5za from "node:module";
1
+ import CJS_COMPAT_NODE_URL_wz9w23i4nmi from 'node:url';
2
+ import CJS_COMPAT_NODE_PATH_wz9w23i4nmi from 'node:path';
3
+ import CJS_COMPAT_NODE_MODULE_wz9w23i4nmi from "node:module";
4
4
 
5
- var __filename = CJS_COMPAT_NODE_URL_f83vzdyy5za.fileURLToPath(import.meta.url);
6
- var __dirname = CJS_COMPAT_NODE_PATH_f83vzdyy5za.dirname(__filename);
7
- var require = CJS_COMPAT_NODE_MODULE_f83vzdyy5za.createRequire(import.meta.url);
5
+ var __filename = CJS_COMPAT_NODE_URL_wz9w23i4nmi.fileURLToPath(import.meta.url);
6
+ var __dirname = CJS_COMPAT_NODE_PATH_wz9w23i4nmi.dirname(__filename);
7
+ var require = CJS_COMPAT_NODE_MODULE_wz9w23i4nmi.createRequire(import.meta.url);
8
8
 
9
9
  // ------------------------------------------------------------
10
10
  // end of CJS compatibility banner, injected by Storybook's esbuild configuration
@@ -12,7 +12,7 @@ var require = CJS_COMPAT_NODE_MODULE_f83vzdyy5za.createRequire(import.meta.url);
12
12
  import {
13
13
  optimizeViteDeps,
14
14
  viteCorePlugins
15
- } from "./_node-chunks/chunk-HCRZWB3B.js";
15
+ } from "./_node-chunks/chunk-7LGLSEOZ.js";
16
16
  export {
17
17
  optimizeViteDeps,
18
18
  viteCorePlugins
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/builder-vite",
3
- "version": "10.4.0-alpha.5",
3
+ "version": "10.4.0-alpha.7",
4
4
  "description": "A Storybook builder to dev and build with Vite",
5
5
  "keywords": [
6
6
  "storybook",
@@ -47,7 +47,7 @@
47
47
  "!src/**/*"
48
48
  ],
49
49
  "dependencies": {
50
- "@storybook/csf-plugin": "10.4.0-alpha.5",
50
+ "@storybook/csf-plugin": "10.4.0-alpha.7",
51
51
  "ts-dedent": "^2.0.0"
52
52
  },
53
53
  "devDependencies": {
@@ -62,7 +62,7 @@
62
62
  "vite": "^7.0.4"
63
63
  },
64
64
  "peerDependencies": {
65
- "storybook": "^10.4.0-alpha.5",
65
+ "storybook": "^10.4.0-alpha.7",
66
66
  "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
67
67
  },
68
68
  "publishConfig": {