storybook-builder-rsbuild 0.0.6 → 0.0.8

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, BuilderResult as BuilderResult$1, NormalizedStoriesSpecifier } from '@storybook/types';
3
+ import { TypescriptOptions as TypescriptOptions$1, Builder, Options, BuilderResult as BuilderResult$1, NormalizedStoriesSpecifier } from 'storybook/internal/types';
4
4
  import { PluginTypeCheckerOptions } from '@rsbuild/plugin-type-check';
5
5
 
6
6
  type RsbuildStats = {
@@ -25,6 +25,10 @@ type BuilderOptions = {
25
25
  * Path to rsbuild.config file, relative to CWD.
26
26
  */
27
27
  rsbuildConfigPath?: string;
28
+ /**
29
+ * Enable Rspack's lazy compilation (experimental).
30
+ */
31
+ lazyCompilation?: boolean;
28
32
  };
29
33
  interface BuilderResult extends BuilderResult$1 {
30
34
  stats?: Stats;
@@ -58,7 +62,7 @@ declare const rsbuild: (_: unknown, options: RsbuildBuilderOptions) => Promise<r
58
62
  declare const getConfig: RsbuildBuilder['getConfig'];
59
63
  declare function bail(): Promise<void>;
60
64
  declare const start: RsbuildBuilder['start'];
61
- declare const build: ({ options, }: BuilderStartOptions) => Promise<Stats>;
65
+ declare const build: ({ options }: BuilderStartOptions) => Promise<Stats>;
62
66
  declare const corePresets: string[];
63
67
  declare const previewMainTemplate: () => string;
64
68
 
package/dist/index.js CHANGED
@@ -120,24 +120,32 @@ __export(src_exports, {
120
120
  toImportFnPart: () => toImportFnPart
121
121
  });
122
122
  module.exports = __toCommonJS(src_exports);
123
+ var import_node_net = require("net");
124
+ var import_node_path5 = require("path");
123
125
  var rsbuildReal = __toESM(require("@rsbuild/core"));
124
- var import_path4 = require("path");
126
+ var import_core2 = require("@rsbuild/core");
125
127
  var import_express = __toESM(require("express"));
126
128
  var import_fs_extra = __toESM(require("fs-extra"));
127
- var import_server_errors = require("@storybook/core-events/server-errors");
129
+ var import_pretty_hrtime = __toESM(require_pretty_hrtime());
130
+ var import_core_path = require("storybook/core-path");
131
+ var import_server_errors = require("storybook/internal/server-errors");
128
132
 
129
133
  // src/preview/iframe-rsbuild.config.ts
130
- var import_path3 = require("path");
134
+ var import_node_path3 = require("path");
135
+ var import_core = require("@rsbuild/core");
136
+ var import_plugin_type_check = require("@rsbuild/plugin-type-check");
137
+ var import_preset = require("@storybook/addon-docs/dist/preset");
131
138
  var import_case_sensitive_paths_webpack_plugin = __toESM(require("case-sensitive-paths-webpack-plugin"));
132
- var import_globals = require("@storybook/preview/globals");
133
- var import_core_common2 = require("@storybook/core-common");
139
+ var import_rsbuild_plugin_html_minifier_terser = require("rsbuild-plugin-html-minifier-terser");
140
+ var import_common2 = require("storybook/internal/common");
141
+ var import_globals = require("storybook/internal/preview/globals");
134
142
  var import_ts_dedent2 = require("ts-dedent");
135
143
 
136
144
  // src/preview/virtual-module-mapping.ts
137
- var import_path = __toESM(require("path"));
138
- var import_fs = __toESM(require("fs"));
139
- var import_path2 = require("path");
140
- var import_core_common = require("@storybook/core-common");
145
+ var import_node_fs = __toESM(require("fs"));
146
+ var import_node_path = __toESM(require("path"));
147
+ var import_node_path2 = require("path");
148
+ var import_core_webpack = require("@storybook/core-webpack");
141
149
 
142
150
  // ../../node_modules/.pnpm/slash@5.1.0/node_modules/slash/index.js
143
151
  function slash(path2) {
@@ -149,7 +157,7 @@ function slash(path2) {
149
157
  }
150
158
 
151
159
  // src/preview/virtual-module-mapping.ts
152
- var import_core_webpack = require("@storybook/core-webpack");
160
+ var import_common = require("storybook/internal/common");
153
161
  var import_ts_dedent = require("ts-dedent");
154
162
  var getVirtualModules = async (options) => {
155
163
  const virtualModules = {};
@@ -158,11 +166,11 @@ var getVirtualModules = async (options) => {
158
166
  const isProd = options.configType === "PRODUCTION";
159
167
  const nonNormalizedStories = await options.presets.apply("stories", []);
160
168
  const entries = [];
161
- const stories = (0, import_core_common.normalizeStories)(nonNormalizedStories, {
169
+ const stories = (0, import_common.normalizeStories)(nonNormalizedStories, {
162
170
  configDir: options.configDir,
163
171
  workingDir
164
172
  });
165
- const realPathRelativeToCwd = import_path.default.relative(workingDir, cwd).split(import_path.default.sep).join(import_path.default.posix.sep);
173
+ const realPathRelativeToCwd = import_node_path.default.relative(workingDir, cwd).split(import_node_path.default.sep).join(import_node_path.default.posix.sep);
166
174
  const previewAnnotations = [
167
175
  ...(await options.presets.apply(
168
176
  "previewAnnotations",
@@ -174,17 +182,18 @@ var getVirtualModules = async (options) => {
174
182
  }
175
183
  return slash(entry);
176
184
  }),
177
- (0, import_core_common.loadPreviewOrConfigFile)(options)
185
+ (0, import_common.loadPreviewOrConfigFile)(options)
178
186
  ].filter(Boolean);
179
187
  const storiesFilename = "storybook-stories.js";
180
- const storiesPath = (0, import_path2.resolve)((0, import_path2.join)(workingDir, storiesFilename));
181
- const needPipelinedImport = !isProd;
188
+ const storiesPath = (0, import_node_path2.resolve)((0, import_node_path2.join)(workingDir, storiesFilename));
189
+ const builderOptions = await (0, import_common.getBuilderOptions)(options);
190
+ const needPipelinedImport = !!builderOptions.lazyCompilation && !isProd;
182
191
  virtualModules[storiesPath] = toImportFn(stories, realPathRelativeToCwd, {
183
192
  needPipelinedImport
184
193
  });
185
- const configEntryPath = (0, import_path2.resolve)((0, import_path2.join)(workingDir, "storybook-config-entry.js"));
186
- virtualModules[configEntryPath] = (0, import_core_common.handlebars)(
187
- await (0, import_core_common.readTemplate)(
194
+ const configEntryPath = (0, import_node_path2.resolve)((0, import_node_path2.join)(workingDir, "storybook-config-entry.js"));
195
+ virtualModules[configEntryPath] = (0, import_common.handlebars)(
196
+ await (0, import_common.readTemplate)(
188
197
  require.resolve("storybook-builder-rsbuild/templates/virtualModuleModernEntry.js.handlebars")
189
198
  ),
190
199
  {
@@ -194,9 +203,9 @@ var getVirtualModules = async (options) => {
194
203
  // We need to double escape `\` for webpack. We may have some in windows paths
195
204
  ).replace(/\\/g, "\\\\");
196
205
  entries.push(configEntryPath);
197
- Object.entries(virtualModules).forEach(([key, value]) => {
198
- import_fs.default.writeFileSync(key, value);
199
- });
206
+ for (const [key, value] of Object.entries(virtualModules)) {
207
+ import_node_fs.default.writeFileSync(key, value);
208
+ }
200
209
  return {
201
210
  virtualModules,
202
211
  entries
@@ -221,7 +230,7 @@ function toImportFnPart(specifier) {
221
230
  `;
222
231
  }
223
232
  function toImportFn(stories, relativeOffset, { needPipelinedImport } = {}) {
224
- let pipelinedImport = `const pipeline = (x) => x();`;
233
+ let pipelinedImport = "const pipeline = (x) => x();";
225
234
  if (needPipelinedImport) {
226
235
  pipelinedImport = `
227
236
  const importPipeline = ${importPipeline};
@@ -270,10 +279,7 @@ function importPipeline() {
270
279
  }
271
280
 
272
281
  // src/preview/iframe-rsbuild.config.ts
273
- var import_core = require("@rsbuild/core");
274
- var import_preset = require("@storybook/addon-docs/dist/preset");
275
- var import_plugin_type_check = require("@rsbuild/plugin-type-check");
276
- var getAbsolutePath = (input) => (0, import_path3.dirname)(require.resolve((0, import_path3.join)(input, "package.json")));
282
+ var getAbsolutePath = (input) => (0, import_node_path3.dirname)(require.resolve((0, import_node_path3.join)(input, "package.json")));
277
283
  var maybeGetAbsolutePath = (input) => {
278
284
  try {
279
285
  return getAbsolutePath(input);
@@ -281,24 +287,24 @@ var maybeGetAbsolutePath = (input) => {
281
287
  return false;
282
288
  }
283
289
  };
284
- var managerAPIPath = maybeGetAbsolutePath(`@storybook/manager-api`);
285
- var componentsPath = maybeGetAbsolutePath(`@storybook/components`);
286
- var globalPath = maybeGetAbsolutePath(`@storybook/global`);
287
- var routerPath = maybeGetAbsolutePath(`@storybook/router`);
288
- var themingPath = maybeGetAbsolutePath(`@storybook/theming`);
290
+ var managerAPIPath = maybeGetAbsolutePath("@storybook/manager-api");
291
+ var componentsPath = maybeGetAbsolutePath("@storybook/components");
292
+ var globalPath = maybeGetAbsolutePath("@storybook/global");
293
+ var routerPath = maybeGetAbsolutePath("@storybook/router");
294
+ var themingPath = maybeGetAbsolutePath("@storybook/theming");
289
295
  var storybookPaths = {
290
296
  ...managerAPIPath ? {
291
- [`@storybook/manager-api`]: managerAPIPath
297
+ "@storybook/manager-api": managerAPIPath
292
298
  } : {},
293
- ...componentsPath ? { [`@storybook/components`]: componentsPath } : {},
294
- ...globalPath ? { [`@storybook/global`]: globalPath } : {},
295
- ...routerPath ? { [`@storybook/router`]: routerPath } : {},
296
- ...themingPath ? { [`@storybook/theming`]: themingPath } : {}
299
+ ...componentsPath ? { "@storybook/components": componentsPath } : {},
300
+ ...globalPath ? { "@storybook/global": globalPath } : {},
301
+ ...routerPath ? { "@storybook/router": routerPath } : {},
302
+ ...themingPath ? { "@storybook/theming": themingPath } : {}
297
303
  };
298
304
  var iframe_rsbuild_config_default = async (options) => {
299
305
  const appliedDocsWebpack = await (0, import_preset.webpack)({}, options);
300
306
  const {
301
- outputDir = (0, import_path3.join)(".", "public"),
307
+ outputDir = (0, import_node_path3.join)(".", "public"),
302
308
  quiet,
303
309
  packageJson,
304
310
  configType,
@@ -339,13 +345,17 @@ var iframe_rsbuild_config_default = async (options) => {
339
345
  options.presets.apply("build"),
340
346
  presets.apply("tags", {})
341
347
  ]);
342
- const { rsbuildConfigPath } = await (0, import_core_common2.getBuilderOptions)(options);
343
- const stories = (0, import_core_common2.normalizeStories)(nonNormalizedStories, {
348
+ const { rsbuildConfigPath } = await (0, import_common2.getBuilderOptions)(options);
349
+ const stories = (0, import_common2.normalizeStories)(nonNormalizedStories, {
344
350
  configDir: options.configDir,
345
351
  workingDir
346
352
  });
347
353
  const shouldCheckTs = typescriptOptions.check && !typescriptOptions.skipCompiler;
348
354
  const tsCheckOptions = typescriptOptions.checkOptions || {};
355
+ const builderOptions = await (0, import_common2.getBuilderOptions)(options);
356
+ const lazyCompilationConfig = builderOptions.lazyCompilation && !isProd ? {
357
+ lazyCompilation: { entries: false }
358
+ } : {};
349
359
  if (!template) {
350
360
  throw new Error(import_ts_dedent2.dedent`
351
361
  Storybook's Webpack5 builder requires a template to be specified.
@@ -375,10 +385,10 @@ var iframe_rsbuild_config_default = async (options) => {
375
385
  },
376
386
  sourceMap: {
377
387
  js: options.build?.test?.disableSourcemaps ? false : "cheap-module-source-map",
378
- css: options.build?.test?.disableSourcemaps ? false : true
388
+ css: !options.build?.test?.disableSourcemaps
379
389
  },
380
390
  distPath: {
381
- root: (0, import_path3.resolve)(process.cwd(), outputDir)
391
+ root: (0, import_node_path3.resolve)(process.cwd(), outputDir)
382
392
  },
383
393
  filename: {
384
394
  js: isProd ? "[name].[contenthash:8].iframe.bundle.js" : "[name].iframe.bundle.js",
@@ -405,7 +415,7 @@ var iframe_rsbuild_config_default = async (options) => {
405
415
  main: [...entries ?? [], ...dynamicEntries]
406
416
  },
407
417
  define: {
408
- ...(0, import_core_common2.stringifyProcessEnvs)(envs),
418
+ ...(0, import_common2.stringifyProcessEnvs)(envs),
409
419
  NODE_ENV: JSON.stringify(process.env.NODE_ENV)
410
420
  }
411
421
  },
@@ -417,9 +427,17 @@ var iframe_rsbuild_config_default = async (options) => {
417
427
  }
418
428
  }
419
429
  },
420
- plugins: [shouldCheckTs ? (0, import_plugin_type_check.pluginTypeCheck)(tsCheckOptions) : null].filter(
421
- Boolean
422
- ),
430
+ plugins: [
431
+ shouldCheckTs ? (0, import_plugin_type_check.pluginTypeCheck)(tsCheckOptions) : null,
432
+ (0, import_rsbuild_plugin_html_minifier_terser.pluginHtmlMinifierTerser)({
433
+ collapseWhitespace: true,
434
+ removeComments: true,
435
+ removeRedundantAttributes: true,
436
+ removeScriptTypeAttributes: false,
437
+ removeStyleLinkTypeAttributes: true,
438
+ useShortDoctype: true
439
+ })
440
+ ].filter(Boolean),
423
441
  tools: {
424
442
  rspack: (config, { addRules, appendPlugins, rspack, mergeConfig }) => {
425
443
  addRules({
@@ -433,7 +451,7 @@ var iframe_rsbuild_config_default = async (options) => {
433
451
  ]
434
452
  });
435
453
  config.resolve ??= {};
436
- config.resolve.symlinks = !(0, import_core_common2.isPreservingSymlinks)();
454
+ config.resolve.symlinks = !(0, import_common2.isPreservingSymlinks)();
437
455
  config.watchOptions = {
438
456
  ignored: /node_modules/
439
457
  };
@@ -458,6 +476,10 @@ var iframe_rsbuild_config_default = async (options) => {
458
476
  config.optimization.runtimeChunk = true;
459
477
  config.optimization.usedExports = options.build?.test?.disableTreeShaking ? false : isProd;
460
478
  config.optimization.moduleIds = "named";
479
+ config.module ??= {};
480
+ config.module.parser ??= {};
481
+ config.module.parser.javascript ??= {};
482
+ config.module.parser.javascript.exportsPresence = false;
461
483
  appendPlugins(
462
484
  [
463
485
  new rspack.ProvidePlugin({
@@ -466,10 +488,15 @@ var iframe_rsbuild_config_default = async (options) => {
466
488
  new import_case_sensitive_paths_webpack_plugin.default()
467
489
  ].filter(Boolean)
468
490
  );
491
+ config.experiments ??= {};
492
+ config.experiments = {
493
+ ...config.experiments,
494
+ ...lazyCompilationConfig
495
+ };
469
496
  return mergeConfig(config, appliedDocsWebpack);
470
497
  },
471
498
  htmlPlugin: {
472
- filename: `iframe.html`,
499
+ filename: "iframe.html",
473
500
  // FIXME: `none` isn't a known option
474
501
  chunksSortMode: "none",
475
502
  alwaysWriteToDisk: true,
@@ -494,14 +521,6 @@ var iframe_rsbuild_config_default = async (options) => {
494
521
  },
495
522
  headHtmlSnippet,
496
523
  bodyHtmlSnippet
497
- },
498
- minify: {
499
- collapseWhitespace: true,
500
- removeComments: true,
501
- removeRedundantAttributes: true,
502
- removeScriptTypeAttributes: false,
503
- removeStyleLinkTypeAttributes: true,
504
- useShortDoctype: true
505
524
  }
506
525
  }
507
526
  }
@@ -509,10 +528,45 @@ var iframe_rsbuild_config_default = async (options) => {
509
528
  return merged;
510
529
  };
511
530
 
531
+ // src/react-shims.ts
532
+ var import_promises = require("fs/promises");
533
+ var import_node_path4 = require("path");
534
+ var getIsReactVersion18or19 = async (options) => {
535
+ const { legacyRootApi } = await options.presets.apply(
536
+ "frameworkOptions"
537
+ ) || {};
538
+ if (legacyRootApi) {
539
+ return false;
540
+ }
541
+ const resolvedReact = await options.presets.apply(
542
+ "resolvedReact",
543
+ {}
544
+ );
545
+ const reactDom = resolvedReact.reactDom || (0, import_node_path4.dirname)(require.resolve("react-dom/package.json"));
546
+ if (!(0, import_node_path4.isAbsolute)(reactDom)) {
547
+ return false;
548
+ }
549
+ const { version } = JSON.parse(
550
+ await (0, import_promises.readFile)((0, import_node_path4.join)(reactDom, "package.json"), "utf-8")
551
+ );
552
+ return version.startsWith("18") || version.startsWith("19") || version.startsWith("0.0.0");
553
+ };
554
+ var applyReactShims = async (config, options) => {
555
+ const isReactVersion18 = await getIsReactVersion18or19(options);
556
+ if (isReactVersion18) {
557
+ return void 0;
558
+ }
559
+ return {
560
+ source: {
561
+ alias: {
562
+ "@storybook/react-dom-shim": "@storybook/react-dom-shim/dist/react-16"
563
+ }
564
+ }
565
+ };
566
+ };
567
+
512
568
  // src/index.ts
513
- var import_pretty_hrtime = __toESM(require_pretty_hrtime());
514
569
  var printDuration = (startTime) => (0, import_pretty_hrtime.default)(process.hrtime(startTime)).replace(" ms", " milliseconds").replace(" s", " seconds").replace(" m", " minutes");
515
- var getAbsolutePath2 = (input) => (0, import_path4.dirname)(require.resolve((0, import_path4.join)(input, "package.json")));
516
570
  var executor = {
517
571
  get: async (options) => {
518
572
  const rsbuildInstance = await options.presets.apply("rsbuildInstance") || rsbuildReal;
@@ -520,14 +574,19 @@ var executor = {
520
574
  }
521
575
  };
522
576
  var rsbuild = async (_, options) => {
523
- const defaultConfig = await iframe_rsbuild_config_default(options);
524
577
  const { presets } = options;
578
+ let defaultConfig = await iframe_rsbuild_config_default(options);
579
+ const shimsConfig = await applyReactShims(defaultConfig, options);
580
+ defaultConfig = (0, import_core2.mergeRsbuildConfig)(
581
+ defaultConfig,
582
+ shimsConfig
583
+ );
525
584
  const finalDefaultConfig = await presets.apply(
526
585
  "rsbuildFinal",
527
586
  defaultConfig,
528
587
  options
529
588
  );
530
- return finalDefaultConfig;
589
+ return (0, import_core2.mergeRsbuildConfig)(finalDefaultConfig);
531
590
  };
532
591
  var getConfig = async (options) => {
533
592
  const { presets } = options;
@@ -558,10 +617,9 @@ var start = async ({
558
617
  ...config,
559
618
  server: {
560
619
  ...config.server,
561
- port: options.port,
562
- host: "localhost",
620
+ port: await getRandomPort(options.host),
621
+ host: options.host,
563
622
  htmlFallback: false,
564
- strictPort: true,
565
623
  printUrls: false
566
624
  },
567
625
  dev: {
@@ -582,13 +640,13 @@ var start = async ({
582
640
  if (!rsbuildBuild) {
583
641
  throw new import_server_errors.WebpackInvocationError({
584
642
  // eslint-disable-next-line local-rules/no-uncategorized-errors
585
- error: new Error(`Missing Rsbuild build instance at runtime!`)
643
+ error: new Error("Missing Rsbuild build instance at runtime!")
586
644
  });
587
645
  }
588
- const previewResolvedDir = getAbsolutePath2("@storybook/preview");
589
- const previewDirOrigin = (0, import_path4.join)(previewResolvedDir, "dist");
646
+ const previewResolvedDir = (0, import_node_path5.join)(import_core_path.corePath, "dist/preview");
647
+ const previewDirOrigin = previewResolvedDir;
590
648
  router.use(
591
- `/sb-preview`,
649
+ "/sb-preview",
592
650
  import_express.default.static(previewDirOrigin, { immutable: true, maxAge: "5m" })
593
651
  );
594
652
  router.use(rsbuildServer.middlewares);
@@ -607,16 +665,16 @@ var build = async ({ options }) => {
607
665
  cwd: process.cwd(),
608
666
  rsbuildConfig: config
609
667
  });
610
- const previewResolvedDir = getAbsolutePath2("@storybook/preview");
611
- const previewDirOrigin = (0, import_path4.join)(previewResolvedDir, "dist");
612
- const previewDirTarget = (0, import_path4.join)(options.outputDir || "", `sb-preview`);
668
+ const previewResolvedDir = (0, import_node_path5.join)(import_core_path.corePath, "dist/preview");
669
+ const previewDirOrigin = previewResolvedDir;
670
+ const previewDirTarget = (0, import_node_path5.join)(options.outputDir || "", "sb-preview");
613
671
  let stats;
614
672
  rsbuildBuild.onAfterBuild((params) => {
615
673
  stats = params.stats;
616
674
  });
617
675
  const previewFiles = import_fs_extra.default.copy(previewDirOrigin, previewDirTarget, {
618
676
  filter: (src) => {
619
- const { ext } = (0, import_path4.parse)(src);
677
+ const { ext } = (0, import_node_path5.parse)(src);
620
678
  if (ext) {
621
679
  return ext === ".js";
622
680
  }
@@ -629,8 +687,21 @@ var build = async ({ options }) => {
629
687
  await Promise.all([rsbuildBuild.build(), previewFiles]);
630
688
  return stats;
631
689
  };
632
- var corePresets = [(0, import_path4.join)(__dirname, "./preview-preset.js")];
690
+ var corePresets = [(0, import_node_path5.join)(__dirname, "./preview-preset.js")];
633
691
  var previewMainTemplate = () => require.resolve("storybook-builder-rsbuild/templates/preview.ejs");
692
+ function getRandomPort(host) {
693
+ return new Promise((resolve3, reject) => {
694
+ const server2 = (0, import_node_net.createServer)();
695
+ server2.unref();
696
+ server2.on("error", reject);
697
+ server2.listen({ port: 0, host }, () => {
698
+ const { port } = server2.address();
699
+ server2.close(() => {
700
+ resolve3(port);
701
+ });
702
+ });
703
+ });
704
+ }
634
705
  // Annotate the CommonJS export names for ESM import in node:
635
706
  0 && (module.exports = {
636
707
  bail,
package/dist/index.mjs CHANGED
@@ -1,18 +1,22 @@
1
1
  import { __commonJS, __toESM, __require } from './chunk-TTFRSOOU.mjs';
2
+ import { createServer } from 'net';
3
+ import path, { join, resolve, parse, dirname, isAbsolute } from 'path';
2
4
  import * as rsbuildReal from '@rsbuild/core';
3
- import { loadConfig, mergeRsbuildConfig } from '@rsbuild/core';
4
- import path, { join, resolve, parse, dirname } from 'path';
5
+ import { mergeRsbuildConfig, loadConfig } from '@rsbuild/core';
5
6
  import express from 'express';
6
7
  import fs2 from 'fs-extra';
7
- import { WebpackInvocationError } from '@storybook/core-events/server-errors';
8
+ import { corePath } from 'storybook/core-path';
9
+ import { WebpackInvocationError } from 'storybook/internal/server-errors';
10
+ import { pluginTypeCheck } from '@rsbuild/plugin-type-check';
11
+ import { webpack } from '@storybook/addon-docs/dist/preset';
8
12
  import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin';
9
- import { globalsNameReferenceMap } from '@storybook/preview/globals';
10
- import { normalizeStories, loadPreviewOrConfigFile, handlebars, readTemplate, getBuilderOptions, stringifyProcessEnvs, isPreservingSymlinks } from '@storybook/core-common';
13
+ import { pluginHtmlMinifierTerser } from 'rsbuild-plugin-html-minifier-terser';
14
+ import { normalizeStories, loadPreviewOrConfigFile, getBuilderOptions, handlebars, readTemplate, stringifyProcessEnvs, isPreservingSymlinks } from 'storybook/internal/common';
15
+ import { globalsNameReferenceMap } from 'storybook/internal/preview/globals';
11
16
  import { dedent } from 'ts-dedent';
12
17
  import fs from 'fs';
13
18
  import { webpackIncludeRegexp } from '@storybook/core-webpack';
14
- import { webpack } from '@storybook/addon-docs/dist/preset';
15
- import { pluginTypeCheck } from '@rsbuild/plugin-type-check';
19
+ import { readFile } from 'fs/promises';
16
20
 
17
21
  // ../../node_modules/.pnpm/pretty-hrtime@1.0.3/node_modules/pretty-hrtime/index.js
18
22
  var require_pretty_hrtime = __commonJS({
@@ -85,6 +89,9 @@ var require_pretty_hrtime = __commonJS({
85
89
  }
86
90
  });
87
91
 
92
+ // src/index.ts
93
+ var import_pretty_hrtime = __toESM(require_pretty_hrtime());
94
+
88
95
  // ../../node_modules/.pnpm/slash@5.1.0/node_modules/slash/index.js
89
96
  function slash(path2) {
90
97
  const isExtendedLengthPath = path2.startsWith("\\\\?\\");
@@ -120,7 +127,8 @@ var getVirtualModules = async (options) => {
120
127
  ].filter(Boolean);
121
128
  const storiesFilename = "storybook-stories.js";
122
129
  const storiesPath = resolve(join(workingDir, storiesFilename));
123
- const needPipelinedImport = !isProd;
130
+ const builderOptions = await getBuilderOptions(options);
131
+ const needPipelinedImport = !!builderOptions.lazyCompilation && !isProd;
124
132
  virtualModules[storiesPath] = toImportFn(stories, realPathRelativeToCwd, {
125
133
  needPipelinedImport
126
134
  });
@@ -138,9 +146,9 @@ var getVirtualModules = async (options) => {
138
146
  // We need to double escape `\` for webpack. We may have some in windows paths
139
147
  ).replace(/\\/g, "\\\\");
140
148
  entries.push(configEntryPath);
141
- Object.entries(virtualModules).forEach(([key, value]) => {
149
+ for (const [key, value] of Object.entries(virtualModules)) {
142
150
  fs.writeFileSync(key, value);
143
- });
151
+ }
144
152
  return {
145
153
  virtualModules,
146
154
  entries
@@ -165,7 +173,7 @@ function toImportFnPart(specifier) {
165
173
  `;
166
174
  }
167
175
  function toImportFn(stories, relativeOffset, { needPipelinedImport } = {}) {
168
- let pipelinedImport = `const pipeline = (x) => x();`;
176
+ let pipelinedImport = "const pipeline = (x) => x();";
169
177
  if (needPipelinedImport) {
170
178
  pipelinedImport = `
171
179
  const importPipeline = ${importPipeline};
@@ -212,6 +220,8 @@ function importPipeline() {
212
220
  return moduleExportsPromise;
213
221
  };
214
222
  }
223
+
224
+ // src/preview/iframe-rsbuild.config.ts
215
225
  var getAbsolutePath = (input) => dirname(__require.resolve(join(input, "package.json")));
216
226
  var maybeGetAbsolutePath = (input) => {
217
227
  try {
@@ -220,19 +230,19 @@ var maybeGetAbsolutePath = (input) => {
220
230
  return false;
221
231
  }
222
232
  };
223
- var managerAPIPath = maybeGetAbsolutePath(`@storybook/manager-api`);
224
- var componentsPath = maybeGetAbsolutePath(`@storybook/components`);
225
- var globalPath = maybeGetAbsolutePath(`@storybook/global`);
226
- var routerPath = maybeGetAbsolutePath(`@storybook/router`);
227
- var themingPath = maybeGetAbsolutePath(`@storybook/theming`);
233
+ var managerAPIPath = maybeGetAbsolutePath("@storybook/manager-api");
234
+ var componentsPath = maybeGetAbsolutePath("@storybook/components");
235
+ var globalPath = maybeGetAbsolutePath("@storybook/global");
236
+ var routerPath = maybeGetAbsolutePath("@storybook/router");
237
+ var themingPath = maybeGetAbsolutePath("@storybook/theming");
228
238
  var storybookPaths = {
229
239
  ...managerAPIPath ? {
230
- [`@storybook/manager-api`]: managerAPIPath
240
+ "@storybook/manager-api": managerAPIPath
231
241
  } : {},
232
- ...componentsPath ? { [`@storybook/components`]: componentsPath } : {},
233
- ...globalPath ? { [`@storybook/global`]: globalPath } : {},
234
- ...routerPath ? { [`@storybook/router`]: routerPath } : {},
235
- ...themingPath ? { [`@storybook/theming`]: themingPath } : {}
242
+ ...componentsPath ? { "@storybook/components": componentsPath } : {},
243
+ ...globalPath ? { "@storybook/global": globalPath } : {},
244
+ ...routerPath ? { "@storybook/router": routerPath } : {},
245
+ ...themingPath ? { "@storybook/theming": themingPath } : {}
236
246
  };
237
247
  var iframe_rsbuild_config_default = async (options) => {
238
248
  const appliedDocsWebpack = await webpack({}, options);
@@ -285,6 +295,10 @@ var iframe_rsbuild_config_default = async (options) => {
285
295
  });
286
296
  const shouldCheckTs = typescriptOptions.check && !typescriptOptions.skipCompiler;
287
297
  const tsCheckOptions = typescriptOptions.checkOptions || {};
298
+ const builderOptions = await getBuilderOptions(options);
299
+ const lazyCompilationConfig = builderOptions.lazyCompilation && !isProd ? {
300
+ lazyCompilation: { entries: false }
301
+ } : {};
288
302
  if (!template) {
289
303
  throw new Error(dedent`
290
304
  Storybook's Webpack5 builder requires a template to be specified.
@@ -314,7 +328,7 @@ var iframe_rsbuild_config_default = async (options) => {
314
328
  },
315
329
  sourceMap: {
316
330
  js: options.build?.test?.disableSourcemaps ? false : "cheap-module-source-map",
317
- css: options.build?.test?.disableSourcemaps ? false : true
331
+ css: !options.build?.test?.disableSourcemaps
318
332
  },
319
333
  distPath: {
320
334
  root: resolve(process.cwd(), outputDir)
@@ -356,9 +370,17 @@ var iframe_rsbuild_config_default = async (options) => {
356
370
  }
357
371
  }
358
372
  },
359
- plugins: [shouldCheckTs ? pluginTypeCheck(tsCheckOptions) : null].filter(
360
- Boolean
361
- ),
373
+ plugins: [
374
+ shouldCheckTs ? pluginTypeCheck(tsCheckOptions) : null,
375
+ pluginHtmlMinifierTerser({
376
+ collapseWhitespace: true,
377
+ removeComments: true,
378
+ removeRedundantAttributes: true,
379
+ removeScriptTypeAttributes: false,
380
+ removeStyleLinkTypeAttributes: true,
381
+ useShortDoctype: true
382
+ })
383
+ ].filter(Boolean),
362
384
  tools: {
363
385
  rspack: (config, { addRules, appendPlugins, rspack, mergeConfig }) => {
364
386
  addRules({
@@ -399,6 +421,10 @@ var iframe_rsbuild_config_default = async (options) => {
399
421
  config.optimization.runtimeChunk = true;
400
422
  config.optimization.usedExports = options.build?.test?.disableTreeShaking ? false : isProd;
401
423
  config.optimization.moduleIds = "named";
424
+ config.module ??= {};
425
+ config.module.parser ??= {};
426
+ config.module.parser.javascript ??= {};
427
+ config.module.parser.javascript.exportsPresence = false;
402
428
  appendPlugins(
403
429
  [
404
430
  new rspack.ProvidePlugin({
@@ -407,10 +433,15 @@ var iframe_rsbuild_config_default = async (options) => {
407
433
  new CaseSensitivePathsPlugin()
408
434
  ].filter(Boolean)
409
435
  );
436
+ config.experiments ??= {};
437
+ config.experiments = {
438
+ ...config.experiments,
439
+ ...lazyCompilationConfig
440
+ };
410
441
  return mergeConfig(config, appliedDocsWebpack);
411
442
  },
412
443
  htmlPlugin: {
413
- filename: `iframe.html`,
444
+ filename: "iframe.html",
414
445
  // FIXME: `none` isn't a known option
415
446
  chunksSortMode: "none",
416
447
  alwaysWriteToDisk: true,
@@ -435,25 +466,48 @@ var iframe_rsbuild_config_default = async (options) => {
435
466
  },
436
467
  headHtmlSnippet,
437
468
  bodyHtmlSnippet
438
- },
439
- minify: {
440
- collapseWhitespace: true,
441
- removeComments: true,
442
- removeRedundantAttributes: true,
443
- removeScriptTypeAttributes: false,
444
- removeStyleLinkTypeAttributes: true,
445
- useShortDoctype: true
446
469
  }
447
470
  }
448
471
  }
449
472
  });
450
473
  return merged;
451
474
  };
475
+ var getIsReactVersion18or19 = async (options) => {
476
+ const { legacyRootApi } = await options.presets.apply(
477
+ "frameworkOptions"
478
+ ) || {};
479
+ if (legacyRootApi) {
480
+ return false;
481
+ }
482
+ const resolvedReact = await options.presets.apply(
483
+ "resolvedReact",
484
+ {}
485
+ );
486
+ const reactDom = resolvedReact.reactDom || dirname(__require.resolve("react-dom/package.json"));
487
+ if (!isAbsolute(reactDom)) {
488
+ return false;
489
+ }
490
+ const { version } = JSON.parse(
491
+ await readFile(join(reactDom, "package.json"), "utf-8")
492
+ );
493
+ return version.startsWith("18") || version.startsWith("19") || version.startsWith("0.0.0");
494
+ };
495
+ var applyReactShims = async (config, options) => {
496
+ const isReactVersion18 = await getIsReactVersion18or19(options);
497
+ if (isReactVersion18) {
498
+ return void 0;
499
+ }
500
+ return {
501
+ source: {
502
+ alias: {
503
+ "@storybook/react-dom-shim": "@storybook/react-dom-shim/dist/react-16"
504
+ }
505
+ }
506
+ };
507
+ };
452
508
 
453
509
  // src/index.ts
454
- var import_pretty_hrtime = __toESM(require_pretty_hrtime());
455
510
  var printDuration = (startTime) => (0, import_pretty_hrtime.default)(process.hrtime(startTime)).replace(" ms", " milliseconds").replace(" s", " seconds").replace(" m", " minutes");
456
- var getAbsolutePath2 = (input) => dirname(__require.resolve(join(input, "package.json")));
457
511
  var executor = {
458
512
  get: async (options) => {
459
513
  const rsbuildInstance = await options.presets.apply("rsbuildInstance") || rsbuildReal;
@@ -461,14 +515,19 @@ var executor = {
461
515
  }
462
516
  };
463
517
  var rsbuild = async (_, options) => {
464
- const defaultConfig = await iframe_rsbuild_config_default(options);
465
518
  const { presets } = options;
519
+ let defaultConfig = await iframe_rsbuild_config_default(options);
520
+ const shimsConfig = await applyReactShims(defaultConfig, options);
521
+ defaultConfig = mergeRsbuildConfig(
522
+ defaultConfig,
523
+ shimsConfig
524
+ );
466
525
  const finalDefaultConfig = await presets.apply(
467
526
  "rsbuildFinal",
468
527
  defaultConfig,
469
528
  options
470
529
  );
471
- return finalDefaultConfig;
530
+ return mergeRsbuildConfig(finalDefaultConfig);
472
531
  };
473
532
  var getConfig = async (options) => {
474
533
  const { presets } = options;
@@ -499,10 +558,9 @@ var start = async ({
499
558
  ...config,
500
559
  server: {
501
560
  ...config.server,
502
- port: options.port,
503
- host: "localhost",
561
+ port: await getRandomPort(options.host),
562
+ host: options.host,
504
563
  htmlFallback: false,
505
- strictPort: true,
506
564
  printUrls: false
507
565
  },
508
566
  dev: {
@@ -523,13 +581,13 @@ var start = async ({
523
581
  if (!rsbuildBuild) {
524
582
  throw new WebpackInvocationError({
525
583
  // eslint-disable-next-line local-rules/no-uncategorized-errors
526
- error: new Error(`Missing Rsbuild build instance at runtime!`)
584
+ error: new Error("Missing Rsbuild build instance at runtime!")
527
585
  });
528
586
  }
529
- const previewResolvedDir = getAbsolutePath2("@storybook/preview");
530
- const previewDirOrigin = join(previewResolvedDir, "dist");
587
+ const previewResolvedDir = join(corePath, "dist/preview");
588
+ const previewDirOrigin = previewResolvedDir;
531
589
  router.use(
532
- `/sb-preview`,
590
+ "/sb-preview",
533
591
  express.static(previewDirOrigin, { immutable: true, maxAge: "5m" })
534
592
  );
535
593
  router.use(rsbuildServer.middlewares);
@@ -548,9 +606,9 @@ var build = async ({ options }) => {
548
606
  cwd: process.cwd(),
549
607
  rsbuildConfig: config
550
608
  });
551
- const previewResolvedDir = getAbsolutePath2("@storybook/preview");
552
- const previewDirOrigin = join(previewResolvedDir, "dist");
553
- const previewDirTarget = join(options.outputDir || "", `sb-preview`);
609
+ const previewResolvedDir = join(corePath, "dist/preview");
610
+ const previewDirOrigin = previewResolvedDir;
611
+ const previewDirTarget = join(options.outputDir || "", "sb-preview");
554
612
  let stats;
555
613
  rsbuildBuild.onAfterBuild((params) => {
556
614
  stats = params.stats;
@@ -572,5 +630,18 @@ var build = async ({ options }) => {
572
630
  };
573
631
  var corePresets = [join(__dirname, "./preview-preset.js")];
574
632
  var previewMainTemplate = () => __require.resolve("storybook-builder-rsbuild/templates/preview.ejs");
633
+ function getRandomPort(host) {
634
+ return new Promise((resolve3, reject) => {
635
+ const server2 = createServer();
636
+ server2.unref();
637
+ server2.on("error", reject);
638
+ server2.listen({ port: 0, host }, () => {
639
+ const { port } = server2.address();
640
+ server2.close(() => {
641
+ resolve3(port);
642
+ });
643
+ });
644
+ });
645
+ }
575
646
 
576
647
  export { bail, build, corePresets, executor, getConfig, getVirtualModules, importPipeline, previewMainTemplate, printDuration, rsbuild, start, toImportFn, toImportFnPart };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storybook-builder-rsbuild",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Rsbuild builder for Storybook",
5
5
  "keywords": [
6
6
  "storybook",
@@ -56,18 +56,9 @@
56
56
  "!src/**/*"
57
57
  ],
58
58
  "dependencies": {
59
- "@rsbuild/plugin-type-check": "0.7.9",
60
- "@storybook/addon-docs": "^8.0.10",
61
- "@storybook/channels": "^8.0.10",
62
- "@storybook/client-logger": "^8.0.10",
63
- "@storybook/core-common": "^8.0.10",
64
- "@storybook/core-events": "^8.0.10",
65
- "@storybook/core-webpack": "^8.0.10",
66
- "@storybook/node-logger": "^8.0.10",
67
- "@storybook/preview": "^8.0.10",
68
- "@storybook/preview-api": "^8.0.10",
69
- "@storybook/react-dom-shim": "^8.0.10",
70
- "@storybook/types": "^8.0.10",
59
+ "@rsbuild/plugin-type-check": "1.0.1-beta.0",
60
+ "@storybook/addon-docs": "^8.2.1",
61
+ "@storybook/core-webpack": "^8.2.1",
71
62
  "browser-assert": "^1.2.1",
72
63
  "case-sensitive-paths-webpack-plugin": "^2.4.0",
73
64
  "cjs-module-lexer": "^1.2.3",
@@ -79,6 +70,7 @@
79
70
  "magic-string": "^0.30.5",
80
71
  "path-browserify": "^1.0.1",
81
72
  "process": "^0.11.10",
73
+ "rsbuild-plugin-html-minifier-terser": "^1.1.0",
82
74
  "style-loader": "^3.3.1",
83
75
  "ts-dedent": "^2.2.0",
84
76
  "url": "^0.11.0",
@@ -86,7 +78,7 @@
86
78
  "util-deprecate": "^1.0.2"
87
79
  },
88
80
  "devDependencies": {
89
- "@rsbuild/core": "0.7.9",
81
+ "@rsbuild/core": "1.0.1-beta.0",
90
82
  "@types/express": "^4.17.21",
91
83
  "@types/fs-extra": "^11.0.4",
92
84
  "@types/node": "^18.0.0",
@@ -94,10 +86,12 @@
94
86
  "add": "^2.0.6",
95
87
  "pretty-hrtime": "^1.0.3",
96
88
  "slash": "^5.0.0",
89
+ "storybook": "8.2.1",
97
90
  "typescript": "^5.3.2"
98
91
  },
99
92
  "peerDependencies": {
100
- "@rsbuild/core": ">= 0.7.0"
93
+ "@rsbuild/core": ">= 1.0.0-alpha.9",
94
+ "storybook": "^8.2.1"
101
95
  },
102
96
  "peerDependenciesMeta": {
103
97
  "typescript": {
@@ -116,6 +110,7 @@
116
110
  "platform": "node"
117
111
  },
118
112
  "scripts": {
113
+ "build": "pnpm run prep --optimized",
119
114
  "check": "node --loader ../../scripts/node_modules/esbuild-register/loader.js -r ../../scripts/node_modules/esbuild-register/register.js ../../scripts/prepare/check.ts",
120
115
  "prep": "node --loader ../../scripts/node_modules/esbuild-register/loader.js -r ../../scripts/node_modules/esbuild-register/register.js ../../scripts/prepare/bundle.ts"
121
116
  }
@@ -1,7 +1,7 @@
1
1
  import { global } from '@storybook/global';
2
2
 
3
- import { ClientApi, PreviewWeb, addons, composeConfigs } from '@storybook/preview-api';
4
- import { createBrowserChannel } from '@storybook/channels';
3
+ import { ClientApi, PreviewWeb, addons, composeConfigs } from 'storybook/internal/preview-api';
4
+ import { createBrowserChannel } from 'storybook/internal/channels';
5
5
 
6
6
  import { importFn } from './{{storiesFilename}}';
7
7