storybook-builder-rsbuild 2.0.3 → 2.1.0

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/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as rsbuildReal from '@rsbuild/core';
2
2
  import { RsbuildConfig } from '@rsbuild/core';
3
- import { TypescriptOptions as TypescriptOptions$1, Builder, Options, StorybookConfigRaw, BuilderResult as BuilderResult$1, NormalizedStoriesSpecifier } from 'storybook/internal/types';
3
+ import { TypescriptOptions as TypescriptOptions$1, Builder, Options, StorybookConfigRaw, BuilderResult as BuilderResult$1 } from 'storybook/internal/types';
4
4
  import { PluginTypeCheckerOptions } from '@rsbuild/plugin-type-check';
5
5
 
6
6
  type RsbuildStats = {
@@ -52,12 +52,6 @@ declare const getVirtualModules: (options: Options) => Promise<{
52
52
  virtualModules: Record<string, string>;
53
53
  entries: string[];
54
54
  }>;
55
- declare function toImportFnPart(specifier: NormalizedStoriesSpecifier): string;
56
- declare function toImportFn(stories: NormalizedStoriesSpecifier[], relativeOffset: string, { needPipelinedImport }?: {
57
- needPipelinedImport?: boolean;
58
- }): string;
59
- type ModuleExports = Record<string, any>;
60
- declare function importPipeline(): (importFn: () => Promise<ModuleExports>) => Promise<ModuleExports>;
61
55
 
62
56
  type StatsOrMultiStats = Parameters<rsbuildReal.OnAfterBuildFn>[0]['stats'];
63
57
  type Stats = NonNullable<Exclude<StatsOrMultiStats, {
@@ -75,4 +69,4 @@ declare const build: ({ options }: BuilderStartOptions) => Promise<Stats>;
75
69
  declare const corePresets: string[];
76
70
  declare const previewMainTemplate: () => string;
77
71
 
78
- export { BuilderOptions, BuilderResult, RsbuildBuilder, RsbuildFinal, Stats, StorybookConfigRsbuild, TypescriptOptions, bail, build, corePresets, executor, getConfig, getVirtualModules, importPipeline, previewMainTemplate, printDuration, start, toImportFn, toImportFnPart };
72
+ export { BuilderOptions, BuilderResult, RsbuildBuilder, RsbuildFinal, Stats, StorybookConfigRsbuild, TypescriptOptions, bail, build, corePresets, executor, getConfig, getVirtualModules, previewMainTemplate, printDuration, start };
package/dist/index.js CHANGED
@@ -111,16 +111,13 @@ __export(src_exports, {
111
111
  executor: () => executor,
112
112
  getConfig: () => getConfig,
113
113
  getVirtualModules: () => getVirtualModules,
114
- importPipeline: () => importPipeline,
115
114
  previewMainTemplate: () => previewMainTemplate,
116
115
  printDuration: () => printDuration,
117
- start: () => start,
118
- toImportFn: () => toImportFn,
119
- toImportFnPart: () => toImportFnPart
116
+ start: () => start
120
117
  });
121
118
  module.exports = __toCommonJS(src_exports);
122
119
  var import_node_net = require("net");
123
- var import_node_path5 = require("path");
120
+ var import_node_path4 = require("path");
124
121
  var rsbuildReal = __toESM(require("@rsbuild/core"));
125
122
  var import_fs_extra = __toESM(require("fs-extra"));
126
123
  var import_pretty_hrtime = __toESM(require_pretty_hrtime());
@@ -129,7 +126,7 @@ var import_common3 = require("storybook/internal/common");
129
126
  var import_server_errors = require("storybook/internal/server-errors");
130
127
 
131
128
  // src/preview/iframe-rsbuild.config.ts
132
- var import_node_path3 = require("path");
129
+ var import_node_path2 = require("path");
133
130
  var import_core = require("@rsbuild/core");
134
131
  var import_plugin_type_check = require("@rsbuild/plugin-type-check");
135
132
  var import_preset = require("@storybook/addon-docs/preset");
@@ -137,41 +134,27 @@ var import_case_sensitive_paths_webpack_plugin = __toESM(require("case-sensitive
137
134
  var import_rsbuild_plugin_html_minifier_terser = require("rsbuild-plugin-html-minifier-terser");
138
135
  var import_common2 = require("storybook/internal/common");
139
136
  var import_globals = require("storybook/internal/preview/globals");
140
- var import_ts_dedent2 = require("ts-dedent");
137
+ var import_ts_dedent = require("ts-dedent");
141
138
 
142
139
  // src/preview/virtual-module-mapping.ts
143
- var import_node_fs = __toESM(require("fs"));
144
- var import_node_path = __toESM(require("path"));
145
- var import_node_path2 = require("path");
140
+ var import_node_path = require("path");
146
141
  var import_core_webpack = require("@storybook/core-webpack");
147
- var import_find_cache_dir = __toESM(require("find-cache-dir"));
148
142
 
149
143
  // ../../node_modules/.pnpm/slash@5.1.0/node_modules/slash/index.js
150
- function slash(path2) {
151
- const isExtendedLengthPath = path2.startsWith("\\\\?\\");
144
+ function slash(path) {
145
+ const isExtendedLengthPath = path.startsWith("\\\\?\\");
152
146
  if (isExtendedLengthPath) {
153
- return path2;
147
+ return path;
154
148
  }
155
- return path2.replace(/\\/g, "/");
149
+ return path.replace(/\\/g, "/");
156
150
  }
157
151
 
158
152
  // src/preview/virtual-module-mapping.ts
159
153
  var import_common = require("storybook/internal/common");
160
- var import_ts_dedent = require("ts-dedent");
161
154
  var getVirtualModules = async (options) => {
162
155
  const virtualModules = {};
163
- const cwd = process.cwd();
164
- const workingDir = options.cache ? (
165
- // TODO: This is a hard code cache dir, as Rspack doesn't support virtual modules now.
166
- // Remove this when Rspack supports virtual modules.
167
- (0, import_find_cache_dir.default)({
168
- name: "storybook-rsbuild-builder",
169
- create: true
170
- })
171
- ) : process.cwd();
172
- if (!import_node_fs.default.existsSync(workingDir)) {
173
- import_node_fs.default.mkdirSync(workingDir, { recursive: true });
174
- }
156
+ const builderOptions = await (0, import_common.getBuilderOptions)(options);
157
+ const workingDir = process.cwd();
175
158
  const isProd = options.configType === "PRODUCTION";
176
159
  const nonNormalizedStories = await options.presets.apply("stories", []);
177
160
  const entries = [];
@@ -179,7 +162,6 @@ var getVirtualModules = async (options) => {
179
162
  configDir: options.configDir,
180
163
  workingDir
181
164
  });
182
- const realPathRelativeToCwd = import_node_path.default.relative(workingDir, cwd).split(import_node_path.default.sep).join(import_node_path.default.posix.sep);
183
165
  const previewAnnotations = [
184
166
  ...(await options.presets.apply(
185
167
  "previewAnnotations",
@@ -194,13 +176,12 @@ var getVirtualModules = async (options) => {
194
176
  (0, import_common.loadPreviewOrConfigFile)(options)
195
177
  ].filter(Boolean);
196
178
  const storiesFilename = "storybook-stories.js";
197
- const storiesPath = (0, import_node_path2.resolve)((0, import_node_path2.join)(workingDir, storiesFilename));
198
- const builderOptions = await (0, import_common.getBuilderOptions)(options);
179
+ const storiesPath = (0, import_node_path.resolve)((0, import_node_path.join)(workingDir, storiesFilename));
199
180
  const needPipelinedImport = !!builderOptions.lazyCompilation && !isProd;
200
- virtualModules[storiesPath] = toImportFn(stories, realPathRelativeToCwd, {
181
+ virtualModules[storiesPath] = (0, import_core_webpack.toImportFn)(stories, {
201
182
  needPipelinedImport
202
183
  });
203
- const configEntryPath = (0, import_node_path2.resolve)((0, import_node_path2.join)(workingDir, "storybook-config-entry.js"));
184
+ const configEntryPath = (0, import_node_path.resolve)((0, import_node_path.join)(workingDir, "storybook-config-entry.js"));
204
185
  virtualModules[configEntryPath] = (await (0, import_common.readTemplate)(
205
186
  require.resolve("storybook-builder-rsbuild/templates/virtualModuleModernEntry.js")
206
187
  )).replaceAll(`'{{storiesFilename}}'`, `'./${storiesFilename}'`).replaceAll(
@@ -211,83 +192,14 @@ var getVirtualModules = async (options) => {
211
192
  previewAnnotations.filter(Boolean).map((entry) => `require('${entry}')`).join(",")
212
193
  ).replace(/\\/g, "\\\\");
213
194
  entries.push(configEntryPath);
214
- for (const [key, value] of Object.entries(virtualModules)) {
215
- import_node_fs.default.writeFileSync(key, value);
216
- }
217
195
  return {
218
196
  virtualModules,
219
197
  entries
220
198
  };
221
199
  };
222
- function toImportFnPart(specifier) {
223
- const { directory, importPathMatcher } = specifier;
224
- return import_ts_dedent.dedent`
225
- async (path) => {
226
- if (!${importPathMatcher}.exec(path)) {
227
- return;
228
- }
229
-
230
- const pathRemainder = path.substring(${directory.length + 1});
231
- return import(
232
- /* webpackChunkName: "[request]" */
233
- /* webpackInclude: ${(0, import_core_webpack.webpackIncludeRegexp)(specifier)} */
234
- '${directory}/' + pathRemainder
235
- );
236
- }
237
-
238
- `;
239
- }
240
- function toImportFn(stories, relativeOffset, { needPipelinedImport } = {}) {
241
- let pipelinedImport = "const pipeline = (x) => x();";
242
- if (needPipelinedImport) {
243
- pipelinedImport = `
244
- const importPipeline = ${importPipeline};
245
- const pipeline = importPipeline();
246
- `;
247
- }
248
- return import_ts_dedent.dedent`
249
- ${pipelinedImport}
250
-
251
- const importers = [
252
- ${stories.map(toImportFnPart).join(",\n")}
253
- ];
254
-
255
- export async function importFn(path) {
256
- const offset = '${relativeOffset}';
257
-
258
- for (let i = 0; i < importers.length; i++) {
259
- const pathWithOffset = buildPath(offset, path)
260
-
261
- const moduleExports = await pipeline(() => importers[i](pathWithOffset));
262
- if (moduleExports) {
263
- return moduleExports;
264
- }
265
- }
266
- }
267
-
268
- function buildPath(offset, path) {
269
- if(path.startsWith('./')) {
270
- return offset + '/' + path.substring(2);
271
- } else {
272
- return offset + '/' + path;
273
- }
274
- }
275
- `;
276
- }
277
- function importPipeline() {
278
- let importGate = Promise.resolve();
279
- return async (importFn) => {
280
- await importGate;
281
- const moduleExportsPromise = importFn();
282
- importGate = importGate.then(async () => {
283
- await moduleExportsPromise;
284
- });
285
- return moduleExportsPromise;
286
- };
287
- }
288
200
 
289
201
  // src/preview/iframe-rsbuild.config.ts
290
- var getAbsolutePath = (input) => (0, import_node_path3.dirname)(require.resolve((0, import_node_path3.join)(input, "package.json")));
202
+ var getAbsolutePath = (input) => (0, import_node_path2.dirname)(require.resolve((0, import_node_path2.join)(input, "package.json")));
291
203
  var maybeGetAbsolutePath = (input) => {
292
204
  try {
293
205
  return getAbsolutePath(input);
@@ -313,7 +225,7 @@ var iframe_rsbuild_config_default = async (options, extraWebpackConfig) => {
313
225
  const { rsbuildConfigPath, addonDocs } = await (0, import_common2.getBuilderOptions)(options);
314
226
  const appliedDocsWebpack = await (0, import_preset.webpack)({}, { ...options, ...addonDocs });
315
227
  const {
316
- outputDir = (0, import_node_path3.join)(".", "public"),
228
+ outputDir = (0, import_node_path2.join)(".", "public"),
317
229
  quiet,
318
230
  packageJson,
319
231
  configType,
@@ -365,7 +277,7 @@ var iframe_rsbuild_config_default = async (options, extraWebpackConfig) => {
365
277
  lazyCompilation: { entries: false }
366
278
  } : {};
367
279
  if (!template) {
368
- throw new Error(import_ts_dedent2.dedent`
280
+ throw new Error(import_ts_dedent.dedent`
369
281
  Storybook's Webpack5 builder requires a template to be specified.
370
282
  Somehow you've ended up with a falsy value for the template option.
371
283
 
@@ -376,7 +288,7 @@ var iframe_rsbuild_config_default = async (options, extraWebpackConfig) => {
376
288
  if (build2?.test?.disableBlocks) {
377
289
  externals["@storybook/blocks"] = "__STORYBOOK_BLOCKS_EMPTY_MODULE__";
378
290
  }
379
- const { virtualModules: _virtualModules, entries: dynamicEntries } = await getVirtualModules(options);
291
+ const { virtualModules: virtualModuleMapping, entries: dynamicEntries } = await getVirtualModules(options);
380
292
  if (!options.cache) {
381
293
  throw new Error("Cache is required");
382
294
  }
@@ -429,7 +341,7 @@ var iframe_rsbuild_config_default = async (options, extraWebpackConfig) => {
429
341
  css: !options.build?.test?.disableSourcemaps
430
342
  },
431
343
  distPath: {
432
- root: (0, import_node_path3.resolve)(process.cwd(), outputDir)
344
+ root: (0, import_node_path2.resolve)(process.cwd(), outputDir)
433
345
  },
434
346
  filename: {
435
347
  js: isProd ? "[name].[contenthash:8].iframe.bundle.js" : "[name].iframe.bundle.js",
@@ -517,7 +429,7 @@ var iframe_rsbuild_config_default = async (options, extraWebpackConfig) => {
517
429
  }
518
430
  ].filter(Boolean),
519
431
  tools: {
520
- rspack: (config, { addRules, appendPlugins, rspack, mergeConfig }) => {
432
+ rspack: (config, { addRules, appendPlugins, rspack: rspack2, mergeConfig }) => {
521
433
  addRules({
522
434
  test: /\.stories\.([tj])sx?$|(stories|story)\.mdx$/,
523
435
  exclude: /node_modules/,
@@ -528,6 +440,10 @@ var iframe_rsbuild_config_default = async (options, extraWebpackConfig) => {
528
440
  }
529
441
  ]
530
442
  });
443
+ config.module ??= {};
444
+ config.module.parser ??= {};
445
+ config.module.parser.javascript ??= {};
446
+ config.module.parser.javascript.unknownContextCritical = false;
531
447
  config.resolve ??= {};
532
448
  config.resolve.symlinks = !(0, import_common2.isPreservingSymlinks)();
533
449
  config.resolve.extensions = Array.from(
@@ -562,9 +478,17 @@ var iframe_rsbuild_config_default = async (options, extraWebpackConfig) => {
562
478
  config.module.parser ??= {};
563
479
  config.module.parser.javascript ??= {};
564
480
  config.module.parser.javascript.exportsPresence = false;
481
+ if (!rspack2.experiments?.VirtualModulesPlugin) {
482
+ throw new Error(
483
+ "rspack.experiments.VirtualModulesPlugin requires at least 1.5.0 version of @rsbuild/core, please upgrade or downgrade storybook-rsbuild-builder to lower version."
484
+ );
485
+ }
565
486
  appendPlugins(
566
487
  [
567
- new rspack.ProvidePlugin({
488
+ Object.keys(virtualModuleMapping).length > 0 ? new rspack2.experiments.VirtualModulesPlugin(
489
+ virtualModuleMapping
490
+ ) : null,
491
+ new rspack2.ProvidePlugin({
568
492
  process: require.resolve("process/browser.js")
569
493
  }),
570
494
  new import_case_sensitive_paths_webpack_plugin.default()
@@ -612,7 +536,7 @@ var iframe_rsbuild_config_default = async (options, extraWebpackConfig) => {
612
536
 
613
537
  // src/react-shims.ts
614
538
  var import_promises = require("fs/promises");
615
- var import_node_path4 = require("path");
539
+ var import_node_path3 = require("path");
616
540
  var getIsReactVersion18or19 = async (options) => {
617
541
  const { legacyRootApi } = await options.presets.apply(
618
542
  "frameworkOptions"
@@ -625,12 +549,12 @@ var getIsReactVersion18or19 = async (options) => {
625
549
  {}
626
550
  );
627
551
  let reactDom = "";
628
- reactDom = resolvedReact.reactDom || (0, import_node_path4.dirname)(require.resolve("react-dom/package.json"));
629
- if (!(0, import_node_path4.isAbsolute)(reactDom)) {
552
+ reactDom = resolvedReact.reactDom || (0, import_node_path3.dirname)(require.resolve("react-dom/package.json"));
553
+ if (!(0, import_node_path3.isAbsolute)(reactDom)) {
630
554
  return false;
631
555
  }
632
556
  const { version } = JSON.parse(
633
- await (0, import_promises.readFile)((0, import_node_path4.join)(reactDom, "package.json"), "utf-8")
557
+ await (0, import_promises.readFile)((0, import_node_path3.join)(reactDom, "package.json"), "utf-8")
634
558
  );
635
559
  return version.startsWith("18") || version.startsWith("19") || version.startsWith("0.0.0");
636
560
  };
@@ -649,7 +573,7 @@ var applyReactShims = async (config, options) => {
649
573
  };
650
574
 
651
575
  // src/index.ts
652
- var corePath = (0, import_node_path5.dirname)(require.resolve("storybook/package.json"));
576
+ var corePath = (0, import_node_path4.dirname)(require.resolve("storybook/package.json"));
653
577
  var printDuration = (startTime) => (0, import_pretty_hrtime.default)(process.hrtime(startTime)).replace(" ms", " milliseconds").replace(" s", " seconds").replace(" m", " minutes");
654
578
  var executor = {
655
579
  get: async (options) => {
@@ -757,7 +681,7 @@ var start = async ({
757
681
  error: new Error("Missing Rsbuild build instance at runtime!")
758
682
  });
759
683
  }
760
- const previewResolvedDir = (0, import_node_path5.join)(corePath, "dist/preview");
684
+ const previewResolvedDir = (0, import_node_path4.join)(corePath, "dist/preview");
761
685
  const previewDirOrigin = previewResolvedDir;
762
686
  router.use(
763
687
  "/sb-preview",
@@ -780,16 +704,16 @@ var build = async ({ options }) => {
780
704
  cwd: process.cwd(),
781
705
  rsbuildConfig: config
782
706
  });
783
- const previewResolvedDir = (0, import_node_path5.join)(corePath, "dist/preview");
707
+ const previewResolvedDir = (0, import_node_path4.join)(corePath, "dist/preview");
784
708
  const previewDirOrigin = previewResolvedDir;
785
- const previewDirTarget = (0, import_node_path5.join)(options.outputDir || "", "sb-preview");
709
+ const previewDirTarget = (0, import_node_path4.join)(options.outputDir || "", "sb-preview");
786
710
  let stats;
787
711
  rsbuildBuild.onAfterBuild((params) => {
788
712
  stats = params.stats;
789
713
  });
790
714
  const previewFiles = import_fs_extra.default.copy(previewDirOrigin, previewDirTarget, {
791
715
  filter: (src) => {
792
- const { ext } = (0, import_node_path5.parse)(src);
716
+ const { ext } = (0, import_node_path4.parse)(src);
793
717
  if (ext) {
794
718
  return ext === ".js";
795
719
  }
@@ -803,7 +727,7 @@ var build = async ({ options }) => {
803
727
  await close();
804
728
  return stats;
805
729
  };
806
- var corePresets = [(0, import_node_path5.join)(__dirname, "./preview-preset.js")];
730
+ var corePresets = [(0, import_node_path4.join)(__dirname, "./preview-preset.js")];
807
731
  var previewMainTemplate = () => require.resolve("storybook-builder-rsbuild/templates/preview.ejs");
808
732
  function getRandomPort(host) {
809
733
  return new Promise((resolve3, reject) => {
@@ -826,10 +750,7 @@ function getRandomPort(host) {
826
750
  executor,
827
751
  getConfig,
828
752
  getVirtualModules,
829
- importPipeline,
830
753
  previewMainTemplate,
831
754
  printDuration,
832
- start,
833
- toImportFn,
834
- toImportFnPart
755
+ start
835
756
  });
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  import { __commonJS, __toESM, __require } from './chunk-TTFRSOOU.mjs';
2
2
  import { createServer } from 'net';
3
- import path, { dirname, join, resolve, parse, isAbsolute } from 'path';
3
+ import { dirname, join, resolve, parse, isAbsolute } from 'path';
4
4
  import * as rsbuildReal from '@rsbuild/core';
5
5
  import { loadConfig, mergeRsbuildConfig } from '@rsbuild/core';
6
- import fs2 from 'fs-extra';
6
+ import fs from 'fs-extra';
7
7
  import sirv from 'sirv';
8
- import { normalizeStories, loadPreviewOrConfigFile, getBuilderOptions, readTemplate, resolveAddonName, getPresets, stringifyProcessEnvs, isPreservingSymlinks } from 'storybook/internal/common';
8
+ import { getBuilderOptions, normalizeStories, loadPreviewOrConfigFile, readTemplate, resolveAddonName, getPresets, stringifyProcessEnvs, isPreservingSymlinks } from 'storybook/internal/common';
9
9
  import { WebpackInvocationError } from 'storybook/internal/server-errors';
10
10
  import { pluginTypeCheck } from '@rsbuild/plugin-type-check';
11
11
  import { webpack } from '@storybook/addon-docs/preset';
@@ -13,9 +13,7 @@ import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin';
13
13
  import { pluginHtmlMinifierTerser } from 'rsbuild-plugin-html-minifier-terser';
14
14
  import { globalsNameReferenceMap } from 'storybook/internal/preview/globals';
15
15
  import { dedent } from 'ts-dedent';
16
- import fs from 'fs';
17
- import { webpackIncludeRegexp } from '@storybook/core-webpack';
18
- import findCacheDirectory from 'find-cache-dir';
16
+ import { toImportFn } from '@storybook/core-webpack';
19
17
  import { readFile } from 'fs/promises';
20
18
 
21
19
  // ../../node_modules/.pnpm/pretty-hrtime@1.0.3/node_modules/pretty-hrtime/index.js
@@ -93,27 +91,17 @@ var require_pretty_hrtime = __commonJS({
93
91
  var import_pretty_hrtime = __toESM(require_pretty_hrtime());
94
92
 
95
93
  // ../../node_modules/.pnpm/slash@5.1.0/node_modules/slash/index.js
96
- function slash(path2) {
97
- const isExtendedLengthPath = path2.startsWith("\\\\?\\");
94
+ function slash(path) {
95
+ const isExtendedLengthPath = path.startsWith("\\\\?\\");
98
96
  if (isExtendedLengthPath) {
99
- return path2;
97
+ return path;
100
98
  }
101
- return path2.replace(/\\/g, "/");
99
+ return path.replace(/\\/g, "/");
102
100
  }
103
101
  var getVirtualModules = async (options) => {
104
102
  const virtualModules = {};
105
- const cwd = process.cwd();
106
- const workingDir = options.cache ? (
107
- // TODO: This is a hard code cache dir, as Rspack doesn't support virtual modules now.
108
- // Remove this when Rspack supports virtual modules.
109
- findCacheDirectory({
110
- name: "storybook-rsbuild-builder",
111
- create: true
112
- })
113
- ) : process.cwd();
114
- if (!fs.existsSync(workingDir)) {
115
- fs.mkdirSync(workingDir, { recursive: true });
116
- }
103
+ const builderOptions = await getBuilderOptions(options);
104
+ const workingDir = process.cwd();
117
105
  const isProd = options.configType === "PRODUCTION";
118
106
  const nonNormalizedStories = await options.presets.apply("stories", []);
119
107
  const entries = [];
@@ -121,7 +109,6 @@ var getVirtualModules = async (options) => {
121
109
  configDir: options.configDir,
122
110
  workingDir
123
111
  });
124
- const realPathRelativeToCwd = path.relative(workingDir, cwd).split(path.sep).join(path.posix.sep);
125
112
  const previewAnnotations = [
126
113
  ...(await options.presets.apply(
127
114
  "previewAnnotations",
@@ -137,9 +124,8 @@ var getVirtualModules = async (options) => {
137
124
  ].filter(Boolean);
138
125
  const storiesFilename = "storybook-stories.js";
139
126
  const storiesPath = resolve(join(workingDir, storiesFilename));
140
- const builderOptions = await getBuilderOptions(options);
141
127
  const needPipelinedImport = !!builderOptions.lazyCompilation && !isProd;
142
- virtualModules[storiesPath] = toImportFn(stories, realPathRelativeToCwd, {
128
+ virtualModules[storiesPath] = toImportFn(stories, {
143
129
  needPipelinedImport
144
130
  });
145
131
  const configEntryPath = resolve(join(workingDir, "storybook-config-entry.js"));
@@ -155,80 +141,11 @@ var getVirtualModules = async (options) => {
155
141
  previewAnnotations.filter(Boolean).map((entry) => `require('${entry}')`).join(",")
156
142
  ).replace(/\\/g, "\\\\");
157
143
  entries.push(configEntryPath);
158
- for (const [key, value] of Object.entries(virtualModules)) {
159
- fs.writeFileSync(key, value);
160
- }
161
144
  return {
162
145
  virtualModules,
163
146
  entries
164
147
  };
165
148
  };
166
- function toImportFnPart(specifier) {
167
- const { directory, importPathMatcher } = specifier;
168
- return dedent`
169
- async (path) => {
170
- if (!${importPathMatcher}.exec(path)) {
171
- return;
172
- }
173
-
174
- const pathRemainder = path.substring(${directory.length + 1});
175
- return import(
176
- /* webpackChunkName: "[request]" */
177
- /* webpackInclude: ${webpackIncludeRegexp(specifier)} */
178
- '${directory}/' + pathRemainder
179
- );
180
- }
181
-
182
- `;
183
- }
184
- function toImportFn(stories, relativeOffset, { needPipelinedImport } = {}) {
185
- let pipelinedImport = "const pipeline = (x) => x();";
186
- if (needPipelinedImport) {
187
- pipelinedImport = `
188
- const importPipeline = ${importPipeline};
189
- const pipeline = importPipeline();
190
- `;
191
- }
192
- return dedent`
193
- ${pipelinedImport}
194
-
195
- const importers = [
196
- ${stories.map(toImportFnPart).join(",\n")}
197
- ];
198
-
199
- export async function importFn(path) {
200
- const offset = '${relativeOffset}';
201
-
202
- for (let i = 0; i < importers.length; i++) {
203
- const pathWithOffset = buildPath(offset, path)
204
-
205
- const moduleExports = await pipeline(() => importers[i](pathWithOffset));
206
- if (moduleExports) {
207
- return moduleExports;
208
- }
209
- }
210
- }
211
-
212
- function buildPath(offset, path) {
213
- if(path.startsWith('./')) {
214
- return offset + '/' + path.substring(2);
215
- } else {
216
- return offset + '/' + path;
217
- }
218
- }
219
- `;
220
- }
221
- function importPipeline() {
222
- let importGate = Promise.resolve();
223
- return async (importFn) => {
224
- await importGate;
225
- const moduleExportsPromise = importFn();
226
- importGate = importGate.then(async () => {
227
- await moduleExportsPromise;
228
- });
229
- return moduleExportsPromise;
230
- };
231
- }
232
149
 
233
150
  // src/preview/iframe-rsbuild.config.ts
234
151
  var getAbsolutePath = (input) => dirname(__require.resolve(join(input, "package.json")));
@@ -320,7 +237,7 @@ var iframe_rsbuild_config_default = async (options, extraWebpackConfig) => {
320
237
  if (build2?.test?.disableBlocks) {
321
238
  externals["@storybook/blocks"] = "__STORYBOOK_BLOCKS_EMPTY_MODULE__";
322
239
  }
323
- const { virtualModules: _virtualModules, entries: dynamicEntries } = await getVirtualModules(options);
240
+ const { virtualModules: virtualModuleMapping, entries: dynamicEntries } = await getVirtualModules(options);
324
241
  if (!options.cache) {
325
242
  throw new Error("Cache is required");
326
243
  }
@@ -461,7 +378,7 @@ var iframe_rsbuild_config_default = async (options, extraWebpackConfig) => {
461
378
  }
462
379
  ].filter(Boolean),
463
380
  tools: {
464
- rspack: (config, { addRules, appendPlugins, rspack, mergeConfig }) => {
381
+ rspack: (config, { addRules, appendPlugins, rspack: rspack2, mergeConfig }) => {
465
382
  addRules({
466
383
  test: /\.stories\.([tj])sx?$|(stories|story)\.mdx$/,
467
384
  exclude: /node_modules/,
@@ -474,6 +391,10 @@ var iframe_rsbuild_config_default = async (options, extraWebpackConfig) => {
474
391
  }
475
392
  ]
476
393
  });
394
+ config.module ??= {};
395
+ config.module.parser ??= {};
396
+ config.module.parser.javascript ??= {};
397
+ config.module.parser.javascript.unknownContextCritical = false;
477
398
  config.resolve ??= {};
478
399
  config.resolve.symlinks = !isPreservingSymlinks();
479
400
  config.resolve.extensions = Array.from(
@@ -508,9 +429,17 @@ var iframe_rsbuild_config_default = async (options, extraWebpackConfig) => {
508
429
  config.module.parser ??= {};
509
430
  config.module.parser.javascript ??= {};
510
431
  config.module.parser.javascript.exportsPresence = false;
432
+ if (!rspack2.experiments?.VirtualModulesPlugin) {
433
+ throw new Error(
434
+ "rspack.experiments.VirtualModulesPlugin requires at least 1.5.0 version of @rsbuild/core, please upgrade or downgrade storybook-rsbuild-builder to lower version."
435
+ );
436
+ }
511
437
  appendPlugins(
512
438
  [
513
- new rspack.ProvidePlugin({
439
+ Object.keys(virtualModuleMapping).length > 0 ? new rspack2.experiments.VirtualModulesPlugin(
440
+ virtualModuleMapping
441
+ ) : null,
442
+ new rspack2.ProvidePlugin({
514
443
  process: __require.resolve("process/browser.js")
515
444
  }),
516
445
  new CaseSensitivePathsPlugin()
@@ -729,7 +658,7 @@ var build = async ({ options }) => {
729
658
  rsbuildBuild.onAfterBuild((params) => {
730
659
  stats = params.stats;
731
660
  });
732
- const previewFiles = fs2.copy(previewDirOrigin, previewDirTarget, {
661
+ const previewFiles = fs.copy(previewDirOrigin, previewDirTarget, {
733
662
  filter: (src) => {
734
663
  const { ext } = parse(src);
735
664
  if (ext) {
@@ -761,4 +690,4 @@ function getRandomPort(host) {
761
690
  });
762
691
  }
763
692
 
764
- export { bail, build, corePresets, executor, getConfig, getVirtualModules, importPipeline, previewMainTemplate, printDuration, start, toImportFn, toImportFnPart };
693
+ export { bail, build, corePresets, executor, getConfig, getVirtualModules, previewMainTemplate, printDuration, start };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storybook-builder-rsbuild",
3
- "version": "2.0.3",
3
+ "version": "2.1.0",
4
4
  "description": "Rsbuild builder for Storybook",
5
5
  "keywords": [
6
6
  "storybook",
@@ -57,20 +57,19 @@
57
57
  "!src/**/*"
58
58
  ],
59
59
  "dependencies": {
60
- "@rsbuild/plugin-type-check": "^1.2.3",
61
- "@storybook/addon-docs": "^9.0.18",
62
- "@storybook/core-webpack": "^9.0.18",
60
+ "@rsbuild/plugin-type-check": "^1.2.4",
61
+ "@storybook/addon-docs": "^9.1.2",
62
+ "@storybook/core-webpack": "^9.1.2",
63
63
  "browser-assert": "^1.2.1",
64
64
  "case-sensitive-paths-webpack-plugin": "^2.4.0",
65
65
  "cjs-module-lexer": "^1.4.3",
66
66
  "constants-browserify": "^1.0.0",
67
67
  "es-module-lexer": "^1.7.0",
68
- "find-cache-dir": "^5.0.0",
69
- "fs-extra": "^11.3.0",
68
+ "fs-extra": "^11.3.1",
70
69
  "magic-string": "^0.30.17",
71
70
  "path-browserify": "^1.0.1",
72
71
  "process": "^0.11.10",
73
- "rsbuild-plugin-html-minifier-terser": "^1.1.1",
72
+ "rsbuild-plugin-html-minifier-terser": "^1.1.2",
74
73
  "sirv": "^2.0.4",
75
74
  "ts-dedent": "^2.2.0",
76
75
  "url": "^0.11.4",
@@ -78,18 +77,19 @@
78
77
  "util-deprecate": "^1.0.2"
79
78
  },
80
79
  "devDependencies": {
81
- "@rsbuild/core": "^1.4.11",
80
+ "@rsbuild/core": "^1.5.0",
82
81
  "@types/find-cache-dir": "^5.0.2",
83
82
  "@types/fs-extra": "^11.0.4",
84
83
  "@types/node": "^18.19.110",
85
84
  "@types/pretty-hrtime": "^1.0.3",
85
+ "find-cache-dir": "^5.0.0",
86
86
  "pretty-hrtime": "^1.0.3",
87
87
  "slash": "^5.1.0",
88
- "storybook": "9.0.18",
89
- "typescript": "^5.8.3"
88
+ "storybook": "9.1.2",
89
+ "typescript": "^5.9.2"
90
90
  },
91
91
  "peerDependencies": {
92
- "@rsbuild/core": "^1.0.1",
92
+ "@rsbuild/core": "^1.5.0",
93
93
  "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
94
94
  "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
95
95
  "storybook": "^9.0.0"
@@ -1,16 +1,23 @@
1
1
  import { createBrowserChannel } from 'storybook/internal/channels'
2
- import {
3
- PreviewWeb,
4
- addons,
5
- composeConfigs,
6
- } from 'storybook/internal/preview-api'
2
+ import { STORY_HOT_UPDATED } from 'storybook/internal/core-events'
3
+ import { isPreview } from 'storybook/internal/csf'
7
4
 
8
5
  import { global } from '@storybook/global'
9
6
 
7
+ import { PreviewWeb, addons, composeConfigs } from 'storybook/preview-api'
10
8
  import { importFn } from '{{storiesFilename}}'
11
9
 
12
- const getProjectAnnotations = () =>
13
- composeConfigs(['{{previewAnnotations_requires}}'])
10
+ const getProjectAnnotations = () => {
11
+ const previewAnnotations = ['{{previewAnnotations_requires}}']
12
+ // the last one in this array is the user preview
13
+ const userPreview = previewAnnotations[previewAnnotations.length - 1]?.default
14
+
15
+ if (isPreview(userPreview)) {
16
+ return userPreview.composed
17
+ }
18
+
19
+ return composeConfigs(previewAnnotations)
20
+ }
14
21
 
15
22
  const channel = createBrowserChannel({ page: 'preview' })
16
23
  addons.setChannel(channel)
@@ -26,6 +33,12 @@ window.__STORYBOOK_STORY_STORE__ = preview.storyStore
26
33
  window.__STORYBOOK_ADDONS_CHANNEL__ = channel
27
34
 
28
35
  if (import.meta.webpackHot) {
36
+ import.meta.webpackHot.addStatusHandler((status) => {
37
+ if (status === 'idle') {
38
+ preview.channel.emit(STORY_HOT_UPDATED)
39
+ }
40
+ })
41
+
29
42
  import.meta.webpackHot.accept('{{storiesFilename}}', () => {
30
43
  // importFn has changed so we need to patch the new one in
31
44
  preview.onStoriesChanged({ importFn })