one
Version:
One is a new React Framework that makes Vite serve both native and web.
975 lines (959 loc) • 43 kB
JavaScript
import { createRequire } from "module";
import { cpus } from "os";
import Path, { join, relative, resolve } from "path";
import FSExtra from "fs-extra";
import MicroMatch from "micromatch";
import { mergeConfig, build as viteBuild } from "vite";
import { fillOptions, getOptimizeDeps, rollupRemoveUnusedImportsPlugin, build as vxrnBuild } from "vxrn";
import * as constants from "../constants.native.js";
import { setServerGlobals } from "../server/setServerGlobals.native.js";
import { getPathnameFromFilePath } from "../utils/getPathnameFromFilePath.native.js";
import { getRouterRootFromOneOptions } from "../utils/getRouterRootFromOneOptions.native.js";
import { isRolldown } from "../utils/isRolldown.native.js";
import { toAbsolute } from "../utils/toAbsolute.native.js";
import { buildVercelOutputDirectory } from "../vercel/build/buildVercelOutputDirectory.native.js";
import { getManifest } from "../vite/getManifest.native.js";
import { loadUserOneOptions } from "../vite/loadConfig.native.js";
import { runWithAsyncLocalContext } from "../vite/one-server-only.native.js";
import { buildPage, printBuildTimings } from "./buildPage.native.js";
import { checkNodeVersion } from "./checkNodeVersion.native.js";
import { getWorkerPool, terminateWorkerPool } from "./workerPool.native.js";
import { generateSitemap } from "./generateSitemap.native.js";
import { labelProcess } from "./label-process.native.js";
import { pLimit } from "../utils/pLimit.native.js";
var {
ensureDir,
writeJSON
} = FSExtra,
BUILD_CONCURRENCY = process.env.ONE_BUILD_CONCURRENCY ? Math.max(1, parseInt(process.env.ONE_BUILD_CONCURRENCY, 10)) : Math.max(1, Math.min(cpus().length, 8));
function shouldUseWorkers(oneOptions) {
var _oneOptions_build;
return process.env.ONE_BUILD_WORKERS === "0" ? !1 : process.env.ONE_BUILD_WORKERS === "1" ? !0 : (oneOptions == null || (_oneOptions_build = oneOptions.build) === null || _oneOptions_build === void 0 ? void 0 : _oneOptions_build.workers) !== !1;
}
process.on("uncaughtException", function (err) {
console.error(err?.message || err);
});
async function build(args) {
var _ref, _args_skipEnv, _oneOptions_web, _oneOptions_build, _oneOptions_build_server, _oneOptions_build1, _oneOptions_build2, _oneOptions_web1, _oneOptions_web2;
process.env.IS_VXRN_CLI = "true", process.env.NODE_ENV ? process.env.NODE_ENV !== "production" && console.warn(`
\u26A0\uFE0F Warning: NODE_ENV is set to "${process.env.NODE_ENV}" (builds default to "production")
`) : process.env.NODE_ENV = "production", labelProcess("build"), checkNodeVersion(), setServerGlobals();
var {
oneOptions
} = await loadUserOneOptions("build"),
routerRoot = getRouterRootFromOneOptions(oneOptions);
!((_oneOptions_web = oneOptions.web) === null || _oneOptions_web === void 0) && _oneOptions_web.defaultRenderMode && (process.env.ONE_DEFAULT_RENDER_MODE = oneOptions.web.defaultRenderMode);
var manifest = getManifest({
routerRoot
}),
serverOutputFormat = ((_oneOptions_build = oneOptions.build) === null || _oneOptions_build === void 0 ? void 0 : _oneOptions_build.server) === !1 ? "esm" : (_ref = (_oneOptions_build1 = oneOptions.build) === null || _oneOptions_build1 === void 0 || (_oneOptions_build_server = _oneOptions_build1.server) === null || _oneOptions_build_server === void 0 ? void 0 : _oneOptions_build_server.outputFormat) !== null && _ref !== void 0 ? _ref : "esm",
buildStartTime = performance.now(),
vxrnOutput = await vxrnBuild({
skipEnv: (_args_skipEnv = args.skipEnv) !== null && _args_skipEnv !== void 0 ? _args_skipEnv : oneOptions.skipEnv,
server: oneOptions.server,
build: {
analyze: !0,
server: ((_oneOptions_build2 = oneOptions.build) === null || _oneOptions_build2 === void 0 ? void 0 : _oneOptions_build2.server) === !1 ? !1 : {
outputFormat: serverOutputFormat
}
}
}, args),
bundleTime = performance.now() - buildStartTime;
if (console.info(`
\u23F1\uFE0F vite bundle: ${(bundleTime / 1e3).toFixed(2)}s
`), !vxrnOutput || args.platform !== "web") return;
var options = await fillOptions(vxrnOutput.options, {
mode: "prod"
}),
{
optimizeDeps
} = getOptimizeDeps("build"),
apiBuildConfig = mergeConfig(
// feels like this should build off the *server* build config not web
vxrnOutput.webBuildConfig, {
configFile: !1,
appType: "custom",
optimizeDeps
});
async function buildCustomRoutes(subFolder, routes) {
var _ref2,
_oneOptions_build_api,
_oneOptions_build3,
_oneOptions_build_api1,
_oneOptions_build12,
_oneOptions_build_api2,
_oneOptions_build22,
input = routes.reduce(function (entries, param) {
var {
page,
file: file2
} = param;
return entries[page.slice(1) + ".js"] = join(routerRoot, file2), entries;
}, {}),
outputFormat = (_ref2 = oneOptions == null || (_oneOptions_build3 = oneOptions.build) === null || _oneOptions_build3 === void 0 || (_oneOptions_build_api = _oneOptions_build3.api) === null || _oneOptions_build_api === void 0 ? void 0 : _oneOptions_build_api.outputFormat) !== null && _ref2 !== void 0 ? _ref2 : serverOutputFormat,
treeshake = oneOptions == null || (_oneOptions_build12 = oneOptions.build) === null || _oneOptions_build12 === void 0 || (_oneOptions_build_api1 = _oneOptions_build12.api) === null || _oneOptions_build_api1 === void 0 ? void 0 : _oneOptions_build_api1.treeshake,
mergedConfig = mergeConfig(apiBuildConfig, {
appType: "custom",
configFile: !1,
// plugins: [
// nodeExternals({
// exclude: optimizeDeps.include,
// }) as any,
// ],
define: {
...vxrnOutput.processEnvDefines
},
ssr: {
noExternal: !0,
external: ["react", "react-dom"],
optimizeDeps
},
build: {
ssr: !0,
emptyOutDir: !1,
outDir: `dist/${subFolder}`,
copyPublicDir: !1,
minify: !1,
rollupOptions: {
treeshake: treeshake ?? {
moduleSideEffects: !1
},
plugins: [
// otherwise rollup is leaving commonjs-only top level imports...
outputFormat === "esm" ? rollupRemoveUnusedImportsPlugin : null].filter(Boolean),
// too many issues
// treeshake: {
// moduleSideEffects: false,
// },
// prevents it from shaking out the exports
preserveEntrySignatures: "strict",
input,
external: function (id2) {
return !1;
},
output: {
entryFileNames: "[name]",
exports: "auto",
...(outputFormat === "esm" ? {
format: "esm",
esModule: !0
} : {
format: "cjs",
// Preserve folder structure and use .cjs extension
entryFileNames: function (chunkInfo) {
var name = chunkInfo.name.replace(/\.js$/, ".cjs");
return name;
},
chunkFileNames: function (chunkInfo) {
var dir = Path.dirname(chunkInfo.name),
name = Path.basename(chunkInfo.name, Path.extname(chunkInfo.name));
return Path.join(dir, `${name}-[hash].cjs`);
},
assetFileNames: function (assetInfo) {
var _assetInfo_name,
name = (_assetInfo_name = assetInfo.name) !== null && _assetInfo_name !== void 0 ? _assetInfo_name : "",
dir = Path.dirname(name),
baseName = Path.basename(name, Path.extname(name)),
ext = Path.extname(name);
return Path.join(dir, `${baseName}-[hash]${ext}`);
}
})
}
}
}
}),
userApiBuildConf = (_oneOptions_build22 = oneOptions.build) === null || _oneOptions_build22 === void 0 || (_oneOptions_build_api2 = _oneOptions_build22.api) === null || _oneOptions_build_api2 === void 0 ? void 0 : _oneOptions_build_api2.config,
finalApiBuildConf = userApiBuildConf ? mergeConfig(mergedConfig, userApiBuildConf) : mergedConfig,
output2 = await viteBuild(
// allow user merging api build config
finalApiBuildConf);
return output2;
}
var builtMiddlewares = {},
apiPromise = manifest.apiRoutes.length ? (console.info(`
\u{1F528} build api routes
`), buildCustomRoutes("api", manifest.apiRoutes)) : Promise.resolve(null),
middlewarePromise = manifest.middlewareRoutes.length ? (console.info(`
\u{1F528} build middlewares
`), buildCustomRoutes("middlewares", manifest.middlewareRoutes)) : Promise.resolve(null),
[apiOutput, middlewareBuildInfo] = await Promise.all([apiPromise, middlewarePromise]);
if (middlewareBuildInfo) {
var _iteratorNormalCompletion = !0,
_didIteratorError = !1,
_iteratorError = void 0;
try {
for (var _loop = function () {
var middleware = _step.value,
absoluteRoot = resolve(process.cwd(), options.root),
fullPath = join(absoluteRoot, routerRoot, middleware.file),
outChunks = middlewareBuildInfo.output.filter(function (x) {
return x.type === "chunk";
}),
chunk2 = outChunks.find(function (x) {
return x.facadeModuleId === fullPath;
});
if (!chunk2) throw new Error("internal err finding middleware");
builtMiddlewares[middleware.file] = join("dist", "middlewares", chunk2.fileName);
}, _iterator = manifest.middlewareRoutes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) _loop();
} catch (err) {
_didIteratorError = !0, _iteratorError = err;
} finally {
try {
!_iteratorNormalCompletion && _iterator.return != null && _iterator.return();
} finally {
if (_didIteratorError) throw _iteratorError;
}
}
}
globalThis.require = createRequire(join(import.meta.url, ".."));
var assets = [],
builtRoutes = [],
sitemapData = [],
collectImportsCache = /* @__PURE__ */new Map(),
cssFileContentsCache = /* @__PURE__ */new Map(),
limit = pLimit(BUILD_CONCURRENCY),
useWorkers = shouldUseWorkers(oneOptions),
workerPool = useWorkers ? getWorkerPool(BUILD_CONCURRENCY) : null;
workerPool && (await workerPool.initialize());
var staticStartTime = performance.now(),
modeLabel = useWorkers ? `workers: ${workerPool?.size}` : `concurrency: ${BUILD_CONCURRENCY}`;
console.info(`
\u{1F528} build static routes (${modeLabel})
`);
var staticDir = join("dist/static"),
clientDir = join("dist/client");
if (await ensureDir(staticDir), !vxrnOutput.serverOutput) throw new Error("No server output");
var clientChunksBySource = /* @__PURE__ */new Map();
if (vxrnOutput.clientOutput) {
var _iteratorNormalCompletion1 = !0,
_didIteratorError1 = !1,
_iteratorError1 = void 0;
try {
for (var _iterator1 = vxrnOutput.clientOutput[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = !0) {
var chunk = _step1.value;
chunk.type === "chunk" && chunk.facadeModuleId && clientChunksBySource.set(chunk.facadeModuleId, {
fileName: chunk.fileName,
imports: chunk.imports || []
});
}
} catch (err) {
_didIteratorError1 = !0, _iteratorError1 = err;
} finally {
try {
!_iteratorNormalCompletion1 && _iterator1.return != null && _iterator1.return();
} finally {
if (_didIteratorError1) throw _iteratorError1;
}
}
}
var outputEntries = [...vxrnOutput.serverOutput.entries()],
layoutServerPaths = /* @__PURE__ */new Map(),
_iteratorNormalCompletion2 = !0,
_didIteratorError2 = !1,
_iteratorError2 = void 0;
try {
for (var _iterator2 = outputEntries[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = !0) {
var [, output] = _step2.value;
if (output.type !== "asset") {
var id = output.facadeModuleId || "",
file = Path.basename(id);
if (file.startsWith("_layout") && id.includes(`/${routerRoot}/`)) {
var relativePath = relative(process.cwd(), id).replace(`${routerRoot}/`, ""),
contextKey = `./${relativePath}`;
layoutServerPaths.set(contextKey, output.fileName);
}
}
}
} catch (err) {
_didIteratorError2 = !0, _iteratorError2 = err;
} finally {
try {
!_iteratorNormalCompletion2 && _iterator2.return != null && _iterator2.return();
} finally {
if (_didIteratorError2) throw _iteratorError2;
}
}
var routeByPath = /* @__PURE__ */new Map(),
_iteratorNormalCompletion3 = !0,
_didIteratorError3 = !1,
_iteratorError3 = void 0;
try {
for (var _iterator3 = manifest.pageRoutes[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = !0) {
var route = _step3.value;
if (route.file) {
var routePath = `${routerRoot}${route.file.slice(1)}`;
routeByPath.set(routePath, route);
}
}
} catch (err) {
_didIteratorError3 = !0, _iteratorError3 = err;
} finally {
try {
!_iteratorNormalCompletion3 && _iterator3.return != null && _iterator3.return();
} finally {
if (_didIteratorError3) throw _iteratorError3;
}
}
var _iteratorNormalCompletion4 = !0,
_didIteratorError4 = !1,
_iteratorError4 = void 0;
try {
for (var _loop1 = async function () {
var [index, output2] = _step4.value,
_ref2,
_ref1,
_vxrnOutput_buildArgs,
_foundRoute_layouts,
_oneOptions_web3,
_oneOptions_web12,
_exported_generateStaticParams;
if (output2.type === "asset") return assets.push(output2), "continue";
var id2 = output2.facadeModuleId || "",
file2 = Path.basename(id2);
if (!id2 || file2[0] === "_" || file2.includes("entry-server") || id2.includes("+api") || !id2.includes(`/${routerRoot}/`)) return "continue";
var relativeId = relative(process.cwd(), id2).replace(`${routerRoot}/`, "/"),
onlyBuild = (_vxrnOutput_buildArgs = vxrnOutput.buildArgs) === null || _vxrnOutput_buildArgs === void 0 ? void 0 : _vxrnOutput_buildArgs.only;
if (onlyBuild && !MicroMatch.contains(relativeId, onlyBuild)) return "continue";
var foundRoute = void 0,
_iteratorNormalCompletion10 = !0,
_didIteratorError10 = !1,
_iteratorError10 = void 0;
try {
for (var _iterator10 = routeByPath[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = !0) {
var [routePath2, route3] = _step10.value;
if (id2.endsWith(routePath2)) {
foundRoute = route3;
break;
}
}
} catch (err) {
_didIteratorError10 = !0, _iteratorError10 = err;
} finally {
try {
!_iteratorNormalCompletion10 && _iterator10.return != null && _iterator10.return();
} finally {
if (_didIteratorError10) throw _iteratorError10;
}
}
if (!foundRoute) return "continue";
var clientChunk = clientChunksBySource.get(id2),
manifestKey = `${routerRoot}${foundRoute.file.slice(1)}`,
clientManifestEntry = vxrnOutput.clientManifest[manifestKey];
if (!clientChunk && foundRoute.type !== "spa" && foundRoute.type !== "ssg") return console.warn(`No client chunk found for route: ${id2}`), "continue";
if (foundRoute.loaderServerPath = output2.fileName, foundRoute.layouts) {
var _iteratorNormalCompletion12 = !0,
_didIteratorError12 = !1,
_iteratorError12 = void 0;
try {
for (var _iterator12 = foundRoute.layouts[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = !0) {
var layout = _step12.value,
serverPath = layoutServerPaths.get(layout.contextKey);
serverPath && (layout.loaderServerPath = serverPath);
}
} catch (err) {
_didIteratorError12 = !0, _iteratorError12 = err;
} finally {
try {
!_iteratorNormalCompletion12 && _iterator12.return != null && _iterator12.return();
} finally {
if (_didIteratorError12) throw _iteratorError12;
}
}
}
function collectImports(entry2) {
var {
type = "js"
} = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {},
{
imports = [],
css
} = entry2,
cacheKey = `${entry2.file || imports.join(",")}:${type}`,
cached = collectImportsCache.get(cacheKey);
if (cached) return cached;
var result = [...new Set([...(type === "js" ? imports : css || []), ...imports.flatMap(function (name) {
var found = vxrnOutput.clientManifest[name];
return found || console.warn("No found imports", name, vxrnOutput.clientManifest), collectImports(found, {
type
});
})].flat().filter(function (x) {
return x && (type === "css" || x.endsWith(".js"));
}).map(function (x) {
return type === "css" || x.startsWith("assets/") ? x : `assets/${x.slice(1)}`;
}))];
return collectImportsCache.set(cacheKey, result), result;
}
var entryImports = collectImports(clientManifestEntry || {}),
layoutEntries = (_ref2 = (_foundRoute_layouts = foundRoute.layouts) === null || _foundRoute_layouts === void 0 ? void 0 : _foundRoute_layouts.flatMap(function (layout2) {
var clientKey2 = `${routerRoot}${layout2.contextKey.slice(1)}`,
found = vxrnOutput.clientManifest[clientKey2];
return found || [];
})) !== null && _ref2 !== void 0 ? _ref2 : [],
layoutImports = layoutEntries.flatMap(function (entry2) {
return [entry2.file, ...collectImports(entry2)];
}),
routePreloads = {},
rootLayoutKey = `${routerRoot}/_layout.tsx`,
rootLayoutEntry = vxrnOutput.clientManifest[rootLayoutKey];
if (rootLayoutEntry && (routePreloads[`/${rootLayoutKey}`] = `/${rootLayoutEntry.file}`), foundRoute.layouts) {
var _iteratorNormalCompletion22 = !0,
_didIteratorError22 = !1,
_iteratorError22 = void 0;
try {
for (var _iterator22 = foundRoute.layouts[Symbol.iterator](), _step22; !(_iteratorNormalCompletion22 = (_step22 = _iterator22.next()).done); _iteratorNormalCompletion22 = !0) {
var layout1 = _step22.value,
clientKey = `${routerRoot}${layout1.contextKey.slice(1)}`,
entry = vxrnOutput.clientManifest[clientKey];
entry && (routePreloads[`/${clientKey}`] = `/${entry.file}`);
}
} catch (err) {
_didIteratorError22 = !0, _iteratorError22 = err;
} finally {
try {
!_iteratorNormalCompletion22 && _iterator22.return != null && _iterator22.return();
} finally {
if (_didIteratorError22) throw _iteratorError22;
}
}
}
if (clientChunk) {
var routeKey = `/${routerRoot}${foundRoute.file.slice(1)}`;
routePreloads[routeKey] = `/${clientChunk.fileName}`;
} else if (clientManifestEntry) {
var routeKey1 = `/${routerRoot}${foundRoute.file.slice(1)}`;
routePreloads[routeKey1] = `/${clientManifestEntry.file}`;
}
var preloadSetupFilePreloads = function () {
if (!oneOptions.setupFile) return [];
var clientSetupFile = typeof oneOptions.setupFile == "string" ? oneOptions.setupFile : oneOptions.setupFile.client;
if (!clientSetupFile) return [];
var needle = clientSetupFile.replace(/^\.\//, "");
for (var file3 in vxrnOutput.clientManifest) if (file3 === needle) {
var entry2 = vxrnOutput.clientManifest[file3];
return [entry2.file];
}
return [];
}(),
allPreloads = [... /* @__PURE__ */new Set([...preloadSetupFilePreloads,
// add the route entry js (like ./app/index.ts) - prefer direct chunk lookup
...(clientChunk ? [clientChunk.fileName] : clientManifestEntry ? [clientManifestEntry.file] : []),
// add the virtual entry
vxrnOutput.clientManifest["virtual:one-entry"].file, ...entryImports, ...layoutImports])].map(function (path2) {
return `/${path2}`;
}),
scriptLoadingMode = (_oneOptions_web3 = oneOptions.web) === null || _oneOptions_web3 === void 0 ? void 0 : _oneOptions_web3.experimental_scriptLoading,
useDeferredLoading = scriptLoadingMode === "defer-non-critical",
useAggressiveLCP = scriptLoadingMode === "after-lcp-aggressive",
needsSeparatedPreloads = useDeferredLoading || useAggressiveLCP,
criticalPreloads = needsSeparatedPreloads ? [... /* @__PURE__ */new Set([...preloadSetupFilePreloads,
// add the virtual entry (framework bootstrap)
vxrnOutput.clientManifest["virtual:one-entry"].file,
// add the route entry js (like ./app/index.ts) - prefer direct chunk lookup
...(clientChunk ? [clientChunk.fileName] : clientManifestEntry ? [clientManifestEntry.file] : []),
// add layout files (but not their deep imports)
...layoutEntries.map(function (entry2) {
return entry2.file;
})])].map(function (path2) {
return `/${path2}`;
}) : void 0,
deferredPreloads = needsSeparatedPreloads ? [... /* @__PURE__ */new Set([...entryImports, ...layoutEntries.flatMap(function (entry2) {
return collectImports(entry2);
})])].filter(function (path2) {
return !criticalPreloads.includes(`/${path2}`);
}).map(function (path2) {
return `/${path2}`;
}) : void 0,
preloads2 = needsSeparatedPreloads ? [...criticalPreloads, ...deferredPreloads] : allPreloads,
allEntries = [clientManifestEntry, ...layoutEntries].filter(Boolean),
allCSS = [... /* @__PURE__ */new Set([
// css from entry imports
...allEntries.flatMap(function (entry2) {
return collectImports(entry2, {
type: "css"
});
}).map(function (path2) {
return `/${path2}`;
}),
// root-level css (handles cssCodeSplit: false)
...Object.entries(vxrnOutput.clientManifest).filter(function (param) {
var [key] = param;
return key.endsWith(".css");
}).map(function (param) {
var [, entry2] = param;
return `/${entry2.file}`;
})])],
allCSSContents = void 0;
!((_oneOptions_web12 = oneOptions.web) === null || _oneOptions_web12 === void 0) && _oneOptions_web12.inlineLayoutCSS && (allCSSContents = await Promise.all(allCSS.map(async function (cssPath) {
var cached = cssFileContentsCache.get(cssPath);
if (cached !== void 0) return cached;
var filePath = join(clientDir, cssPath);
try {
var content = await FSExtra.readFile(filePath, "utf-8");
return cssFileContentsCache.set(cssPath, content), content;
} catch {
return console.warn(`[one] Warning: Could not read CSS file ${filePath}`), cssFileContentsCache.set(cssPath, ""), "";
}
}))), process.env.DEBUG && console.info("[one] building routes", {
foundRoute,
layoutEntries,
allEntries,
allCSS
});
var serverJsPath = join("dist/server", output2.fileName),
exported = void 0;
try {
exported = await import(toAbsolute(serverJsPath));
} catch (err) {
throw console.error("Error importing page (original error)", err), new Error(`Error importing page: ${serverJsPath}`, {
cause: err
});
}
var isDynamic = !!Object.keys(foundRoute.routeKeys).length;
if (foundRoute.type === "ssg" && isDynamic && !foundRoute.page.includes("+not-found") && !foundRoute.page.includes("_sitemap") && !exported.generateStaticParams) throw new Error(`[one] Error: Missing generateStaticParams
Route ${foundRoute.page} of type ${foundRoute.type} must export generateStaticParams so build can complete.
See docs on generateStaticParams:
https://onestack.dev/docs/routing-exports#generatestaticparams
`);
var paramsList = (_ref1 = await ((_exported_generateStaticParams = exported.generateStaticParams) === null || _exported_generateStaticParams === void 0 ? void 0 : _exported_generateStaticParams.call(exported))) !== null && _ref1 !== void 0 ? _ref1 : [{}];
console.info(`
[build] page ${relativeId} (with ${paramsList.length} routes)
`), process.env.DEBUG && console.info("paramsList", JSON.stringify(paramsList, null, 2));
var routeSitemapExport = exported.sitemap,
isAfterLCPMode = scriptLoadingMode === "after-lcp" || scriptLoadingMode === "after-lcp-aggressive",
useAfterLCP = foundRoute.type === "ssg" && isAfterLCPMode,
useAfterLCPAggressive = foundRoute.type === "ssg" && scriptLoadingMode === "after-lcp-aggressive",
shouldCollectSitemap = foundRoute.type !== "api" && foundRoute.type !== "layout" && !foundRoute.isNotFound && !foundRoute.page.includes("+not-found") && !foundRoute.page.includes("_sitemap"),
pageBuilds = paramsList.map(function (params) {
var path2 = getPathnameFromFilePath(relativeId, params, foundRoute.type === "ssg");
return workerPool ? (console.info(` \u21A6 route ${path2}`), workerPool.buildPage({
serverEntry: vxrnOutput.serverEntry,
path: path2,
relativeId,
params,
foundRoute,
clientManifestEntry,
staticDir,
clientDir,
builtMiddlewares,
serverJsPath,
preloads: preloads2,
allCSS,
routePreloads,
allCSSContents,
criticalPreloads,
deferredPreloads,
useAfterLCP,
useAfterLCPAggressive
}).then(function (built2) {
return {
built: built2,
path: path2
};
})) : limit(async function () {
console.info(` \u21A6 route ${path2}`);
var built2 = await runWithAsyncLocalContext(async function () {
return await buildPage(vxrnOutput.serverEntry, path2, relativeId, params, foundRoute, clientManifestEntry, staticDir, clientDir, builtMiddlewares, serverJsPath, preloads2, allCSS, routePreloads, allCSSContents, criticalPreloads, deferredPreloads, useAfterLCP, useAfterLCPAggressive);
});
return {
built: built2,
path: path2
};
});
}),
results = await Promise.all(pageBuilds),
_iteratorNormalCompletion32 = !0,
_didIteratorError32 = !1,
_iteratorError32 = void 0;
try {
for (var _iterator32 = results[Symbol.iterator](), _step32; !(_iteratorNormalCompletion32 = (_step32 = _iterator32.next()).done); _iteratorNormalCompletion32 = !0) {
var {
built,
path
} = _step32.value;
builtRoutes.push(built), shouldCollectSitemap && sitemapData.push({
path,
routeExport: routeSitemapExport
});
}
} catch (err) {
_didIteratorError32 = !0, _iteratorError32 = err;
} finally {
try {
!_iteratorNormalCompletion32 && _iterator32.return != null && _iterator32.return();
} finally {
if (_didIteratorError32) throw _iteratorError32;
}
}
}, _iterator4 = outputEntries[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = !0) await _loop1();
} catch (err) {
_didIteratorError4 = !0, _iteratorError4 = err;
} finally {
try {
!_iteratorNormalCompletion4 && _iterator4.return != null && _iterator4.return();
} finally {
if (_didIteratorError4) throw _iteratorError4;
}
}
workerPool && (await terminateWorkerPool());
var staticTime = performance.now() - staticStartTime;
console.info(`
\u23F1\uFE0F static routes: ${(staticTime / 1e3).toFixed(2)}s (${builtRoutes.length} pages)
`), printBuildTimings(), await moveAllFiles(staticDir, clientDir), await FSExtra.rm(staticDir, {
force: !0,
recursive: !0
});
var routeMap = {},
routeToBuildInfo = {},
pathToRoute = {},
preloads = {},
cssPreloads = {},
loaders = {},
_iteratorNormalCompletion5 = !0,
_didIteratorError5 = !1,
_iteratorError5 = void 0;
try {
for (var _iterator5 = builtRoutes[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = !0) {
var route1 = _step5.value;
route1.cleanPath.includes("*") || (routeMap[route1.cleanPath] = route1.htmlPath);
var {
// dont include loaderData it can be huge
loaderData: _loaderData,
...rest
} = route1;
routeToBuildInfo[route1.routeFile] = rest;
var _iteratorNormalCompletion6 = !0,
_didIteratorError6 = !1,
_iteratorError6 = void 0;
try {
for (var _iterator6 = getCleanPaths([route1.path, route1.cleanPath])[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = !0) {
var p = _step6.value;
pathToRoute[p] = route1.routeFile;
}
} catch (err) {
_didIteratorError6 = !0, _iteratorError6 = err;
} finally {
try {
!_iteratorNormalCompletion6 && _iterator6.return != null && _iterator6.return();
} finally {
if (_didIteratorError6) throw _iteratorError6;
}
}
preloads[route1.preloadPath] = !0, cssPreloads[route1.cssPreloadPath] = !0, loaders[route1.loaderPath] = !0;
}
} catch (err) {
_didIteratorError5 = !0, _iteratorError5 = err;
} finally {
try {
!_iteratorNormalCompletion5 && _iterator5.return != null && _iterator5.return();
} finally {
if (_didIteratorError5) throw _iteratorError5;
}
}
function createBuildManifestRoute(route3) {
var {
layouts,
...built
} = route3;
layouts?.length && (built.layouts = layouts.map(function (layout) {
return {
contextKey: layout.contextKey,
loaderServerPath: layout.loaderServerPath
};
}));
var buildInfo = builtRoutes.find(function (x) {
return x.routeFile === route3.file;
});
if (built.middlewares && buildInfo?.middlewares) {
var _iteratorNormalCompletion10 = !0,
_didIteratorError10 = !1,
_iteratorError10 = void 0;
try {
for (var _iterator10 = built.middlewares.entries()[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = !0) {
var [index, mw] = _step10.value;
mw.contextKey = buildInfo.middlewares[index];
}
} catch (err) {
_didIteratorError10 = !0, _iteratorError10 = err;
} finally {
try {
!_iteratorNormalCompletion10 && _iterator10.return != null && _iterator10.return();
} finally {
if (_didIteratorError10) throw _iteratorError10;
}
}
}
return buildInfo && (built.loaderPath = buildInfo.loaderPath), built;
}
var buildInfoForWriting = {
oneOptions,
routeToBuildInfo,
pathToRoute,
manifest: {
pageRoutes: manifest.pageRoutes.map(createBuildManifestRoute),
apiRoutes: manifest.apiRoutes.map(createBuildManifestRoute),
allRoutes: manifest.allRoutes.map(createBuildManifestRoute)
},
routeMap,
constants: JSON.parse(JSON.stringify({
...constants
})),
preloads,
cssPreloads,
loaders,
useRolldown: await isRolldown()
};
await writeJSON(toAbsolute("dist/buildInfo.json"), buildInfoForWriting);
var sitemapConfig = (_oneOptions_web1 = oneOptions.web) === null || _oneOptions_web1 === void 0 ? void 0 : _oneOptions_web1.sitemap;
if (sitemapConfig) {
var sitemapOptions = typeof sitemapConfig == "boolean" ? {} : sitemapConfig,
sitemapXml = generateSitemap(sitemapData, sitemapOptions),
sitemapPath = join(clientDir, "sitemap.xml");
await FSExtra.writeFile(sitemapPath, sitemapXml), console.info(`
\u{1F4C4} generated sitemap.xml (${sitemapData.length} URLs)
`);
}
var postBuildLogs = [],
platform = (_oneOptions_web2 = oneOptions.web) === null || _oneOptions_web2 === void 0 ? void 0 : _oneOptions_web2.deploy;
switch (platform && postBuildLogs.push(`[one.build] platform ${platform}`), platform) {
case "vercel":
{
var vercelJsonPath = join(options.root, "vercel.json");
if (FSExtra.existsSync(vercelJsonPath)) try {
var vercelConfig = JSON.parse(FSExtra.readFileSync(vercelJsonPath, "utf-8"));
vercelConfig.cleanUrls || (console.warn(`
\u26A0\uFE0F Warning: Your vercel.json is missing "cleanUrls": true`), console.warn(" Without this, direct navigation to SSG pages will 404."), console.warn(` Add "cleanUrls": true to your vercel.json to fix this.
`));
} catch {}
await buildVercelOutputDirectory({
apiOutput,
buildInfoForWriting,
clientDir,
oneOptionsRoot: options.root,
postBuildLogs
});
break;
}
case "cloudflare":
{
var pageRouteMap = [],
apiRouteMap = [],
middlewareRouteMap = [],
_iteratorNormalCompletion7 = !0,
_didIteratorError7 = !1,
_iteratorError7 = void 0;
try {
for (var _iterator7 = Object.entries(buildInfoForWriting.routeToBuildInfo)[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = !0) {
var [routeFile, info] = _step7.value;
if (info.serverJsPath) {
var importPath = "./" + info.serverJsPath.replace(/^dist\//, "");
pageRouteMap.push(` '${routeFile}': () => import('${importPath}')`);
}
}
} catch (err) {
_didIteratorError7 = !0, _iteratorError7 = err;
} finally {
try {
!_iteratorNormalCompletion7 && _iterator7.return != null && _iterator7.return();
} finally {
if (_didIteratorError7) throw _iteratorError7;
}
}
var _iteratorNormalCompletion8 = !0,
_didIteratorError8 = !1,
_iteratorError8 = void 0;
try {
for (var _iterator8 = buildInfoForWriting.manifest.apiRoutes[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = !0) {
var route2 = _step8.value;
if (route2.file) {
var apiFileName = route2.page.slice(1).replace(/\[/g, "_").replace(/\]/g, "_"),
importPath1 = `./api/${apiFileName}.js`;
apiRouteMap.push(` '${route2.page}': () => import('${importPath1}')`);
}
}
} catch (err) {
_didIteratorError8 = !0, _iteratorError8 = err;
} finally {
try {
!_iteratorNormalCompletion8 && _iterator8.return != null && _iterator8.return();
} finally {
if (_didIteratorError8) throw _iteratorError8;
}
}
var _iteratorNormalCompletion9 = !0,
_didIteratorError9 = !1,
_iteratorError9 = void 0;
try {
for (var _iterator9 = Object.entries(builtMiddlewares)[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = !0) {
var [middlewareFile, builtPath] = _step9.value,
importPath2 = "./" + builtPath.replace(/^dist\//, "");
middlewareRouteMap.push(` '${builtPath}': () => import('${importPath2}')`);
}
} catch (err) {
_didIteratorError9 = !0, _iteratorError9 = err;
} finally {
try {
!_iteratorNormalCompletion9 && _iterator9.return != null && _iterator9.return();
} finally {
if (_didIteratorError9) throw _iteratorError9;
}
}
var workerSrcPath = join(options.root, "dist", "_worker-src.js"),
workerCode = `// Polyfill MessageChannel for React SSR (not available in Cloudflare Workers by default)
if (typeof MessageChannel === 'undefined') {
globalThis.MessageChannel = class MessageChannel {
constructor() {
this.port1 = { postMessage: () => {}, onmessage: null, close: () => {} }
this.port2 = { postMessage: () => {}, onmessage: null, close: () => {} }
}
}
}
import { serve, setFetchStaticHtml } from 'one/serve-worker'
// Lazy import map - modules load on-demand when route is matched
const lazyRoutes = {
serverEntry: () => import('./server/_virtual_one-entry.js'),
pages: {
${pageRouteMap.join(`,
`)}
},
api: {
${apiRouteMap.join(`,
`)}
},
middlewares: {
${middlewareRouteMap.join(`,
`)}
}
}
const buildInfo = ${JSON.stringify(buildInfoForWriting)}
let app
export default {
async fetch(request, env, ctx) {
if (!app) {
app = await serve(buildInfo, lazyRoutes)
}
// Set up static HTML fetcher for this request (uses ASSETS binding)
if (env.ASSETS) {
setFetchStaticHtml(async (path) => {
try {
const url = new URL(request.url)
url.pathname = path
const assetResponse = await env.ASSETS.fetch(new Request(url))
if (assetResponse && assetResponse.ok) {
return await assetResponse.text()
}
} catch (e) {
// Asset not found
}
return null
})
}
try {
// Try the app first
const response = await app.fetch(request, env, ctx)
// If no route matched (404) or no response, try serving static assets
if (!response || response.status === 404) {
if (env.ASSETS) {
try {
const assetResponse = await env.ASSETS.fetch(request)
// If asset exists, return it
if (assetResponse && assetResponse.status !== 404) {
return assetResponse
}
} catch (e) {
// Asset not found, continue with original response
}
}
}
return response
} finally {
// Clean up per-request state
setFetchStaticHtml(null)
}
}
}
`;
await FSExtra.writeFile(workerSrcPath, workerCode), console.info(`
[cloudflare] Bundling worker...`), await viteBuild({
root: options.root,
logLevel: "warn",
build: {
outDir: "dist",
emptyOutDir: !1,
// Use SSR mode with node target for proper Node.js module resolution
ssr: workerSrcPath,
rollupOptions: {
external: [
// React Native dev tools - not needed in production
"@react-native/dev-middleware", "@react-native/debugger-shell", "metro", "metro-core", "metro-runtime",
// Native modules that can't run in workers
/\.node$/],
output: {
entryFileNames: "worker.js",
format: "es",
// Keep dynamic imports separate for lazy loading
inlineDynamicImports: !1
}
},
minify: !0,
target: "esnext"
},
define: {
"process.env.NODE_ENV": JSON.stringify("production"),
"process.env.VITE_ENVIRONMENT": JSON.stringify("ssr")
},
resolve: {
conditions: ["workerd", "worker", "node", "module", "default"]
},
ssr: {
target: "node",
noExternal: !0
}
}), await FSExtra.remove(workerSrcPath);
var wranglerConfig = `{
"name": "one-app",
"main": "worker.js",
"compatibility_date": "2024-12-05",
"compatibility_flags": ["nodejs_compat"],
"find_additional_modules": true,
"rules": [
{ "type": "ESModule", "globs": ["./server/**/*.js"], "fallthrough": true },
{ "type": "ESModule", "globs": ["./api/**/*.js"], "fallthrough": true },
{ "type": "ESModule", "globs": ["./middlewares/**/*.js"], "fallthrough": true }
],
"assets": { "directory": "client", "binding": "ASSETS", "run_worker_first": true }
}
`;
await FSExtra.writeFile(join(options.root, "dist", "wrangler.jsonc"), wranglerConfig), postBuildLogs.push("Cloudflare worker bundled at dist/worker.js"), postBuildLogs.push("To deploy: cd dist && wrangler deploy");
break;
}
}
postBuildLogs.length && (console.info(`
`), postBuildLogs.forEach(function (log) {
console.info(` \xB7 ${log}`);
})), console.info(`
\u{1F49B} build complete
`);
}
var TRAILING_INDEX_REGEX = /\/index(\.(web))?/;
function getCleanPaths(possiblePaths) {
return Array.from(new Set(Array.from(new Set(possiblePaths)).flatMap(function (p) {
var paths = [p];
if (p.match(TRAILING_INDEX_REGEX)) {
var pathWithTrailingIndexRemoved = p.replace(TRAILING_INDEX_REGEX, "");
paths.push(pathWithTrailingIndexRemoved), paths.push(pathWithTrailingIndexRemoved + "/");
}
return paths;
})));
}
async function moveAllFiles(src, dest) {
try {
await FSExtra.copy(src, dest, {
overwrite: !0,
errorOnExist: !1
});
} catch (err) {
console.error("Error moving files:", err);
}
}
export { build };
//# sourceMappingURL=build.native.js.map