Skip to content

Commit 6ee9239

Browse files
wbinnssmithabhi12299
authored andcommitted
Base JS runtime for builds (vercel#70169)
1 parent 06ced61 commit 6ee9239

28 files changed

+1153
-848
lines changed

turbopack/crates/turbopack-browser/src/ecmascript/evaluate/chunk.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ impl EcmascriptDevEvaluateChunk {
146146
let runtime_code = turbopack_ecmascript_runtime::get_browser_runtime_code(
147147
environment,
148148
chunking_context.chunk_base_path(),
149+
Value::new(chunking_context.runtime_type()),
149150
Vc::cell(output_root.to_string().into()),
150151
);
151152
code.push_code(&*runtime_code.await?);
@@ -154,6 +155,7 @@ impl EcmascriptDevEvaluateChunk {
154155
let runtime_code = turbopack_ecmascript_runtime::get_browser_runtime_code(
155156
environment,
156157
chunking_context.chunk_base_path(),
158+
Value::new(chunking_context.runtime_type()),
157159
Vc::cell(output_root.to_string().into()),
158160
);
159161
code.push_code(&*runtime_code.await?);

turbopack/crates/turbopack-ecmascript-runtime/js/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
"check": "run-p check:*",
99
"check:nodejs": "tsc -p src/nodejs",
1010
"check:browser-dev-client": "tsc -p src/browser/dev/hmr-client",
11-
"check:browser-dev-runtime-base": "tsc -p src/browser/dev/runtime/base",
12-
"check:browser-dev-runtime-dom": "tsc -p src/browser/dev/runtime/dom",
13-
"check:browser-dev-runtime-edge": "tsc -p src/browser/dev/runtime/edge"
11+
"check:browser-runtime-base": "tsc -p src/browser/runtime/base",
12+
"check:browser-runtime-dom": "tsc -p src/browser/runtime/dom",
13+
"check:browser-runtime-edge": "tsc -p src/browser/runtime/edge"
1414
},
1515
"exports": {
1616
".": "./src/main.js",

turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/hmr-client.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/// <reference path="../../../shared/runtime-types.d.ts" />
2-
/// <reference path="../runtime/base/globals.d.ts" />
3-
/// <reference path="../runtime/base/protocol.d.ts" />
4-
/// <reference path="../runtime/base/extensions.d.ts" />
2+
/// <reference path="../../runtime/base/dev-globals.d.ts" />
3+
/// <reference path="../../runtime/base/dev-protocol.d.ts" />
4+
/// <reference path="../../runtime/base/dev-extensions.ts" />
55

66
import {
77
addMessageListener as turboSocketAddMessageListener,
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/// <reference path="./runtime-base.ts" />
2+
/// <reference path="./dummy.ts" />
3+
4+
declare var augmentContext: ((context: unknown) => unknown);
5+
6+
const moduleCache: ModuleCache<Module> = {};
7+
8+
/**
9+
* Gets or instantiates a runtime module.
10+
*/
11+
// @ts-ignore
12+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
13+
function getOrInstantiateRuntimeModule(
14+
moduleId: ModuleId,
15+
chunkPath: ChunkPath,
16+
): Module {
17+
const module = moduleCache[moduleId];
18+
if (module) {
19+
if (module.error) {
20+
throw module.error;
21+
}
22+
return module;
23+
}
24+
25+
return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath });
26+
}
27+
28+
/**
29+
* Retrieves a module from the cache, or instantiate it if it is not cached.
30+
*/
31+
// Used by the backend
32+
// @ts-ignore
33+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
34+
const getOrInstantiateModuleFromParent: GetOrInstantiateModuleFromParent<Module> = (
35+
id,
36+
sourceModule
37+
) => {
38+
const module = moduleCache[id];
39+
40+
if (module) {
41+
return module;
42+
}
43+
44+
return instantiateModule(id, {
45+
type: SourceType.Parent,
46+
parentId: sourceModule.id,
47+
});
48+
};
49+
50+
function instantiateModule(id: ModuleId, source: SourceInfo): Module {
51+
const moduleFactory = moduleFactories[id];
52+
if (typeof moduleFactory !== "function") {
53+
// This can happen if modules incorrectly handle HMR disposes/updates,
54+
// e.g. when they keep a `setTimeout` around which still executes old code
55+
// and contains e.g. a `require("something")` call.
56+
let instantiationReason;
57+
switch (source.type) {
58+
case SourceType.Runtime:
59+
instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`;
60+
break;
61+
case SourceType.Parent:
62+
instantiationReason = `because it was required from module ${source.parentId}`;
63+
break;
64+
case SourceType.Update:
65+
instantiationReason = "because of an HMR update";
66+
break;
67+
default:
68+
invariant(source, (source) => `Unknown source type: ${source?.type}`);
69+
}
70+
throw new Error(
71+
`Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`
72+
);
73+
}
74+
75+
switch (source.type) {
76+
case SourceType.Runtime:
77+
runtimeModules.add(id);
78+
break;
79+
case SourceType.Parent:
80+
// No need to add this module as a child of the parent module here, this
81+
// has already been taken care of in `getOrInstantiateModuleFromParent`.
82+
break;
83+
case SourceType.Update:
84+
throw new Error('Unexpected')
85+
default:
86+
invariant(source, (source) => `Unknown source type: ${source?.type}`);
87+
}
88+
89+
const module: Module = {
90+
exports: {},
91+
error: undefined,
92+
loaded: false,
93+
id,
94+
namespaceObject: undefined,
95+
};
96+
97+
moduleCache[id] = module;
98+
99+
// NOTE(alexkirsz) This can fail when the module encounters a runtime error.
100+
try {
101+
const sourceInfo: SourceInfo = { type: SourceType.Parent, parentId: id };
102+
103+
const r = commonJsRequire.bind(null, module);
104+
moduleFactory.call(
105+
module.exports,
106+
augmentContext({
107+
a: asyncModule.bind(null, module),
108+
e: module.exports,
109+
r: commonJsRequire.bind(null, module),
110+
t: runtimeRequire,
111+
f: moduleContext,
112+
i: esmImport.bind(null, module),
113+
s: esmExport.bind(null, module, module.exports),
114+
j: dynamicExport.bind(null, module, module.exports),
115+
v: exportValue.bind(null, module),
116+
n: exportNamespace.bind(null, module),
117+
m: module,
118+
c: moduleCache,
119+
M: moduleFactories,
120+
l: loadChunk.bind(null, sourceInfo),
121+
w: loadWebAssembly.bind(null, sourceInfo),
122+
u: loadWebAssemblyModule.bind(null, sourceInfo),
123+
g: globalThis,
124+
P: resolveAbsolutePath,
125+
U: relativeURL,
126+
R: createResolvePathFromModule(r),
127+
b: getWorkerBlobURL,
128+
__dirname: typeof module.id === "string" ? module.id.replace(/(^|\/)\/+$/, "") : module.id
129+
})
130+
);
131+
} catch (error) {
132+
module.error = error as any;
133+
throw error;
134+
}
135+
136+
module.loaded = true;
137+
if (module.namespaceObject && module.exports !== module.namespaceObject) {
138+
// in case of a circular dependency: cjs1 -> esm2 -> cjs1
139+
interopEsm(module.exports, module.namespaceObject);
140+
}
141+
142+
return module;
143+
}
144+

0 commit comments

Comments
 (0)