site-panzai/node_modules/@nuxt/vite-builder/dist/_chunks/dev-bundler.mjs

231 lines
7.3 KiB
JavaScript
Raw Normal View History

2026-11-13 13:57:04 +01:00
import { hashId, isCSS, toArray, uniq, writeManifest } from "./manifest.mjs";
import { builtinModules } from "node:module";
import { existsSync } from "node:fs";
import { isAbsolute, normalize, resolve } from "pathe";
import { isIgnored, logger } from "@nuxt/kit";
import { withTrailingSlash } from "ufo";
import escapeStringRegexp from "escape-string-regexp";
import { writeFile } from "node:fs/promises";
import { pathToFileURL } from "node:url";
import { genDynamicImport, genObjectFromRawEntries } from "knitwork";
import { debounce } from "perfect-debounce";
import { ExternalsDefaults, isExternal } from "externality";
function createIsExternal(viteServer, nuxt) {
const externalOpts = {
inline: [
/virtual:/,
/\.ts$/,
...ExternalsDefaults.inline || [],
...viteServer.config.ssr.noExternal && viteServer.config.ssr.noExternal !== true ? toArray(viteServer.config.ssr.noExternal) : []
],
external: [
"#shared",
new RegExp("^" + escapeStringRegexp(withTrailingSlash(resolve(nuxt.options.rootDir, nuxt.options.dir.shared)))),
...viteServer.config.ssr.external || [],
/node_modules/
],
resolve: {
modules: nuxt.options.modulesDir,
type: "module",
extensions: [
".ts",
".js",
".json",
".vue",
".mjs",
".jsx",
".tsx",
".wasm"
]
}
};
return (id) => isExternal(id, nuxt.options.rootDir, externalOpts);
}
async function transformRequest(opts, id) {
if (id && id.startsWith("/@id/__x00__")) id = "\0" + id.slice(12);
if (id && id.startsWith("/@id/")) id = id.slice(5);
if (id && !id.startsWith("/@fs/") && id.startsWith("/")) {
const resolvedPath = resolve(opts.viteServer.config.root, "." + id);
if (existsSync(resolvedPath)) id = resolvedPath;
}
id = id.replace(/^\/?(?=\w:)/, "/@fs/");
const externalId = id.replace(/\?v=\w+$|^\/@fs/, "");
if (await opts.isExternal(externalId)) return {
code: `(global, module, _, exports, importMeta, ssrImport, ssrDynamicImport, ssrExportAll) =>
${genDynamicImport(builtinModules.includes(externalId.split("node:").pop()) ? externalId : isAbsolute(externalId) ? pathToFileURL(externalId).href : externalId, { wrapper: false })}
.then(r => {
if (r.default && r.default.__esModule)
r = r.default
exports.default = r.default
ssrExportAll(r)
})
.catch(e => {
console.error(e)
throw new Error(${JSON.stringify(`[vite dev] Error loading external "${id}".`)})
})`,
deps: [],
dynamicDeps: []
};
const res = await opts.viteServer.transformRequest(id, { ssr: true }).catch((err) => {
logger.warn(`[SSR] Error transforming ${id}:`, err);
}) || {
code: "",
map: {},
deps: [],
dynamicDeps: []
};
return {
code: `async function (global, module, exports, __vite_ssr_exports__, __vite_ssr_import_meta__, __vite_ssr_import__, __vite_ssr_dynamic_import__, __vite_ssr_exportAll__) {
${res.code || "/* empty */"};
}`,
deps: res.deps || [],
dynamicDeps: res.dynamicDeps || []
};
}
async function transformRequestRecursive(opts, id, parent = "<entry>", chunks = {}) {
if (chunks[id]) {
chunks[id].parents.push(parent);
return;
}
const res = await transformRequest(opts, id);
const deps = uniq([...res.deps, ...res.dynamicDeps]);
chunks[id] = {
id,
code: res.code,
deps,
parents: [parent]
};
for (const dep of deps) await transformRequestRecursive(opts, dep, id, chunks);
return Object.values(chunks);
}
async function bundleRequest(opts, entryURL) {
const chunks = await transformRequestRecursive(opts, entryURL);
const listIds = (ids) => ids.map((id) => `// - ${id} (${hashId(id)})`).join("\n");
return {
code: [
chunks.map((chunk) => `
// --------------------
// Request: ${chunk.id}
// Parents: \n${listIds(chunk.parents)}
// Dependencies: \n${listIds(chunk.deps)}
// --------------------
const ${hashId(chunk.id + "-" + chunk.code)} = ${chunk.code}
`).join("\n"),
`const __modules__ = ${genObjectFromRawEntries(chunks.map((chunk) => [chunk.id, hashId(chunk.id + "-" + chunk.code)]))}`,
`
const __pendingModules__ = new Map()
const __pendingImports__ = new Map()
const __ssrContext__ = { global: globalThis }
function __ssrLoadModule__(url, urlStack = []) {
const pendingModule = __pendingModules__.get(url)
if (pendingModule) { return pendingModule }
const modulePromise = __instantiateModule__(url, urlStack)
__pendingModules__.set(url, modulePromise)
modulePromise.catch(() => { __pendingModules__.delete(url) })
.finally(() => { __pendingModules__.delete(url) })
return modulePromise
}
async function __instantiateModule__(url, urlStack) {
const mod = __modules__[url]
if (mod.stubModule) { return mod.stubModule }
const stubModule = { [Symbol.toStringTag]: 'Module' }
Object.defineProperty(stubModule, '__esModule', { value: true })
mod.stubModule = stubModule
// https://vitejs.dev/guide/api-hmr.html
const importMeta = { url, hot: { accept() {}, prune() {}, dispose() {}, invalidate() {}, decline() {}, on() {} } }
urlStack = urlStack.concat(url)
const isCircular = url => urlStack.includes(url)
const pendingDeps = []
const ssrImport = async (dep) => {
// TODO: Handle externals if dep[0] !== '.' | '/'
if (!isCircular(dep) && !__pendingImports__.get(dep)?.some(isCircular)) {
pendingDeps.push(dep)
if (pendingDeps.length === 1) {
__pendingImports__.set(url, pendingDeps)
}
await __ssrLoadModule__(dep, urlStack)
if (pendingDeps.length === 1) {
__pendingImports__.delete(url)
} else {
pendingDeps.splice(pendingDeps.indexOf(dep), 1)
}
}
return __modules__[dep].stubModule
}
function ssrDynamicImport (dep) {
// TODO: Handle dynamic import starting with . relative to url
return ssrImport(dep)
}
function ssrExportAll(sourceModule) {
for (const key in sourceModule) {
if (key !== 'default') {
try {
Object.defineProperty(stubModule, key, {
enumerable: true,
configurable: true,
get() { return sourceModule[key] }
})
} catch (_err) { }
}
}
}
const cjsModule = {
get exports () {
return stubModule.default
},
set exports (v) {
stubModule.default = v
},
}
await mod(
__ssrContext__.global,
cjsModule,
stubModule.default,
stubModule,
importMeta,
ssrImport,
ssrDynamicImport,
ssrExportAll
)
return stubModule
}
`,
`export default await __ssrLoadModule__(${JSON.stringify(entryURL)})`
].join("\n\n"),
ids: chunks.map((i) => i.id)
};
}
async function initViteDevBundler(ctx, onBuild) {
const viteServer = ctx.ssrServer;
const options = {
viteServer,
isExternal: createIsExternal(viteServer, ctx.nuxt)
};
const _doBuild = async () => {
const start = Date.now();
const { code, ids } = await bundleRequest(options, ctx.entry);
await writeFile(resolve(ctx.nuxt.options.buildDir, "dist/server/server.mjs"), code, "utf-8");
const manifestIds = [];
for (const i of ids) if (isCSS(i)) manifestIds.push(i.slice(1));
await writeManifest(ctx, manifestIds);
const time = Date.now() - start;
logger.success(`Vite server built in ${time}ms`);
await onBuild();
};
const doBuild = debounce(_doBuild);
await _doBuild();
viteServer.watcher.on("all", (_event, file) => {
file = normalize(file);
if (file.indexOf(ctx.nuxt.options.buildDir) === 0 || isIgnored(file)) return;
doBuild();
});
ctx.nuxt.hook("app:templatesGenerated", () => doBuild());
}
export { initViteDevBundler };