storybook-builder-rsbuild
Version:
Rsbuild builder for Storybook
811 lines (793 loc) • 28 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// ../../node_modules/.pnpm/pretty-hrtime@1.0.3/node_modules/pretty-hrtime/index.js
var require_pretty_hrtime = __commonJS({
"../../node_modules/.pnpm/pretty-hrtime@1.0.3/node_modules/pretty-hrtime/index.js"(exports, module2) {
"use strict";
var minimalDesc = ["h", "min", "s", "ms", "\u03BCs", "ns"];
var verboseDesc = ["hour", "minute", "second", "millisecond", "microsecond", "nanosecond"];
var convert = [60 * 60, 60, 1, 1e6, 1e3, 1];
module2.exports = function(source, opts) {
var verbose, precise, i, spot, sourceAtStep, valAtStep, decimals, strAtStep, results, totalSeconds;
verbose = false;
precise = false;
if (opts) {
verbose = opts.verbose || false;
precise = opts.precise || false;
}
if (!Array.isArray(source) || source.length !== 2) {
return "";
}
if (typeof source[0] !== "number" || typeof source[1] !== "number") {
return "";
}
if (source[1] < 0) {
totalSeconds = source[0] + source[1] / 1e9;
source[0] = parseInt(totalSeconds);
source[1] = parseFloat((totalSeconds % 1).toPrecision(9)) * 1e9;
}
results = "";
for (i = 0; i < 6; i++) {
spot = i < 3 ? 0 : 1;
sourceAtStep = source[spot];
if (i !== 3 && i !== 0) {
sourceAtStep = sourceAtStep % convert[i - 1];
}
if (i === 2) {
sourceAtStep += source[1] / 1e9;
}
valAtStep = sourceAtStep / convert[i];
if (valAtStep >= 1) {
if (verbose) {
valAtStep = Math.floor(valAtStep);
}
if (!precise) {
decimals = valAtStep >= 10 ? 0 : 2;
strAtStep = valAtStep.toFixed(decimals);
} else {
strAtStep = valAtStep.toString();
}
if (strAtStep.indexOf(".") > -1 && strAtStep[strAtStep.length - 1] === "0") {
strAtStep = strAtStep.replace(/\.?0+$/, "");
}
if (results) {
results += " ";
}
results += strAtStep;
if (verbose) {
results += " " + verboseDesc[i];
if (strAtStep !== "1") {
results += "s";
}
} else {
results += " " + minimalDesc[i];
}
if (!verbose) {
break;
}
}
}
return results;
};
}
});
// src/index.ts
var src_exports = {};
__export(src_exports, {
bail: () => bail,
build: () => build,
corePresets: () => corePresets,
executor: () => executor,
getConfig: () => getConfig,
getVirtualModules: () => getVirtualModules,
importPipeline: () => importPipeline,
previewMainTemplate: () => previewMainTemplate,
printDuration: () => printDuration,
start: () => start,
toImportFn: () => toImportFn,
toImportFnPart: () => toImportFnPart
});
module.exports = __toCommonJS(src_exports);
var import_node_net = require("net");
var import_node_path5 = require("path");
var rsbuildReal = __toESM(require("@rsbuild/core"));
var import_fs_extra = __toESM(require("fs-extra"));
var import_pretty_hrtime = __toESM(require_pretty_hrtime());
var import_sirv = __toESM(require("sirv"));
var import_core_path = require("storybook/core-path");
var import_common3 = require("storybook/internal/common");
var import_server_errors = require("storybook/internal/server-errors");
// src/preview/iframe-rsbuild.config.ts
var import_node_path3 = require("path");
var import_core = require("@rsbuild/core");
var import_plugin_type_check = require("@rsbuild/plugin-type-check");
var import_preset = require("@storybook/addon-docs/dist/preset");
var import_case_sensitive_paths_webpack_plugin = __toESM(require("case-sensitive-paths-webpack-plugin"));
var import_rsbuild_plugin_html_minifier_terser = require("rsbuild-plugin-html-minifier-terser");
var import_common2 = require("storybook/internal/common");
var import_globals = require("storybook/internal/preview/globals");
var import_ts_dedent2 = require("ts-dedent");
// src/preview/virtual-module-mapping.ts
var import_node_fs = __toESM(require("fs"));
var import_node_path = __toESM(require("path"));
var import_node_path2 = require("path");
var import_core_webpack = require("@storybook/core-webpack");
var import_find_cache_dir = __toESM(require("find-cache-dir"));
// ../../node_modules/.pnpm/slash@5.1.0/node_modules/slash/index.js
function slash(path2) {
const isExtendedLengthPath = path2.startsWith("\\\\?\\");
if (isExtendedLengthPath) {
return path2;
}
return path2.replace(/\\/g, "/");
}
// src/preview/virtual-module-mapping.ts
var import_common = require("storybook/internal/common");
var import_ts_dedent = require("ts-dedent");
var getVirtualModules = async (options) => {
const virtualModules = {};
const cwd = process.cwd();
const workingDir = options.cache ? (
// TODO: This is a hard code cache dir, as Rspack doesn't support virtual modules now.
// Remove this when Rspack supports virtual modules.
(0, import_find_cache_dir.default)({
name: "storybook-rsbuild-builder",
create: true
})
) : process.cwd();
if (!import_node_fs.default.existsSync(workingDir)) {
import_node_fs.default.mkdirSync(workingDir, { recursive: true });
}
const isProd = options.configType === "PRODUCTION";
const nonNormalizedStories = await options.presets.apply("stories", []);
const entries = [];
const stories = (0, import_common.normalizeStories)(nonNormalizedStories, {
configDir: options.configDir,
workingDir
});
const realPathRelativeToCwd = import_node_path.default.relative(workingDir, cwd).split(import_node_path.default.sep).join(import_node_path.default.posix.sep);
const previewAnnotations = [
...(await options.presets.apply(
"previewAnnotations",
[],
options
)).map((entry) => {
if (typeof entry === "object") {
return entry.absolute;
}
return slash(entry);
}),
(0, import_common.loadPreviewOrConfigFile)(options)
].filter(Boolean);
const storiesFilename = "storybook-stories.js";
const storiesPath = (0, import_node_path2.resolve)((0, import_node_path2.join)(workingDir, storiesFilename));
const builderOptions = await (0, import_common.getBuilderOptions)(options);
const needPipelinedImport = !!builderOptions.lazyCompilation && !isProd;
virtualModules[storiesPath] = toImportFn(stories, realPathRelativeToCwd, {
needPipelinedImport
});
const configEntryPath = (0, import_node_path2.resolve)((0, import_node_path2.join)(workingDir, "storybook-config-entry.js"));
virtualModules[configEntryPath] = (await (0, import_common.readTemplate)(
require.resolve("storybook-builder-rsbuild/templates/virtualModuleModernEntry.js")
)).replaceAll(`'{{storiesFilename}}'`, `'./${storiesFilename}'`).replaceAll(
`'{{previewAnnotations}}'`,
previewAnnotations.filter(Boolean).map((entry) => `'${entry}'`).join(",")
).replaceAll(
`'{{previewAnnotations_requires}}'`,
previewAnnotations.filter(Boolean).map((entry) => `require('${entry}')`).join(",")
).replace(/\\/g, "\\\\");
entries.push(configEntryPath);
for (const [key, value] of Object.entries(virtualModules)) {
import_node_fs.default.writeFileSync(key, value);
}
return {
virtualModules,
entries
};
};
function toImportFnPart(specifier) {
const { directory, importPathMatcher } = specifier;
return import_ts_dedent.dedent`
async (path) => {
if (!${importPathMatcher}.exec(path)) {
return;
}
const pathRemainder = path.substring(${directory.length + 1});
return import(
/* webpackChunkName: "[request]" */
/* webpackInclude: ${(0, import_core_webpack.webpackIncludeRegexp)(specifier)} */
'${directory}/' + pathRemainder
);
}
`;
}
function toImportFn(stories, relativeOffset, { needPipelinedImport } = {}) {
let pipelinedImport = "const pipeline = (x) => x();";
if (needPipelinedImport) {
pipelinedImport = `
const importPipeline = ${importPipeline};
const pipeline = importPipeline();
`;
}
return import_ts_dedent.dedent`
${pipelinedImport}
const importers = [
${stories.map(toImportFnPart).join(",\n")}
];
export async function importFn(path) {
const offset = '${relativeOffset}';
for (let i = 0; i < importers.length; i++) {
const pathWithOffset = buildPath(offset, path)
const moduleExports = await pipeline(() => importers[i](pathWithOffset));
if (moduleExports) {
return moduleExports;
}
}
}
function buildPath(offset, path) {
if(path.startsWith('./')) {
return offset + '/' + path.substring(2);
} else {
return offset + '/' + path;
}
}
`;
}
function importPipeline() {
let importGate = Promise.resolve();
return async (importFn) => {
await importGate;
const moduleExportsPromise = importFn();
importGate = importGate.then(async () => {
await moduleExportsPromise;
});
return moduleExportsPromise;
};
}
// src/preview/iframe-rsbuild.config.ts
var getAbsolutePath = (input) => (0, import_node_path3.dirname)(require.resolve((0, import_node_path3.join)(input, "package.json")));
var maybeGetAbsolutePath = (input) => {
try {
return getAbsolutePath(input);
} catch (e) {
return false;
}
};
var builtInResolveExtensions = [
".mjs",
".js",
".jsx",
".ts",
".tsx",
".json",
".cjs"
];
var managerAPIPath = maybeGetAbsolutePath("@storybook/manager-api");
var componentsPath = maybeGetAbsolutePath("@storybook/components");
var globalPath = maybeGetAbsolutePath("@storybook/global");
var routerPath = maybeGetAbsolutePath("@storybook/router");
var themingPath = maybeGetAbsolutePath("@storybook/theming");
var storybookPaths = {
...managerAPIPath ? {
"@storybook/manager-api": managerAPIPath
} : {},
...componentsPath ? { "@storybook/components": componentsPath } : {},
...globalPath ? { "@storybook/global": globalPath } : {},
...routerPath ? { "@storybook/router": routerPath } : {},
...themingPath ? { "@storybook/theming": themingPath } : {}
};
var iframe_rsbuild_config_default = async (options, extraWebpackConfig) => {
const { rsbuildConfigPath, addonDocs } = await (0, import_common2.getBuilderOptions)(options);
const appliedDocsWebpack = await (0, import_preset.webpack)({}, { ...options, ...addonDocs });
const {
outputDir = (0, import_node_path3.join)(".", "public"),
quiet,
packageJson,
configType,
presets,
previewUrl,
typescriptOptions,
features
} = options;
const isProd = configType === "PRODUCTION";
const workingDir = process.cwd();
const [
coreOptions,
frameworkOptions,
envs,
logLevel,
headHtmlSnippet,
bodyHtmlSnippet,
template,
docsOptions,
entries,
nonNormalizedStories,
_modulesCount,
build2,
tagsOptions
] = await Promise.all([
presets.apply("core"),
presets.apply("frameworkOptions"),
presets.apply("env"),
presets.apply("logLevel", void 0),
presets.apply("previewHead"),
presets.apply("previewBody"),
presets.apply("previewMainTemplate"),
presets.apply("docs"),
presets.apply("entries", []),
presets.apply("stories", []),
options.cache?.get("modulesCount", 1e3),
options.presets.apply("build"),
presets.apply("tags", {})
]);
const stories = (0, import_common2.normalizeStories)(nonNormalizedStories, {
configDir: options.configDir,
workingDir
});
const shouldCheckTs = typescriptOptions.check && !typescriptOptions.skipCompiler;
const tsCheckOptions = typescriptOptions.checkOptions || {};
const builderOptions = await (0, import_common2.getBuilderOptions)(options);
const lazyCompilationConfig = builderOptions.lazyCompilation && !isProd ? {
lazyCompilation: { entries: false }
} : {};
if (!template) {
throw new Error(import_ts_dedent2.dedent`
Storybook's Webpack5 builder requires a template to be specified.
Somehow you've ended up with a falsy value for the template option.
Please file an issue at https://github.com/storybookjs/storybook with a reproduction.
`);
}
const externals = import_globals.globalsNameReferenceMap;
if (build2?.test?.disableBlocks) {
externals["@storybook/blocks"] = "__STORYBOOK_BLOCKS_EMPTY_MODULE__";
}
const { virtualModules: _virtualModules, entries: dynamicEntries } = await getVirtualModules(options);
if (!options.cache) {
throw new Error("Cache is required");
}
let contentFromConfig = {};
const { content } = await (0, import_core.loadConfig)({
cwd: workingDir,
path: rsbuildConfigPath
});
const { environments, ...withoutEnv } = content;
if (content.environments) {
const envCount = Object.keys(content.environments).length;
if (envCount === 0) {
contentFromConfig = withoutEnv;
} else if (envCount === 1) {
contentFromConfig = (0, import_core.mergeRsbuildConfig)(
withoutEnv,
content.environments[0]
);
} else {
const userEnv = builderOptions.environment;
if (typeof userEnv !== "string") {
throw new Error(
"You must specify an environment when there are multiple environments in the Rsbuild config."
);
}
if (Object.keys(content.environments).includes(userEnv)) {
contentFromConfig = (0, import_core.mergeRsbuildConfig)(
withoutEnv,
content.environments[userEnv]
);
} else {
throw new Error(
`The specified environment "${userEnv}" is not found in the Rsbuild config.`
);
}
}
} else {
contentFromConfig = content;
}
contentFromConfig.source ??= {};
contentFromConfig.source.entry = {};
const resourceFilename = isProd ? "static/media/[name].[contenthash:8][ext]" : "static/media/[path][name][ext]";
const rsbuildConfig = (0, import_core.mergeRsbuildConfig)(contentFromConfig, {
output: {
cleanDistPath: false,
assetPrefix: "/",
dataUriLimit: {
media: 1e4
},
sourceMap: {
js: options.build?.test?.disableSourcemaps ? false : "cheap-module-source-map",
css: !options.build?.test?.disableSourcemaps
},
distPath: {
root: (0, import_node_path3.resolve)(process.cwd(), outputDir)
},
filename: {
js: isProd ? "[name].[contenthash:8].iframe.bundle.js" : "[name].iframe.bundle.js",
image: resourceFilename,
font: resourceFilename,
media: resourceFilename
},
externals
},
server: {
// Storybook will handle public directory itself, disable Rsbuild's public dir
// feature to prevent overwriting Storybook's public directory.
publicDir: false
},
dev: {
assetPrefix: "/",
progressBar: !quiet
},
source: {
// TODO: Rspack doesn't support virtual modules yet, use cache dir instead
// we needed to explicitly set the module in `node_modules` to be compiled
include: [/[\\/]node_modules[\\/].*[\\/]storybook-config-entry\.js/],
alias: {
...storybookPaths
},
entry: {
// to avoid `It's not allowed to load an initial chunk on demand. The chunk name "main" is already used by an entrypoint` of
main: [...entries ?? [], ...dynamicEntries]
},
define: {
...(0, import_common2.stringifyProcessEnvs)(envs),
NODE_ENV: JSON.stringify(process.env.NODE_ENV)
}
},
performance: {
chunkSplit: {
strategy: "custom",
splitChunks: {
chunks: "all"
}
}
},
plugins: [
shouldCheckTs ? (0, import_plugin_type_check.pluginTypeCheck)(tsCheckOptions) : null,
(0, import_rsbuild_plugin_html_minifier_terser.pluginHtmlMinifierTerser)(() => ({
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: false,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true
}))
].filter(Boolean),
tools: {
rspack: (config, { addRules, appendPlugins, rspack, mergeConfig }) => {
addRules({
test: /\.stories\.([tj])sx?$|(stories|story)\.mdx$/,
exclude: /node_modules/,
enforce: "post",
use: [
{
loader: require.resolve("storybook-builder-rsbuild/loaders/export-order-loader")
}
]
});
config.resolve ??= {};
config.resolve.symlinks = !(0, import_common2.isPreservingSymlinks)();
config.resolve.extensions = Array.from(
/* @__PURE__ */ new Set([
...config.resolve.extensions ?? [],
...builtInResolveExtensions
])
);
config.watchOptions = {
ignored: /node_modules/
};
config.ignoreWarnings = [
...config.ignoreWarnings || [],
/export '\S+' was not found in 'global'/,
/export '\S+' was not found in '@storybook\/global'/
];
config.resolve ??= {};
config.resolve.fallback ??= {
stream: false,
path: require.resolve("path-browserify"),
assert: require.resolve("browser-assert"),
util: require.resolve("util"),
url: require.resolve("url"),
fs: false,
constants: require.resolve("constants-browserify")
};
config.optimization ??= {};
config.optimization.runtimeChunk = true;
config.optimization.usedExports = options.build?.test?.disableTreeShaking ? false : isProd;
config.optimization.moduleIds = "named";
config.module ??= {};
config.module.parser ??= {};
config.module.parser.javascript ??= {};
config.module.parser.javascript.exportsPresence = false;
appendPlugins(
[
new rspack.ProvidePlugin({
process: require.resolve("process/browser.js")
}),
new import_case_sensitive_paths_webpack_plugin.default()
].filter(Boolean)
);
config.experiments ??= {};
config.experiments = {
...config.experiments,
...lazyCompilationConfig
};
return mergeConfig(config, extraWebpackConfig, appliedDocsWebpack);
},
htmlPlugin: {
filename: "iframe.html",
// FIXME: `none` isn't a known option
chunksSortMode: "none",
alwaysWriteToDisk: true,
inject: false,
template,
templateParameters: {
version: packageJson?.version ?? "0.0.0-storybook-rsbuild-unknown-version",
globals: {
CONFIG_TYPE: configType,
LOGLEVEL: logLevel,
FRAMEWORK_OPTIONS: frameworkOptions,
CHANNEL_OPTIONS: coreOptions.channelOptions,
FEATURES: features,
PREVIEW_URL: previewUrl,
STORIES: stories.map((specifier) => ({
...specifier,
importPathMatcher: specifier.importPathMatcher.source
})),
DOCS_OPTIONS: docsOptions,
TAGS_OPTIONS: tagsOptions,
...build2?.test?.disableBlocks ? { __STORYBOOK_BLOCKS_EMPTY_MODULE__: {} } : {}
},
headHtmlSnippet,
bodyHtmlSnippet
}
}
}
});
return rsbuildConfig;
};
// src/react-shims.ts
var import_promises = require("fs/promises");
var import_node_path4 = require("path");
var getIsReactVersion18or19 = async (options) => {
const { legacyRootApi } = await options.presets.apply(
"frameworkOptions"
) || {};
if (legacyRootApi) {
return false;
}
const resolvedReact = await options.presets.apply(
"resolvedReact",
{}
);
const reactDom = resolvedReact.reactDom || (0, import_node_path4.dirname)(require.resolve("react-dom/package.json"));
if (!(0, import_node_path4.isAbsolute)(reactDom)) {
return false;
}
const { version } = JSON.parse(
await (0, import_promises.readFile)((0, import_node_path4.join)(reactDom, "package.json"), "utf-8")
);
return version.startsWith("18") || version.startsWith("19") || version.startsWith("0.0.0");
};
var applyReactShims = async (config, options) => {
const isReactVersion18 = await getIsReactVersion18or19(options);
if (isReactVersion18) {
return void 0;
}
return {
source: {
alias: {
"@storybook/react-dom-shim": "@storybook/react-dom-shim/dist/react-16"
}
}
};
};
// src/index.ts
var printDuration = (startTime) => (0, import_pretty_hrtime.default)(process.hrtime(startTime)).replace(" ms", " milliseconds").replace(" s", " seconds").replace(" m", " minutes");
var executor = {
get: async (options) => {
const rsbuildInstance = await options.presets.apply("rsbuildInstance") || rsbuildReal;
return rsbuildInstance;
}
};
var isObject = (val) => val != null && typeof val === "object" && Array.isArray(val) === false;
function nonNullables(value) {
return value !== void 0;
}
var rsbuild = async (_, options) => {
const { presets } = options;
const webpackAddons = await presets.apply("webpackAddons");
const resolvedWebpackAddons = (webpackAddons ?? []).map((preset) => {
const addonOptions = isObject(preset) ? preset.options || void 0 : void 0;
const name = isObject(preset) ? preset.name : preset;
return (0, import_common3.resolveAddonName)(options.configDir, name, addonOptions);
}).filter(nonNullables);
const { apply } = await (0, import_common3.getPresets)(resolvedWebpackAddons, options);
const webpackAddonsConfig = await apply(
"webpackFinal",
// TODO: using empty webpack config as base for now. It's better to using the composed rspack
// config in `iframe-rsbuild.config.ts` as base config. But when `tools.rspack` is an async function,
// the following `tools.rspack` raise an ` Promises are not supported` error.
{
output: {},
module: {},
plugins: [],
resolve: {},
devServer: {},
optimization: {},
performance: {},
externals: {},
experiments: {},
node: {},
stats: {},
entry: {}
},
options
);
let defaultConfig = await iframe_rsbuild_config_default(options, webpackAddonsConfig);
const shimsConfig = await applyReactShims(defaultConfig, options);
defaultConfig = rsbuildReal.mergeRsbuildConfig(
defaultConfig,
shimsConfig
);
const finalDefaultConfig = await presets.apply(
"rsbuildFinal",
defaultConfig,
options
);
return finalDefaultConfig;
};
var getConfig = async (options) => {
const { presets } = options;
const typescriptOptions = await presets.apply("typescript", {}, options);
const frameworkOptions = await presets.apply("frameworkOptions");
return rsbuild({}, {
...options,
typescriptOptions,
frameworkOptions
});
};
var server;
async function bail() {
return server?.close();
}
var start = async ({
startTime,
options,
router,
server: storybookServer,
channel
}) => {
const { createRsbuild } = await executor.get(options);
const config = await getConfig(options);
const rsbuildBuild = await createRsbuild({
cwd: process.cwd(),
rsbuildConfig: {
...config,
server: {
...config.server,
port: await getRandomPort(options.host),
host: options.host,
htmlFallback: false,
printUrls: false
}
}
});
const rsbuildServer = await rsbuildBuild.createDevServer();
const waitFirstCompileDone = new Promise((resolve3) => {
rsbuildBuild.onDevCompileDone(({ stats: stats2, isFirstCompile }) => {
if (!isFirstCompile) {
return;
}
resolve3(stats2);
});
});
server = rsbuildServer;
if (!rsbuildBuild) {
throw new import_server_errors.WebpackInvocationError({
// eslint-disable-next-line local-rules/no-uncategorized-errors
error: new Error("Missing Rsbuild build instance at runtime!")
});
}
const previewResolvedDir = (0, import_node_path5.join)(import_core_path.corePath, "dist/preview");
const previewDirOrigin = previewResolvedDir;
router.use(
"/sb-preview",
(0, import_sirv.default)(previewDirOrigin, { maxAge: 3e5, dev: true, immutable: true })
);
router.use(rsbuildServer.middlewares);
rsbuildServer.connectWebSocket({ server: storybookServer });
const stats = await waitFirstCompileDone;
await server.afterListen();
return {
bail,
stats,
totalTime: process.hrtime(startTime)
};
};
var build = async ({ options }) => {
const { createRsbuild } = await executor.get(options);
const config = await getConfig(options);
const rsbuildBuild = await createRsbuild({
cwd: process.cwd(),
rsbuildConfig: config
});
const previewResolvedDir = (0, import_node_path5.join)(import_core_path.corePath, "dist/preview");
const previewDirOrigin = previewResolvedDir;
const previewDirTarget = (0, import_node_path5.join)(options.outputDir || "", "sb-preview");
let stats;
rsbuildBuild.onAfterBuild((params) => {
stats = params.stats;
});
const previewFiles = import_fs_extra.default.copy(previewDirOrigin, previewDirTarget, {
filter: (src) => {
const { ext } = (0, import_node_path5.parse)(src);
if (ext) {
return ext === ".js";
}
return true;
}
});
rsbuildBuild.onAfterBuild((params) => {
stats = params.stats;
});
const [{ close }] = await Promise.all([rsbuildBuild.build(), previewFiles]);
await close();
return stats;
};
var corePresets = [(0, import_node_path5.join)(__dirname, "./preview-preset.js")];
var previewMainTemplate = () => require.resolve("storybook-builder-rsbuild/templates/preview.ejs");
function getRandomPort(host) {
return new Promise((resolve3, reject) => {
const server2 = (0, import_node_net.createServer)();
server2.unref();
server2.on("error", reject);
server2.listen({ port: 0, host }, () => {
const { port } = server2.address();
server2.close(() => {
resolve3(port);
});
});
});
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
bail,
build,
corePresets,
executor,
getConfig,
getVirtualModules,
importPipeline,
previewMainTemplate,
printDuration,
start,
toImportFn,
toImportFnPart
});