-
Notifications
You must be signed in to change notification settings - Fork 27k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Currently we ship dev runtimes (with things like HMR logic) along with code for loading chunks. This separates them and allows us to include a minimal runtime for builds. Test Plan: `TURBOPACK=1 TURBOPACK_BUILD=1 pnpm build` on an app with a `middleware.ts` and verified it loads when started.
- Loading branch information
1 parent
74d2136
commit 17b3172
Showing
25 changed files
with
888 additions
and
525 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 3 additions & 3 deletions
6
turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/hmr-client.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
156 changes: 156 additions & 0 deletions
156
turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/runtime/base/build-base.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
const moduleCache: ModuleCache<BaseModule> = {}; | ||
|
||
/** | ||
* Gets or instantiates a runtime module. | ||
*/ | ||
// @ts-ignore | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
function getOrInstantiateRuntimeModule( | ||
moduleId: ModuleId, | ||
chunkPath: ChunkPath, | ||
): BaseModule { | ||
const module = moduleCache[moduleId]; | ||
if (module) { | ||
if (module.error) { | ||
throw module.error; | ||
} | ||
return module; | ||
} | ||
|
||
return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath }); | ||
} | ||
|
||
/** | ||
* Retrieves a module from the cache, or instantiate it if it is not cached. | ||
*/ | ||
// @ts-ignore | ||
const getOrInstantiateModuleFromParent: GetOrInstantiateModuleFromParent = ( | ||
id, | ||
sourceModule | ||
) => { | ||
const module = moduleCache[id]; | ||
|
||
if (sourceModule.children.indexOf(id) === -1) { | ||
sourceModule.children.push(id); | ||
} | ||
|
||
if (module) { | ||
if (module.parents.indexOf(sourceModule.id) === -1) { | ||
module.parents.push(sourceModule.id); | ||
} | ||
|
||
return module; | ||
} | ||
|
||
return instantiateModule(id, { | ||
type: SourceType.Parent, | ||
parentId: sourceModule.id, | ||
}); | ||
}; | ||
|
||
|
||
// globalThis.getOrInstantiateRuntimeModule = getOrInstantiateRuntimeModule; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
function instantiateModule(id: ModuleId, source: SourceInfo): BaseModule { | ||
debugger; | ||
const moduleFactory = moduleFactories[id]; | ||
if (typeof moduleFactory !== "function") { | ||
// This can happen if modules incorrectly handle HMR disposes/updates, | ||
// e.g. when they keep a `setTimeout` around which still executes old code | ||
// and contains e.g. a `require("something")` call. | ||
let instantiationReason; | ||
switch (source.type) { | ||
case SourceType.Runtime: | ||
instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`; | ||
break; | ||
case SourceType.Parent: | ||
instantiationReason = `because it was required from module ${source.parentId}`; | ||
break; | ||
case SourceType.Update: | ||
instantiationReason = "because of an HMR update"; | ||
break; | ||
default: | ||
invariant(source, (source) => `Unknown source type: ${source?.type}`); | ||
} | ||
throw new Error( | ||
`Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.` | ||
); | ||
} | ||
|
||
let parents: ModuleId[]; | ||
switch (source.type) { | ||
case SourceType.Runtime: | ||
runtimeModules.add(id); | ||
parents = []; | ||
break; | ||
case SourceType.Parent: | ||
// No need to add this module as a child of the parent module here, this | ||
// has already been taken care of in `getOrInstantiateModuleFromParent`. | ||
parents = [source.parentId]; | ||
break; | ||
case SourceType.Update: | ||
parents = source.parents || []; | ||
break; | ||
default: | ||
invariant(source, (source) => `Unknown source type: ${source?.type}`); | ||
} | ||
|
||
const module: Module = { | ||
exports: {}, | ||
error: undefined, | ||
loaded: false, | ||
id, | ||
parents, | ||
children: [], | ||
namespaceObject: undefined, | ||
}; | ||
|
||
moduleCache[id] = module; | ||
|
||
// NOTE(alexkirsz) This can fail when the module encounters a runtime error. | ||
try { | ||
const sourceInfo: SourceInfo = { type: SourceType.Parent, parentId: id }; | ||
|
||
const r = commonJsRequire.bind(null, module); | ||
moduleFactory.call( | ||
module.exports, | ||
{ | ||
a: asyncModule.bind(null, module), | ||
e: module.exports, | ||
r: commonJsRequire.bind(null, module), | ||
t: runtimeRequire, | ||
f: moduleContext, | ||
i: esmImport.bind(null, module), | ||
s: esmExport.bind(null, module, module.exports), | ||
j: dynamicExport.bind(null, module, module.exports), | ||
v: exportValue.bind(null, module), | ||
n: exportNamespace.bind(null, module), | ||
m: module, | ||
c: moduleCache, | ||
M: moduleFactories, | ||
l: loadChunk.bind(null, sourceInfo), | ||
w: loadWebAssembly.bind(null, sourceInfo), | ||
u: loadWebAssemblyModule.bind(null, sourceInfo), | ||
g: globalThis, | ||
P: resolveAbsolutePath, | ||
U: relativeURL, | ||
R: createResolvePathFromModule(r), | ||
b: getWorkerBlobURL, | ||
__dirname: typeof module.id === "string" ? module.id.replace(/(^|\/)\/+$/, "") : module.id | ||
} | ||
); | ||
} catch (error) { | ||
module.error = error as any; | ||
throw error; | ||
} | ||
|
||
module.loaded = true; | ||
if (module.namespaceObject && module.exports !== module.namespaceObject) { | ||
// in case of a circular dependency: cjs1 -> esm2 -> cjs1 | ||
interopEsm(module.exports, module.namespaceObject); | ||
} | ||
|
||
return module; | ||
} | ||
|
Oops, something went wrong.