UNPKG

storybook-builder-rsbuild

Version:
811 lines (793 loc) 28 kB
"use strict"; 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 });