-
Notifications
You must be signed in to change notification settings - Fork 28.3k
/
utils.js
170 lines (147 loc) Β· 4.88 KB
/
utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
'use strict';
const {
ArrayIsArray,
SafeSet,
SafeWeakMap,
ObjectFreeze,
} = primordials;
const {
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING,
ERR_INVALID_ARG_VALUE,
} = require('internal/errors').codes;
const { getOptionValue } = require('internal/options');
const {
loadPreloadModules,
initializeFrozenIntrinsics,
} = require('internal/process/pre_execution');
const { pathToFileURL } = require('internal/url');
const {
setImportModuleDynamicallyCallback,
setInitializeImportMetaObjectCallback,
} = internalBinding('module_wrap');
const {
getModuleFromWrap,
} = require('internal/vm/module');
const assert = require('internal/assert');
const callbackMap = new SafeWeakMap();
function setCallbackForWrap(wrap, data) {
callbackMap.set(wrap, data);
}
let defaultImportModuleDynamically;
function setDefaultImportModuleDynamically(importModuleDynamically) {
defaultImportModuleDynamically = importModuleDynamically;
}
let defaultConditions;
function getDefaultConditions() {
assert(defaultConditions !== undefined);
return defaultConditions;
}
let defaultConditionsSet;
function getDefaultConditionsSet() {
assert(defaultConditionsSet !== undefined);
return defaultConditionsSet;
}
// This function is called during pre-execution, before any user code is run.
function initializeDefaultConditions() {
const userConditions = getOptionValue('--conditions');
const noAddons = getOptionValue('--no-addons');
const addonConditions = noAddons ? [] : ['node-addons'];
defaultConditions = ObjectFreeze([
'node',
'import',
...addonConditions,
...userConditions,
]);
defaultConditionsSet = new SafeSet(defaultConditions);
}
/**
* @param {string[]} [conditions]
* @returns {Set<string>}
*/
function getConditionsSet(conditions) {
if (conditions !== undefined && conditions !== getDefaultConditions()) {
if (!ArrayIsArray(conditions)) {
throw new ERR_INVALID_ARG_VALUE('conditions', conditions,
'expected an array');
}
return new SafeSet(conditions);
}
return getDefaultConditionsSet();
}
function initializeImportMetaObject(wrap, meta) {
if (callbackMap.has(wrap)) {
const { initializeImportMeta } = callbackMap.get(wrap);
if (initializeImportMeta !== undefined) {
meta = initializeImportMeta(meta, getModuleFromWrap(wrap) || wrap);
}
}
}
async function importModuleDynamicallyCallback(wrap, specifier, assertions) {
if (callbackMap.has(wrap)) {
const { importModuleDynamically } = callbackMap.get(wrap);
if (importModuleDynamically !== undefined) {
return importModuleDynamically(
specifier, getModuleFromWrap(wrap) || wrap, assertions);
}
}
if (defaultImportModuleDynamically) {
return defaultImportModuleDynamically(specifier, assertions);
}
throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING();
}
// This is configured during pre-execution. Specifically it's set to true for
// the loader worker in internal/main/worker_thread.js.
let _isLoaderWorker = false;
function initializeESM(isLoaderWorker = false) {
_isLoaderWorker = isLoaderWorker;
initializeDefaultConditions();
// Setup per-isolate callbacks that locate data or callbacks that we keep
// track of for different ESM modules.
setInitializeImportMetaObjectCallback(initializeImportMetaObject);
setImportModuleDynamicallyCallback(importModuleDynamicallyCallback);
}
function isLoaderWorker() {
return _isLoaderWorker;
}
async function initializeHooks() {
const customLoaderURLs = getOptionValue('--experimental-loader');
let cwd;
try {
// `process.cwd()` can fail if the parent directory is deleted while the process runs.
cwd = process.cwd() + '/';
} catch {
cwd = '/';
}
const { Hooks } = require('internal/modules/esm/hooks');
const esmLoader = require('internal/process/esm_loader').esmLoader;
const hooks = new Hooks();
esmLoader.setCustomizations(hooks);
// We need the loader customizations to be set _before_ we start invoking
// `--require`, otherwise loops can happen because a `--require` script
// might call `register(...)` before we've installed ourselves. These
// global values are magically set in `setupUserModules` just for us and
// we call them in the correct order.
// N.B. This block appears here specifically in order to ensure that
// `--require` calls occur before `--loader` ones do.
loadPreloadModules();
initializeFrozenIntrinsics();
const parentURL = pathToFileURL(cwd).href;
for (let i = 0; i < customLoaderURLs.length; i++) {
await hooks.register(
customLoaderURLs[i],
parentURL,
);
}
const preloadScripts = hooks.initializeGlobalPreload();
return { __proto__: null, hooks, preloadScripts };
}
module.exports = {
setCallbackForWrap,
setDefaultImportModuleDynamically,
initializeESM,
initializeHooks,
getDefaultConditions,
getConditionsSet,
loaderWorkerId: 'internal/modules/esm/worker',
isLoaderWorker,
};