From 6060256c62c1317f664d8267b1d97075300e189f Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 16 Jul 2024 18:07:42 +0200 Subject: [PATCH] Use fs and vm for async chunk loading in Node (#8722) ### Description Use `fs` and `vm` when loading chunks asynchronously in Node, to not block the thread while reading large chunks Closes PACK-411 ### Testing Instructions Using the `test/e2e/app-dir/dynamic/` Next.js tests --- .../js/src/nodejs/runtime.ts | 48 +++++++++++++++---- .../output/[turbopack]_runtime.js | 37 ++++++++++---- .../output/[turbopack]_runtime.js.map | 2 +- 3 files changed, 70 insertions(+), 17 deletions(-) diff --git a/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts b/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts index 38dbc4918ec25..54a0244f524fd 100644 --- a/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts +++ b/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts @@ -49,6 +49,8 @@ type ModuleFactory = ( ) => undefined; const url = require("url"); +const fs = require("fs/promises"); +const vm = require("vm"); const moduleFactories: ModuleFactories = Object.create(null); const moduleCache: ModuleCache = Object.create(null); @@ -118,15 +120,45 @@ async function loadChunkAsync( source: SourceInfo, chunkData: ChunkData ): Promise { - return new Promise((resolve, reject) => { - try { - loadChunk(chunkData, source); - } catch (err) { - reject(err); - return; + const chunkPath = typeof chunkData === "string" ? chunkData : chunkData.path; + if (!chunkPath.endsWith(".js")) { + // We only support loading JS chunks in Node.js. + // This branch can be hit when trying to load a CSS chunk. + return; + } + + const resolved = path.resolve(RUNTIME_ROOT, chunkPath); + + try { + const contents = await fs.readFile(resolved, "utf-8"); + + const module = { + exports: {}, + }; + vm.runInThisContext( + "(function(module, exports, require, __dirname, __filename) {" + + contents + + "\n})", + resolved + )(module, module.exports, require, path.dirname(resolved), resolved); + + const chunkModules: ModuleFactories = module.exports; + for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) { + if (!moduleFactories[moduleId]) { + moduleFactories[moduleId] = moduleFactory; + } } - resolve(); - }); + } catch (e) { + let errorMessage = `Failed to load chunk ${chunkPath}`; + + if (source) { + errorMessage += ` from ${stringifySourceInfo(source)}`; + } + + throw new Error(errorMessage, { + cause: e, + }); + } } function loadWebAssembly(chunkPath: ChunkPath, imports: WebAssembly.Imports) { diff --git a/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js b/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js index 57d30e4001002..d1ea5ab0f4fdf 100644 --- a/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js +++ b/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js @@ -428,6 +428,8 @@ function stringifySourceInfo(source) { } } const url = require("url"); +const fs = require("fs/promises"); +const vm = require("vm"); const moduleFactories = Object.create(null); const moduleCache = Object.create(null); /** @@ -476,15 +478,34 @@ function loadChunkPath(chunkPath, source) { } } async function loadChunkAsync(source, chunkData) { - return new Promise((resolve, reject)=>{ - try { - loadChunk(chunkData, source); - } catch (err) { - reject(err); - return; + const chunkPath = typeof chunkData === "string" ? chunkData : chunkData.path; + if (!chunkPath.endsWith(".js")) { + // We only support loading JS chunks in Node.js. + // This branch can be hit when trying to load a CSS chunk. + return; + } + const resolved = path.resolve(RUNTIME_ROOT, chunkPath); + try { + const contents = await fs.readFile(resolved, "utf-8"); + const module1 = { + exports: {} + }; + vm.runInThisContext("(function(module, exports, require, __dirname, __filename) {" + contents + "\n})", resolved)(module1, module1.exports, require, path.dirname(resolved), resolved); + const chunkModules = module1.exports; + for (const [moduleId, moduleFactory] of Object.entries(chunkModules)){ + if (!moduleFactories[moduleId]) { + moduleFactories[moduleId] = moduleFactory; + } } - resolve(); - }); + } catch (e) { + let errorMessage = `Failed to load chunk ${chunkPath}`; + if (source) { + errorMessage += ` from ${stringifySourceInfo(source)}`; + } + throw new Error(errorMessage, { + cause: e + }); + } } function loadWebAssembly(chunkPath, imports) { const resolved = path.resolve(RUNTIME_ROOT, chunkPath); diff --git a/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map b/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map index 988fc1672184d..bf446d5d55b18 100644 --- a/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map +++ b/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map @@ -6,5 +6,5 @@ {"offset": {"line": 327, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/shared-node/base-externals-utils.ts"],"sourcesContent":["/// \n\n/// A 'base' utilities to support runtime can have externals.\n/// Currently this is for node.js / edge runtime both.\n/// If a fn requires node.js specific behavior, it should be placed in `node-external-utils` instead.\n\nasync function externalImport(id: ModuleId) {\n let raw;\n try {\n raw = await import(id);\n } catch (err) {\n // TODO(alexkirsz) This can happen when a client-side module tries to load\n // an external module we don't provide a shim for (e.g. querystring, url).\n // For now, we fail semi-silently, but in the future this should be a\n // compilation error.\n throw new Error(`Failed to load external module ${id}: ${err}`);\n }\n\n if (raw && raw.__esModule && raw.default && \"default\" in raw.default) {\n return interopEsm(raw.default, createNS(raw), true);\n }\n\n return raw;\n}\n\nfunction externalRequire(\n id: ModuleId,\n esm: boolean = false\n): Exports | EsmNamespaceObject {\n let raw;\n try {\n raw = require(id);\n } catch (err) {\n // TODO(alexkirsz) This can happen when a client-side module tries to load\n // an external module we don't provide a shim for (e.g. querystring, url).\n // For now, we fail semi-silently, but in the future this should be a\n // compilation error.\n throw new Error(`Failed to load external module ${id}: ${err}`);\n }\n\n if (!esm || raw.__esModule) {\n return raw;\n }\n\n return interopEsm(raw, createNS(raw), true);\n}\n\nexternalRequire.resolve = (\n id: string,\n options?: {\n paths?: string[];\n }\n) => {\n return require.resolve(id, options);\n};\n"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,6DAA6D;AAC7D,sDAAsD;AACtD,qGAAqG;AAErG,eAAe,eAAe,EAAY;IACxC,IAAI;IACJ,IAAI;QACF,MAAM,MAAM,MAAM,CAAC;IACrB,EAAE,OAAO,KAAK;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,qBAAqB;QACrB,MAAM,IAAI,MAAM,CAAC,+BAA+B,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC;IAChE;IAEA,IAAI,OAAO,IAAI,UAAU,IAAI,IAAI,OAAO,IAAI,aAAa,IAAI,OAAO,EAAE;QACpE,OAAO,WAAW,IAAI,OAAO,EAAE,SAAS,MAAM;IAChD;IAEA,OAAO;AACT;AAEA,SAAS,gBACP,EAAY,EACZ,MAAe,KAAK;IAEpB,IAAI;IACJ,IAAI;QACF,MAAM,QAAQ;IAChB,EAAE,OAAO,KAAK;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,qBAAqB;QACrB,MAAM,IAAI,MAAM,CAAC,+BAA+B,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC;IAChE;IAEA,IAAI,CAAC,OAAO,IAAI,UAAU,EAAE;QAC1B,OAAO;IACT;IAEA,OAAO,WAAW,KAAK,SAAS,MAAM;AACxC;AAEA,gBAAgB,OAAO,GAAG,CACxB,IACA;IAIA,OAAO,QAAQ,OAAO,CAAC,IAAI;AAC7B"}}, {"offset": {"line": 366, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/shared-node/node-externals-utils.ts"],"sourcesContent":["declare var RUNTIME_PUBLIC_PATH: string;\ndeclare var OUTPUT_ROOT: string;\ndeclare var ASSET_PREFIX: string;\n\nconst path = require(\"path\");\n\nconst relativePathToRuntimeRoot = path.relative(RUNTIME_PUBLIC_PATH, \".\");\n// Compute the relative path to the `distDir`.\nconst relativePathToDistRoot = path.relative(\n path.join(OUTPUT_ROOT, RUNTIME_PUBLIC_PATH),\n \".\"\n);\nconst RUNTIME_ROOT = path.resolve(__filename, relativePathToRuntimeRoot);\n// Compute the absolute path to the root, by stripping distDir from the absolute path to this file.\nconst ABSOLUTE_ROOT = path.resolve(__filename, relativePathToDistRoot);\n\n/**\n * Returns an absolute path to the given module path.\n * Module path should be relative, either path to a file or a directory.\n *\n * This fn allows to calculate an absolute path for some global static values, such as\n * `__dirname` or `import.meta.url` that Turbopack will not embeds in compile time.\n * See ImportMetaBinding::code_generation for the usage.\n */\nfunction resolveAbsolutePath(modulePath?: string): string {\n if (modulePath) {\n return path.join(ABSOLUTE_ROOT, modulePath);\n }\n return ABSOLUTE_ROOT;\n}\n"],"names":[],"mappings":"AAIA,MAAM,OAAO,QAAQ;AAErB,MAAM,4BAA4B,KAAK,QAAQ,CAAC,qBAAqB;AACrE,8CAA8C;AAC9C,MAAM,yBAAyB,KAAK,QAAQ,CAC1C,KAAK,IAAI,CAAC,aAAa,sBACvB;AAEF,MAAM,eAAe,KAAK,OAAO,CAAC,YAAY;AAC9C,mGAAmG;AACnG,MAAM,gBAAgB,KAAK,OAAO,CAAC,YAAY;AAE/C;;;;;;;CAOC,GACD,SAAS,oBAAoB,UAAmB;IAC9C,IAAI,YAAY;QACd,OAAO,KAAK,IAAI,CAAC,eAAe;IAClC;IACA,OAAO;AACT"}}, {"offset": {"line": 386, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/shared-node/node-wasm-utils.ts"],"sourcesContent":["/// \n\nfunction readWebAssemblyAsResponse(path: string) {\n const { createReadStream } = require(\"fs\") as typeof import(\"fs\");\n const { Readable } = require(\"stream\") as typeof import(\"stream\");\n\n const stream = createReadStream(path);\n\n // @ts-ignore unfortunately there's a slight type mismatch with the stream.\n return new Response(Readable.toWeb(stream), {\n headers: {\n \"content-type\": \"application/wasm\",\n },\n });\n}\n\nasync function compileWebAssemblyFromPath(\n path: string\n): Promise {\n const response = readWebAssemblyAsResponse(path);\n\n return await WebAssembly.compileStreaming(response);\n}\n\nasync function instantiateWebAssemblyFromPath(\n path: string,\n importsObj: WebAssembly.Imports\n): Promise {\n const response = readWebAssemblyAsResponse(path);\n\n const { instance } = await WebAssembly.instantiateStreaming(\n response,\n importsObj\n );\n\n return instance.exports;\n}\n"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,SAAS,0BAA0B,IAAY;IAC7C,MAAM,EAAE,gBAAgB,EAAE,GAAG,QAAQ;IACrC,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ;IAE7B,MAAM,SAAS,iBAAiB;IAEhC,2EAA2E;IAC3E,OAAO,IAAI,SAAS,SAAS,KAAK,CAAC,SAAS;QAC1C,SAAS;YACP,gBAAgB;QAClB;IACF;AACF;AAEA,eAAe,2BACb,IAAY;IAEZ,MAAM,WAAW,0BAA0B;IAE3C,OAAO,MAAM,YAAY,gBAAgB,CAAC;AAC5C;AAEA,eAAe,+BACb,IAAY,EACZ,UAA+B;IAE/B,MAAM,WAAW,0BAA0B;IAE3C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,YAAY,oBAAoB,CACzD,UACA;IAGF,OAAO,SAAS,OAAO;AACzB"}}, - {"offset": {"line": 407, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/nodejs/runtime.ts"],"sourcesContent":["/// \n/// \n/// \n/// \n\nenum SourceType {\n /**\n * The module was instantiated because it was included in an evaluated chunk's\n * runtime.\n */\n Runtime = 0,\n /**\n * The module was instantiated because a parent module imported it.\n */\n Parent = 1,\n}\n\ntype SourceInfo =\n | {\n type: SourceType.Runtime;\n chunkPath: ChunkPath;\n }\n | {\n type: SourceType.Parent;\n parentId: ModuleId;\n };\n\nfunction stringifySourceInfo(source: SourceInfo): string {\n switch (source.type) {\n case SourceType.Runtime:\n return `runtime for chunk ${source.chunkPath}`;\n case SourceType.Parent:\n return `parent module ${source.parentId}`;\n }\n}\n\ntype ExternalRequire = (id: ModuleId) => Exports | EsmNamespaceObject;\ntype ExternalImport = (id: ModuleId) => Promise;\n\ninterface TurbopackNodeBuildContext extends TurbopackBaseContext {\n R: ResolvePathFromModule;\n x: ExternalRequire;\n y: ExternalImport;\n}\n\ntype ModuleFactory = (\n this: Module[\"exports\"],\n context: TurbopackNodeBuildContext\n) => undefined;\n\nconst url = require(\"url\");\n\nconst moduleFactories: ModuleFactories = Object.create(null);\nconst moduleCache: ModuleCache = Object.create(null);\n\n/**\n * Returns an absolute path to the given module's id.\n */\nfunction createResolvePathFromModule(\n resolver: (moduleId: string) => Exports\n): (moduleId: string) => string {\n return function resolvePathFromModule(moduleId: string): string {\n const exported = resolver(moduleId);\n const exportedPath = exported?.default ?? exported;\n if (typeof exportedPath !== \"string\") {\n return exported as any;\n }\n\n const strippedAssetPrefix = exportedPath.slice(ASSET_PREFIX.length);\n const resolved = path.resolve(\n ABSOLUTE_ROOT,\n OUTPUT_ROOT,\n strippedAssetPrefix\n );\n\n return url.pathToFileURL(resolved);\n };\n}\n\nfunction loadChunk(chunkData: ChunkData, source?: SourceInfo): void {\n if (typeof chunkData === \"string\") {\n return loadChunkPath(chunkData, source);\n } else {\n return loadChunkPath(chunkData.path, source);\n }\n}\n\nfunction loadChunkPath(chunkPath: ChunkPath, source?: SourceInfo): void {\n if (!chunkPath.endsWith(\".js\")) {\n // We only support loading JS chunks in Node.js.\n // This branch can be hit when trying to load a CSS chunk.\n return;\n }\n\n try {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n const chunkModules: ModuleFactories = require(resolved);\n\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n moduleFactories[moduleId] = moduleFactory;\n }\n }\n } catch (e) {\n let errorMessage = `Failed to load chunk ${chunkPath}`;\n\n if (source) {\n errorMessage += ` from ${stringifySourceInfo(source)}`;\n }\n\n throw new Error(errorMessage, {\n cause: e,\n });\n }\n}\n\nasync function loadChunkAsync(\n source: SourceInfo,\n chunkData: ChunkData\n): Promise {\n return new Promise((resolve, reject) => {\n try {\n loadChunk(chunkData, source);\n } catch (err) {\n reject(err);\n return;\n }\n resolve();\n });\n}\n\nfunction loadWebAssembly(chunkPath: ChunkPath, imports: WebAssembly.Imports) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n\n return instantiateWebAssemblyFromPath(resolved, imports);\n}\n\nfunction loadWebAssemblyModule(chunkPath: ChunkPath) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n\n return compileWebAssemblyFromPath(resolved);\n}\n\nfunction instantiateModule(id: ModuleId, source: SourceInfo): Module {\n const moduleFactory = moduleFactories[id];\n if (typeof moduleFactory !== \"function\") {\n // This can happen if modules incorrectly handle HMR disposes/updates,\n // e.g. when they keep a `setTimeout` around which still executes old code\n // and contains e.g. a `require(\"something\")` call.\n let instantiationReason;\n switch (source.type) {\n case SourceType.Runtime:\n instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`;\n break;\n case SourceType.Parent:\n instantiationReason = `because it was required from module ${source.parentId}`;\n break;\n }\n throw new Error(\n `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`\n );\n }\n\n let parents: ModuleId[];\n switch (source.type) {\n case SourceType.Runtime:\n parents = [];\n break;\n case SourceType.Parent:\n // No need to add this module as a child of the parent module here, this\n // has already been taken care of in `getOrInstantiateModuleFromParent`.\n parents = [source.parentId];\n break;\n }\n\n const module: Module = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n parents,\n children: [],\n namespaceObject: undefined,\n };\n moduleCache[id] = module;\n\n // NOTE(alexkirsz) This can fail when the module encounters a runtime error.\n try {\n const r = commonJsRequire.bind(null, module);\n moduleFactory.call(module.exports, {\n a: asyncModule.bind(null, module),\n e: module.exports,\n r,\n t: runtimeRequire,\n x: externalRequire,\n y: externalImport,\n f: moduleContext,\n i: esmImport.bind(null, module),\n s: esmExport.bind(null, module, module.exports),\n j: dynamicExport.bind(null, module, module.exports),\n v: exportValue.bind(null, module),\n n: exportNamespace.bind(null, module),\n m: module,\n c: moduleCache,\n M: moduleFactories,\n l: loadChunkAsync.bind(null, { type: SourceType.Parent, parentId: id }),\n w: loadWebAssembly,\n u: loadWebAssemblyModule,\n g: globalThis,\n P: resolveAbsolutePath,\n U: relativeURL,\n R: createResolvePathFromModule(r),\n __dirname: module.id.replace(/(^|\\/)[\\/]+$/, \"\"),\n });\n } catch (error) {\n module.error = error as any;\n throw error;\n }\n\n module.loaded = true;\n if (module.namespaceObject && module.exports !== module.namespaceObject) {\n // in case of a circular dependency: cjs1 -> esm2 -> cjs1\n interopEsm(module.exports, module.namespaceObject);\n }\n\n return module;\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it if it is not cached.\n */\nfunction getOrInstantiateModuleFromParent(\n id: ModuleId,\n sourceModule: Module\n): Module {\n const module = moduleCache[id];\n\n if (sourceModule.children.indexOf(id) === -1) {\n sourceModule.children.push(id);\n }\n\n if (module) {\n if (module.parents.indexOf(sourceModule.id) === -1) {\n module.parents.push(sourceModule.id);\n }\n\n return module;\n }\n\n return instantiateModule(id, {\n type: SourceType.Parent,\n parentId: sourceModule.id,\n });\n}\n\n/**\n * Instantiates a runtime module.\n */\nfunction instantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath });\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it as a runtime module if it is not cached.\n */\nfunction getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n const module = moduleCache[moduleId];\n if (module) {\n if (module.error) {\n throw module.error;\n }\n return module;\n }\n\n return instantiateRuntimeModule(moduleId, chunkPath);\n}\n\nmodule.exports = {\n getOrInstantiateRuntimeModule,\n loadChunk,\n};\n"],"names":[],"mappings":"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"}}] + {"offset": {"line": 407, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/nodejs/runtime.ts"],"sourcesContent":["/// \n/// \n/// \n/// \n\nenum SourceType {\n /**\n * The module was instantiated because it was included in an evaluated chunk's\n * runtime.\n */\n Runtime = 0,\n /**\n * The module was instantiated because a parent module imported it.\n */\n Parent = 1,\n}\n\ntype SourceInfo =\n | {\n type: SourceType.Runtime;\n chunkPath: ChunkPath;\n }\n | {\n type: SourceType.Parent;\n parentId: ModuleId;\n };\n\nfunction stringifySourceInfo(source: SourceInfo): string {\n switch (source.type) {\n case SourceType.Runtime:\n return `runtime for chunk ${source.chunkPath}`;\n case SourceType.Parent:\n return `parent module ${source.parentId}`;\n }\n}\n\ntype ExternalRequire = (id: ModuleId) => Exports | EsmNamespaceObject;\ntype ExternalImport = (id: ModuleId) => Promise;\n\ninterface TurbopackNodeBuildContext extends TurbopackBaseContext {\n R: ResolvePathFromModule;\n x: ExternalRequire;\n y: ExternalImport;\n}\n\ntype ModuleFactory = (\n this: Module[\"exports\"],\n context: TurbopackNodeBuildContext\n) => undefined;\n\nconst url = require(\"url\");\nconst fs = require(\"fs/promises\");\nconst vm = require(\"vm\");\n\nconst moduleFactories: ModuleFactories = Object.create(null);\nconst moduleCache: ModuleCache = Object.create(null);\n\n/**\n * Returns an absolute path to the given module's id.\n */\nfunction createResolvePathFromModule(\n resolver: (moduleId: string) => Exports\n): (moduleId: string) => string {\n return function resolvePathFromModule(moduleId: string): string {\n const exported = resolver(moduleId);\n const exportedPath = exported?.default ?? exported;\n if (typeof exportedPath !== \"string\") {\n return exported as any;\n }\n\n const strippedAssetPrefix = exportedPath.slice(ASSET_PREFIX.length);\n const resolved = path.resolve(\n ABSOLUTE_ROOT,\n OUTPUT_ROOT,\n strippedAssetPrefix\n );\n\n return url.pathToFileURL(resolved);\n };\n}\n\nfunction loadChunk(chunkData: ChunkData, source?: SourceInfo): void {\n if (typeof chunkData === \"string\") {\n return loadChunkPath(chunkData, source);\n } else {\n return loadChunkPath(chunkData.path, source);\n }\n}\n\nfunction loadChunkPath(chunkPath: ChunkPath, source?: SourceInfo): void {\n if (!chunkPath.endsWith(\".js\")) {\n // We only support loading JS chunks in Node.js.\n // This branch can be hit when trying to load a CSS chunk.\n return;\n }\n\n try {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n const chunkModules: ModuleFactories = require(resolved);\n\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n moduleFactories[moduleId] = moduleFactory;\n }\n }\n } catch (e) {\n let errorMessage = `Failed to load chunk ${chunkPath}`;\n\n if (source) {\n errorMessage += ` from ${stringifySourceInfo(source)}`;\n }\n\n throw new Error(errorMessage, {\n cause: e,\n });\n }\n}\n\nasync function loadChunkAsync(\n source: SourceInfo,\n chunkData: ChunkData\n): Promise {\n const chunkPath = typeof chunkData === \"string\" ? chunkData : chunkData.path;\n if (!chunkPath.endsWith(\".js\")) {\n // We only support loading JS chunks in Node.js.\n // This branch can be hit when trying to load a CSS chunk.\n return;\n }\n\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n\n try {\n const contents = await fs.readFile(resolved, \"utf-8\");\n\n const module = {\n exports: {},\n };\n vm.runInThisContext(\n \"(function(module, exports, require, __dirname, __filename) {\" +\n contents +\n \"\\n})\",\n resolved\n )(module, module.exports, require, path.dirname(resolved), resolved);\n\n const chunkModules: ModuleFactories = module.exports;\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n moduleFactories[moduleId] = moduleFactory;\n }\n }\n } catch (e) {\n let errorMessage = `Failed to load chunk ${chunkPath}`;\n\n if (source) {\n errorMessage += ` from ${stringifySourceInfo(source)}`;\n }\n\n throw new Error(errorMessage, {\n cause: e,\n });\n }\n}\n\nfunction loadWebAssembly(chunkPath: ChunkPath, imports: WebAssembly.Imports) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n\n return instantiateWebAssemblyFromPath(resolved, imports);\n}\n\nfunction loadWebAssemblyModule(chunkPath: ChunkPath) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n\n return compileWebAssemblyFromPath(resolved);\n}\n\nfunction instantiateModule(id: ModuleId, source: SourceInfo): Module {\n const moduleFactory = moduleFactories[id];\n if (typeof moduleFactory !== \"function\") {\n // This can happen if modules incorrectly handle HMR disposes/updates,\n // e.g. when they keep a `setTimeout` around which still executes old code\n // and contains e.g. a `require(\"something\")` call.\n let instantiationReason;\n switch (source.type) {\n case SourceType.Runtime:\n instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`;\n break;\n case SourceType.Parent:\n instantiationReason = `because it was required from module ${source.parentId}`;\n break;\n }\n throw new Error(\n `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`\n );\n }\n\n let parents: ModuleId[];\n switch (source.type) {\n case SourceType.Runtime:\n parents = [];\n break;\n case SourceType.Parent:\n // No need to add this module as a child of the parent module here, this\n // has already been taken care of in `getOrInstantiateModuleFromParent`.\n parents = [source.parentId];\n break;\n }\n\n const module: Module = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n parents,\n children: [],\n namespaceObject: undefined,\n };\n moduleCache[id] = module;\n\n // NOTE(alexkirsz) This can fail when the module encounters a runtime error.\n try {\n const r = commonJsRequire.bind(null, module);\n moduleFactory.call(module.exports, {\n a: asyncModule.bind(null, module),\n e: module.exports,\n r,\n t: runtimeRequire,\n x: externalRequire,\n y: externalImport,\n f: moduleContext,\n i: esmImport.bind(null, module),\n s: esmExport.bind(null, module, module.exports),\n j: dynamicExport.bind(null, module, module.exports),\n v: exportValue.bind(null, module),\n n: exportNamespace.bind(null, module),\n m: module,\n c: moduleCache,\n M: moduleFactories,\n l: loadChunkAsync.bind(null, { type: SourceType.Parent, parentId: id }),\n w: loadWebAssembly,\n u: loadWebAssemblyModule,\n g: globalThis,\n P: resolveAbsolutePath,\n U: relativeURL,\n R: createResolvePathFromModule(r),\n __dirname: module.id.replace(/(^|\\/)[\\/]+$/, \"\"),\n });\n } catch (error) {\n module.error = error as any;\n throw error;\n }\n\n module.loaded = true;\n if (module.namespaceObject && module.exports !== module.namespaceObject) {\n // in case of a circular dependency: cjs1 -> esm2 -> cjs1\n interopEsm(module.exports, module.namespaceObject);\n }\n\n return module;\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it if it is not cached.\n */\nfunction getOrInstantiateModuleFromParent(\n id: ModuleId,\n sourceModule: Module\n): Module {\n const module = moduleCache[id];\n\n if (sourceModule.children.indexOf(id) === -1) {\n sourceModule.children.push(id);\n }\n\n if (module) {\n if (module.parents.indexOf(sourceModule.id) === -1) {\n module.parents.push(sourceModule.id);\n }\n\n return module;\n }\n\n return instantiateModule(id, {\n type: SourceType.Parent,\n parentId: sourceModule.id,\n });\n}\n\n/**\n * Instantiates a runtime module.\n */\nfunction instantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath });\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it as a runtime module if it is not cached.\n */\nfunction getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n const module = moduleCache[moduleId];\n if (module) {\n if (module.error) {\n throw module.error;\n }\n return module;\n }\n\n return instantiateRuntimeModule(moduleId, chunkPath);\n}\n\nmodule.exports = {\n getOrInstantiateRuntimeModule,\n loadChunk,\n};\n"],"names":[],"mappings":"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"}}] } \ No newline at end of file