vite-node 3.2.0-beta.2 → 3.2.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-hmr.cjs +19 -3
- package/dist/chunk-hmr.mjs +19 -3
- package/dist/cli.cjs +5 -2
- package/dist/cli.mjs +5 -2
- package/dist/client.cjs +29 -0
- package/dist/client.mjs +29 -0
- package/dist/hmr.d.ts +3 -0
- package/dist/server.cjs +22 -1
- package/dist/server.mjs +22 -1
- package/dist/source-map.cjs +84 -3
- package/dist/source-map.mjs +84 -3
- package/dist/utils.cjs +9 -0
- package/dist/utils.mjs +9 -0
- package/package.json +3 -3
package/dist/chunk-hmr.cjs
CHANGED
|
@@ -14,6 +14,7 @@ function viteNodeHmrPlugin() {
|
|
|
14
14
|
return {
|
|
15
15
|
name: "vite-node:hmr",
|
|
16
16
|
config() {
|
|
17
|
+
// chokidar fsevents is unstable on macos when emitting "ready" event
|
|
17
18
|
if (process.platform === "darwin" && false);
|
|
18
19
|
},
|
|
19
20
|
configureServer(server) {
|
|
@@ -23,6 +24,8 @@ function viteNodeHmrPlugin() {
|
|
|
23
24
|
_send(payload);
|
|
24
25
|
emitter.emit("message", payload);
|
|
25
26
|
};
|
|
27
|
+
// eslint-disable-next-line ts/ban-ts-comment
|
|
28
|
+
// @ts-ignore Vite 6 compat
|
|
26
29
|
const environments = server.environments;
|
|
27
30
|
if (environments) environments.ssr.hot.send = function(payload) {
|
|
28
31
|
_send(payload);
|
|
@@ -55,6 +58,7 @@ function sendMessageBuffer(runner, emitter) {
|
|
|
55
58
|
maps.messageBuffer.length = 0;
|
|
56
59
|
}
|
|
57
60
|
async function reload(runner, files) {
|
|
61
|
+
// invalidate module cache but not node_modules
|
|
58
62
|
Array.from(runner.moduleCache.keys()).forEach((fsPath) => {
|
|
59
63
|
if (!fsPath.includes("node_modules")) runner.moduleCache.delete(fsPath);
|
|
60
64
|
});
|
|
@@ -82,9 +86,14 @@ async function fetchUpdate(runner, { path, acceptedPath }) {
|
|
|
82
86
|
acceptedPath = utils.normalizeRequestId(acceptedPath);
|
|
83
87
|
const maps = getCache(runner);
|
|
84
88
|
const mod = maps.hotModulesMap.get(path);
|
|
85
|
-
if (!mod)
|
|
89
|
+
if (!mod)
|
|
90
|
+
// In a code-splitting project,
|
|
91
|
+
// it is common that the hot-updating module is not loaded yet.
|
|
92
|
+
// https://github.com/vitejs/vite/issues/721
|
|
93
|
+
return;
|
|
86
94
|
const isSelfUpdate = path === acceptedPath;
|
|
87
95
|
let fetchedModule;
|
|
96
|
+
// determine the qualified callbacks before we re-import the modules
|
|
88
97
|
const qualifiedCallbacks = mod.callbacks.filter(({ deps }) => deps.includes(acceptedPath));
|
|
89
98
|
if (isSelfUpdate || qualifiedCallbacks.length > 0) {
|
|
90
99
|
const disposer = maps.disposeMap.get(acceptedPath);
|
|
@@ -115,6 +124,7 @@ async function handleMessage(runner, emitter, files, payload) {
|
|
|
115
124
|
await notifyListeners(runner, "vite:beforeUpdate", payload);
|
|
116
125
|
await Promise.all(payload.updates.map((update) => {
|
|
117
126
|
if (update.type === "js-update") return queueUpdate(runner, fetchUpdate(runner, update));
|
|
127
|
+
// css-update
|
|
118
128
|
console.error(`${browser.s.cyan("[vite-node]")} no support css hmr.}`);
|
|
119
129
|
return null;
|
|
120
130
|
}));
|
|
@@ -147,6 +157,8 @@ function createHotContext(runner, emitter, files, ownerPath) {
|
|
|
147
157
|
debugHmr("createHotContext", ownerPath);
|
|
148
158
|
const maps = getCache(runner);
|
|
149
159
|
if (!maps.dataMap.has(ownerPath)) maps.dataMap.set(ownerPath, {});
|
|
160
|
+
// when a file is hot updated, a new context is created
|
|
161
|
+
// clear its stale callbacks
|
|
150
162
|
const mod = maps.hotModulesMap.get(ownerPath);
|
|
151
163
|
if (mod) mod.callbacks = [];
|
|
152
164
|
const newListeners = new Map();
|
|
@@ -170,8 +182,12 @@ function createHotContext(runner, emitter, files, ownerPath) {
|
|
|
170
182
|
acceptDeps([ownerPath], callback && (([mod]) => callback(mod)));
|
|
171
183
|
},
|
|
172
184
|
accept(deps, callback) {
|
|
173
|
-
if (typeof deps === "function" || !deps)
|
|
174
|
-
|
|
185
|
+
if (typeof deps === "function" || !deps)
|
|
186
|
+
// self-accept: hot.accept(() => {})
|
|
187
|
+
acceptDeps([ownerPath], ([mod]) => deps && deps(mod));
|
|
188
|
+
else if (typeof deps === "string")
|
|
189
|
+
// explicit deps
|
|
190
|
+
acceptDeps([deps], ([mod]) => callback && callback(mod));
|
|
175
191
|
else if (Array.isArray(deps)) acceptDeps(deps, callback);
|
|
176
192
|
else throw new TypeError("invalid hot.accept() usage.");
|
|
177
193
|
},
|
package/dist/chunk-hmr.mjs
CHANGED
|
@@ -12,6 +12,7 @@ function viteNodeHmrPlugin() {
|
|
|
12
12
|
return {
|
|
13
13
|
name: "vite-node:hmr",
|
|
14
14
|
config() {
|
|
15
|
+
// chokidar fsevents is unstable on macos when emitting "ready" event
|
|
15
16
|
if (process.platform === "darwin" && false);
|
|
16
17
|
},
|
|
17
18
|
configureServer(server) {
|
|
@@ -21,6 +22,8 @@ function viteNodeHmrPlugin() {
|
|
|
21
22
|
_send(payload);
|
|
22
23
|
emitter.emit("message", payload);
|
|
23
24
|
};
|
|
25
|
+
// eslint-disable-next-line ts/ban-ts-comment
|
|
26
|
+
// @ts-ignore Vite 6 compat
|
|
24
27
|
const environments = server.environments;
|
|
25
28
|
if (environments) environments.ssr.hot.send = function(payload) {
|
|
26
29
|
_send(payload);
|
|
@@ -53,6 +56,7 @@ function sendMessageBuffer(runner, emitter) {
|
|
|
53
56
|
maps.messageBuffer.length = 0;
|
|
54
57
|
}
|
|
55
58
|
async function reload(runner, files) {
|
|
59
|
+
// invalidate module cache but not node_modules
|
|
56
60
|
Array.from(runner.moduleCache.keys()).forEach((fsPath) => {
|
|
57
61
|
if (!fsPath.includes("node_modules")) runner.moduleCache.delete(fsPath);
|
|
58
62
|
});
|
|
@@ -80,9 +84,14 @@ async function fetchUpdate(runner, { path, acceptedPath }) {
|
|
|
80
84
|
acceptedPath = normalizeRequestId(acceptedPath);
|
|
81
85
|
const maps = getCache(runner);
|
|
82
86
|
const mod = maps.hotModulesMap.get(path);
|
|
83
|
-
if (!mod)
|
|
87
|
+
if (!mod)
|
|
88
|
+
// In a code-splitting project,
|
|
89
|
+
// it is common that the hot-updating module is not loaded yet.
|
|
90
|
+
// https://github.com/vitejs/vite/issues/721
|
|
91
|
+
return;
|
|
84
92
|
const isSelfUpdate = path === acceptedPath;
|
|
85
93
|
let fetchedModule;
|
|
94
|
+
// determine the qualified callbacks before we re-import the modules
|
|
86
95
|
const qualifiedCallbacks = mod.callbacks.filter(({ deps }) => deps.includes(acceptedPath));
|
|
87
96
|
if (isSelfUpdate || qualifiedCallbacks.length > 0) {
|
|
88
97
|
const disposer = maps.disposeMap.get(acceptedPath);
|
|
@@ -113,6 +122,7 @@ async function handleMessage(runner, emitter, files, payload) {
|
|
|
113
122
|
await notifyListeners(runner, "vite:beforeUpdate", payload);
|
|
114
123
|
await Promise.all(payload.updates.map((update) => {
|
|
115
124
|
if (update.type === "js-update") return queueUpdate(runner, fetchUpdate(runner, update));
|
|
125
|
+
// css-update
|
|
116
126
|
console.error(`${s.cyan("[vite-node]")} no support css hmr.}`);
|
|
117
127
|
return null;
|
|
118
128
|
}));
|
|
@@ -145,6 +155,8 @@ function createHotContext(runner, emitter, files, ownerPath) {
|
|
|
145
155
|
debugHmr("createHotContext", ownerPath);
|
|
146
156
|
const maps = getCache(runner);
|
|
147
157
|
if (!maps.dataMap.has(ownerPath)) maps.dataMap.set(ownerPath, {});
|
|
158
|
+
// when a file is hot updated, a new context is created
|
|
159
|
+
// clear its stale callbacks
|
|
148
160
|
const mod = maps.hotModulesMap.get(ownerPath);
|
|
149
161
|
if (mod) mod.callbacks = [];
|
|
150
162
|
const newListeners = new Map();
|
|
@@ -168,8 +180,12 @@ function createHotContext(runner, emitter, files, ownerPath) {
|
|
|
168
180
|
acceptDeps([ownerPath], callback && (([mod]) => callback(mod)));
|
|
169
181
|
},
|
|
170
182
|
accept(deps, callback) {
|
|
171
|
-
if (typeof deps === "function" || !deps)
|
|
172
|
-
|
|
183
|
+
if (typeof deps === "function" || !deps)
|
|
184
|
+
// self-accept: hot.accept(() => {})
|
|
185
|
+
acceptDeps([ownerPath], ([mod]) => deps && deps(mod));
|
|
186
|
+
else if (typeof deps === "string")
|
|
187
|
+
// explicit deps
|
|
188
|
+
acceptDeps([deps], ([mod]) => callback && callback(mod));
|
|
173
189
|
else if (Array.isArray(deps)) acceptDeps(deps, callback);
|
|
174
190
|
else throw new TypeError("invalid hot.accept() usage.");
|
|
175
191
|
},
|
package/dist/cli.cjs
CHANGED
|
@@ -21,7 +21,7 @@ require('node:perf_hooks');
|
|
|
21
21
|
require('es-module-lexer');
|
|
22
22
|
require('./constants.cjs');
|
|
23
23
|
|
|
24
|
-
var version = "3.2.0-beta.
|
|
24
|
+
var version = "3.2.0-beta.3";
|
|
25
25
|
|
|
26
26
|
const cli = cac("vite-node");
|
|
27
27
|
cli.option("-r, --root <path>", "Use specified root directory").option("-c, --config <path>", "Use specified config file").option("-m, --mode <mode>", "Set env mode").option("-w, --watch", "Restart on file changes, similar to \"nodemon\"").option("--script", "Use vite-node as a script runner").option("--options <options>", "Use specified Vite server options").option("-v, --version", "Output the version number").option("-h, --help", "Display help for command");
|
|
@@ -76,7 +76,9 @@ async function run(files, options = {}) {
|
|
|
76
76
|
plugins: [options.watch && hmr.viteNodeHmrPlugin()]
|
|
77
77
|
});
|
|
78
78
|
if (Number(vite.version.split(".")[0]) < 6) await server$1.pluginContainer.buildStart({});
|
|
79
|
-
else
|
|
79
|
+
else
|
|
80
|
+
// directly access client plugin container until https://github.com/vitejs/vite/issues/19607
|
|
81
|
+
await server$1.environments.client.pluginContainer.buildStart({});
|
|
80
82
|
const env = vite.loadEnv(server$1.config.mode, server$1.config.envDir, "");
|
|
81
83
|
for (const key in env) {
|
|
82
84
|
var _process$env;
|
|
@@ -97,6 +99,7 @@ async function run(files, options = {}) {
|
|
|
97
99
|
return hmr.createHotContext(runner, server$1.emitter, files, url);
|
|
98
100
|
}
|
|
99
101
|
});
|
|
102
|
+
// provide the vite define variable in this context
|
|
100
103
|
await runner.executeId("/@vite/env");
|
|
101
104
|
for (const file of files) await runner.executeFile(file);
|
|
102
105
|
if (!options.watch) await server$1.close();
|
package/dist/cli.mjs
CHANGED
|
@@ -19,7 +19,7 @@ import 'node:perf_hooks';
|
|
|
19
19
|
import 'es-module-lexer';
|
|
20
20
|
import './constants.mjs';
|
|
21
21
|
|
|
22
|
-
var version = "3.2.0-beta.
|
|
22
|
+
var version = "3.2.0-beta.3";
|
|
23
23
|
|
|
24
24
|
const cli = cac("vite-node");
|
|
25
25
|
cli.option("-r, --root <path>", "Use specified root directory").option("-c, --config <path>", "Use specified config file").option("-m, --mode <mode>", "Set env mode").option("-w, --watch", "Restart on file changes, similar to \"nodemon\"").option("--script", "Use vite-node as a script runner").option("--options <options>", "Use specified Vite server options").option("-v, --version", "Output the version number").option("-h, --help", "Display help for command");
|
|
@@ -74,7 +74,9 @@ async function run(files, options = {}) {
|
|
|
74
74
|
plugins: [options.watch && viteNodeHmrPlugin()]
|
|
75
75
|
});
|
|
76
76
|
if (Number(version$1.split(".")[0]) < 6) await server.pluginContainer.buildStart({});
|
|
77
|
-
else
|
|
77
|
+
else
|
|
78
|
+
// directly access client plugin container until https://github.com/vitejs/vite/issues/19607
|
|
79
|
+
await server.environments.client.pluginContainer.buildStart({});
|
|
78
80
|
const env = loadEnv(server.config.mode, server.config.envDir, "");
|
|
79
81
|
for (const key in env) {
|
|
80
82
|
var _process$env;
|
|
@@ -95,6 +97,7 @@ async function run(files, options = {}) {
|
|
|
95
97
|
return createHotContext(runner, server.emitter, files, url);
|
|
96
98
|
}
|
|
97
99
|
});
|
|
100
|
+
// provide the vite define variable in this context
|
|
98
101
|
await runner.executeId("/@vite/env");
|
|
99
102
|
for (const file of files) await runner.executeFile(file);
|
|
100
103
|
if (!options.watch) await server.close();
|
package/dist/client.cjs
CHANGED
|
@@ -155,12 +155,14 @@ class ViteNodeRunner {
|
|
|
155
155
|
const { imports, importers } = mod;
|
|
156
156
|
if (importee) importers.add(importee);
|
|
157
157
|
const getStack = () => `stack:\n${[...callstack, fsPath].reverse().map((p) => ` - ${p}`).join("\n")}`;
|
|
158
|
+
// check circular dependency
|
|
158
159
|
if (callstack.includes(fsPath) || Array.from(imports.values()).some((i) => importers.has(i))) {
|
|
159
160
|
if (mod.exports) return mod.exports;
|
|
160
161
|
}
|
|
161
162
|
let debugTimer;
|
|
162
163
|
if (this.debug) debugTimer = setTimeout(() => console.warn(`[vite-node] module ${fsPath} takes over 2s to load.\n${getStack()}`), 2e3);
|
|
163
164
|
try {
|
|
165
|
+
// cached module
|
|
164
166
|
if (mod.promise) return await mod.promise;
|
|
165
167
|
const promise = this.directRequest(id, fsPath, callstack);
|
|
166
168
|
Object.assign(mod, {
|
|
@@ -183,6 +185,7 @@ class ViteNodeRunner {
|
|
|
183
185
|
const { path, exists } = utils.toFilePath(dep, this.root);
|
|
184
186
|
if (!this.options.resolveId || exists) return [dep, path];
|
|
185
187
|
const resolved = await this.options.resolveId(dep, importer);
|
|
188
|
+
// supported since Vite 5-beta.19
|
|
186
189
|
if (resolved === null || resolved === void 0 || (_resolved$meta = resolved.meta) === null || _resolved$meta === void 0 || (_resolved$meta = _resolved$meta["vite:alias"]) === null || _resolved$meta === void 0 ? void 0 : _resolved$meta.noResolved) {
|
|
187
190
|
const error = new Error(`Cannot find module '${id}'${importer ? ` imported from '${importer}'` : ""}.
|
|
188
191
|
|
|
@@ -206,6 +209,7 @@ class ViteNodeRunner {
|
|
|
206
209
|
}
|
|
207
210
|
async resolveUrl(id, importee) {
|
|
208
211
|
const resolveKey = `resolve:${id}`;
|
|
212
|
+
// put info about new import as soon as possible, so we can start tracking it
|
|
209
213
|
this.moduleCache.setByModuleId(resolveKey, { resolving: true });
|
|
210
214
|
try {
|
|
211
215
|
return await this._resolveUrl(id, importee);
|
|
@@ -221,6 +225,7 @@ class ViteNodeRunner {
|
|
|
221
225
|
try {
|
|
222
226
|
return await this.options.fetchModule(id);
|
|
223
227
|
} catch (cause) {
|
|
228
|
+
// rethrow vite error if it cannot load the module because it's not resolved
|
|
224
229
|
if (typeof cause === "object" && cause.code === "ERR_LOAD_URL" || typeof (cause === null || cause === void 0 ? void 0 : cause.message) === "string" && cause.message.includes("Failed to load url")) {
|
|
225
230
|
const error = new Error(`Cannot find ${utils.isBareImport(id) ? "package" : "module"} '${id}'${importer ? ` imported from '${importer}'` : ""}`, { cause });
|
|
226
231
|
error.code = "ERR_MODULE_NOT_FOUND";
|
|
@@ -253,6 +258,7 @@ class ViteNodeRunner {
|
|
|
253
258
|
if (transformed == null) throw new Error(`[vite-node] Failed to load "${id}" imported from ${callstack[callstack.length - 2]}`);
|
|
254
259
|
const { Object, Reflect, Symbol } = this.getContextPrimitives();
|
|
255
260
|
const modulePath = utils.cleanUrl(moduleId);
|
|
261
|
+
// disambiguate the `<UNIT>:/` on windows: see nodejs/node#31710
|
|
256
262
|
const href = node_url.pathToFileURL(modulePath).href;
|
|
257
263
|
const __filename = node_url.fileURLToPath(href);
|
|
258
264
|
const __dirname = path.dirname(__filename);
|
|
@@ -270,6 +276,8 @@ class ViteNodeRunner {
|
|
|
270
276
|
});
|
|
271
277
|
const SYMBOL_NOT_DEFINED = Symbol("not defined");
|
|
272
278
|
let moduleExports = SYMBOL_NOT_DEFINED;
|
|
279
|
+
// this proxy is triggered only on exports.{name} and module.exports access
|
|
280
|
+
// inside the module itself. imported module is always "exports"
|
|
273
281
|
const cjsExports = new Proxy(exports, {
|
|
274
282
|
get: (target, p, receiver) => {
|
|
275
283
|
if (Reflect.has(target, p)) return Reflect.get(target, p, receiver);
|
|
@@ -277,12 +285,16 @@ class ViteNodeRunner {
|
|
|
277
285
|
},
|
|
278
286
|
getPrototypeOf: () => Object.prototype,
|
|
279
287
|
set: (_, p, value) => {
|
|
288
|
+
// treat "module.exports =" the same as "exports.default =" to not have nested "default.default",
|
|
289
|
+
// so "exports.default" becomes the actual module
|
|
280
290
|
if (p === "default" && this.shouldInterop(modulePath, { default: value }) && cjsExports !== value) {
|
|
281
291
|
exportAll(cjsExports, value);
|
|
282
292
|
exports.default = value;
|
|
283
293
|
return true;
|
|
284
294
|
}
|
|
285
295
|
if (!Reflect.has(exports, "default")) exports.default = {};
|
|
296
|
+
// returns undefined, when accessing named exports, if default is not an object
|
|
297
|
+
// but is still present inside hasOwnKeys, this is Node behaviour for CJS
|
|
286
298
|
if (moduleExports !== SYMBOL_NOT_DEFINED && utils.isPrimitive(moduleExports)) {
|
|
287
299
|
defineExport(exports, p, () => void 0);
|
|
288
300
|
return true;
|
|
@@ -306,6 +318,7 @@ class ViteNodeRunner {
|
|
|
306
318
|
return cjsExports;
|
|
307
319
|
}
|
|
308
320
|
};
|
|
321
|
+
// Vite hot context
|
|
309
322
|
let hotContext;
|
|
310
323
|
if (this.options.createHotContext) Object.defineProperty(meta, "hot", {
|
|
311
324
|
enumerable: true,
|
|
@@ -318,11 +331,20 @@ class ViteNodeRunner {
|
|
|
318
331
|
hotContext = value;
|
|
319
332
|
}
|
|
320
333
|
});
|
|
334
|
+
// Be careful when changing this
|
|
335
|
+
// changing context will change amount of code added on line :114 (vm.runInThisContext)
|
|
336
|
+
// this messes up sourcemaps for coverage
|
|
337
|
+
// adjust `WRAPPER_LENGTH` variable in packages/coverage-v8/src/provider.ts if you do change this
|
|
321
338
|
const context = this.prepareContext({
|
|
322
339
|
__vite_ssr_import__: request,
|
|
323
340
|
__vite_ssr_dynamic_import__: request,
|
|
324
341
|
__vite_ssr_exports__: exports,
|
|
325
342
|
__vite_ssr_exportAll__: (obj) => exportAll(exports, obj),
|
|
343
|
+
__vite_ssr_exportName__: (name, getter) => Object.defineProperty(exports, name, {
|
|
344
|
+
enumerable: true,
|
|
345
|
+
configurable: true,
|
|
346
|
+
get: getter
|
|
347
|
+
}),
|
|
326
348
|
__vite_ssr_import_meta__: meta,
|
|
327
349
|
require: node_module.createRequire(href),
|
|
328
350
|
exports: cjsExports,
|
|
@@ -331,6 +353,7 @@ class ViteNodeRunner {
|
|
|
331
353
|
__dirname
|
|
332
354
|
});
|
|
333
355
|
debugExecute(__filename);
|
|
356
|
+
// remove shebang
|
|
334
357
|
if (transformed[0] === "#") transformed = transformed.replace(/^#!.*/, (s) => " ".repeat(s.length));
|
|
335
358
|
await this.runModule(context, transformed);
|
|
336
359
|
return exports;
|
|
@@ -344,6 +367,7 @@ class ViteNodeRunner {
|
|
|
344
367
|
}
|
|
345
368
|
async runModule(context, transformed) {
|
|
346
369
|
var _this$options$moduleE;
|
|
370
|
+
// add 'use strict' since ESM enables it by default
|
|
347
371
|
const codeDefinition = `'use strict';async (${Object.keys(context).join(",")})=>{{`;
|
|
348
372
|
const code = `${codeDefinition}${transformed}\n}}`;
|
|
349
373
|
const options = {
|
|
@@ -364,6 +388,8 @@ class ViteNodeRunner {
|
|
|
364
388
|
*/
|
|
365
389
|
shouldInterop(path, mod) {
|
|
366
390
|
if (this.options.interopDefault === false) return false;
|
|
391
|
+
// never interop ESM modules
|
|
392
|
+
// TODO: should also skip for `.js` with `type="module"`
|
|
367
393
|
return !path.endsWith(".mjs") && "default" in mod;
|
|
368
394
|
}
|
|
369
395
|
importExternalModule(path) {
|
|
@@ -415,6 +441,7 @@ function interopModule(mod) {
|
|
|
415
441
|
defaultExport
|
|
416
442
|
};
|
|
417
443
|
}
|
|
444
|
+
// keep consistency with Vite on how exports are defined
|
|
418
445
|
function defineExport(exports, key, value) {
|
|
419
446
|
Object.defineProperty(exports, key, {
|
|
420
447
|
enumerable: true,
|
|
@@ -423,6 +450,8 @@ function defineExport(exports, key, value) {
|
|
|
423
450
|
});
|
|
424
451
|
}
|
|
425
452
|
function exportAll(exports, sourceModule) {
|
|
453
|
+
// #1120 when a module exports itself it causes
|
|
454
|
+
// call stack error
|
|
426
455
|
if (exports === sourceModule) return;
|
|
427
456
|
if (utils.isPrimitive(sourceModule) || Array.isArray(sourceModule) || sourceModule instanceof Promise) return;
|
|
428
457
|
for (const key in sourceModule) if (key !== "default" && !(key in exports)) try {
|
package/dist/client.mjs
CHANGED
|
@@ -153,12 +153,14 @@ class ViteNodeRunner {
|
|
|
153
153
|
const { imports, importers } = mod;
|
|
154
154
|
if (importee) importers.add(importee);
|
|
155
155
|
const getStack = () => `stack:\n${[...callstack, fsPath].reverse().map((p) => ` - ${p}`).join("\n")}`;
|
|
156
|
+
// check circular dependency
|
|
156
157
|
if (callstack.includes(fsPath) || Array.from(imports.values()).some((i) => importers.has(i))) {
|
|
157
158
|
if (mod.exports) return mod.exports;
|
|
158
159
|
}
|
|
159
160
|
let debugTimer;
|
|
160
161
|
if (this.debug) debugTimer = setTimeout(() => console.warn(`[vite-node] module ${fsPath} takes over 2s to load.\n${getStack()}`), 2e3);
|
|
161
162
|
try {
|
|
163
|
+
// cached module
|
|
162
164
|
if (mod.promise) return await mod.promise;
|
|
163
165
|
const promise = this.directRequest(id, fsPath, callstack);
|
|
164
166
|
Object.assign(mod, {
|
|
@@ -181,6 +183,7 @@ class ViteNodeRunner {
|
|
|
181
183
|
const { path, exists } = toFilePath(dep, this.root);
|
|
182
184
|
if (!this.options.resolveId || exists) return [dep, path];
|
|
183
185
|
const resolved = await this.options.resolveId(dep, importer);
|
|
186
|
+
// supported since Vite 5-beta.19
|
|
184
187
|
if (resolved === null || resolved === void 0 || (_resolved$meta = resolved.meta) === null || _resolved$meta === void 0 || (_resolved$meta = _resolved$meta["vite:alias"]) === null || _resolved$meta === void 0 ? void 0 : _resolved$meta.noResolved) {
|
|
185
188
|
const error = new Error(`Cannot find module '${id}'${importer ? ` imported from '${importer}'` : ""}.
|
|
186
189
|
|
|
@@ -204,6 +207,7 @@ class ViteNodeRunner {
|
|
|
204
207
|
}
|
|
205
208
|
async resolveUrl(id, importee) {
|
|
206
209
|
const resolveKey = `resolve:${id}`;
|
|
210
|
+
// put info about new import as soon as possible, so we can start tracking it
|
|
207
211
|
this.moduleCache.setByModuleId(resolveKey, { resolving: true });
|
|
208
212
|
try {
|
|
209
213
|
return await this._resolveUrl(id, importee);
|
|
@@ -219,6 +223,7 @@ class ViteNodeRunner {
|
|
|
219
223
|
try {
|
|
220
224
|
return await this.options.fetchModule(id);
|
|
221
225
|
} catch (cause) {
|
|
226
|
+
// rethrow vite error if it cannot load the module because it's not resolved
|
|
222
227
|
if (typeof cause === "object" && cause.code === "ERR_LOAD_URL" || typeof (cause === null || cause === void 0 ? void 0 : cause.message) === "string" && cause.message.includes("Failed to load url")) {
|
|
223
228
|
const error = new Error(`Cannot find ${isBareImport(id) ? "package" : "module"} '${id}'${importer ? ` imported from '${importer}'` : ""}`, { cause });
|
|
224
229
|
error.code = "ERR_MODULE_NOT_FOUND";
|
|
@@ -251,6 +256,7 @@ class ViteNodeRunner {
|
|
|
251
256
|
if (transformed == null) throw new Error(`[vite-node] Failed to load "${id}" imported from ${callstack[callstack.length - 2]}`);
|
|
252
257
|
const { Object, Reflect, Symbol } = this.getContextPrimitives();
|
|
253
258
|
const modulePath = cleanUrl(moduleId);
|
|
259
|
+
// disambiguate the `<UNIT>:/` on windows: see nodejs/node#31710
|
|
254
260
|
const href = pathToFileURL(modulePath).href;
|
|
255
261
|
const __filename = fileURLToPath(href);
|
|
256
262
|
const __dirname = dirname(__filename);
|
|
@@ -268,6 +274,8 @@ class ViteNodeRunner {
|
|
|
268
274
|
});
|
|
269
275
|
const SYMBOL_NOT_DEFINED = Symbol("not defined");
|
|
270
276
|
let moduleExports = SYMBOL_NOT_DEFINED;
|
|
277
|
+
// this proxy is triggered only on exports.{name} and module.exports access
|
|
278
|
+
// inside the module itself. imported module is always "exports"
|
|
271
279
|
const cjsExports = new Proxy(exports, {
|
|
272
280
|
get: (target, p, receiver) => {
|
|
273
281
|
if (Reflect.has(target, p)) return Reflect.get(target, p, receiver);
|
|
@@ -275,12 +283,16 @@ class ViteNodeRunner {
|
|
|
275
283
|
},
|
|
276
284
|
getPrototypeOf: () => Object.prototype,
|
|
277
285
|
set: (_, p, value) => {
|
|
286
|
+
// treat "module.exports =" the same as "exports.default =" to not have nested "default.default",
|
|
287
|
+
// so "exports.default" becomes the actual module
|
|
278
288
|
if (p === "default" && this.shouldInterop(modulePath, { default: value }) && cjsExports !== value) {
|
|
279
289
|
exportAll(cjsExports, value);
|
|
280
290
|
exports.default = value;
|
|
281
291
|
return true;
|
|
282
292
|
}
|
|
283
293
|
if (!Reflect.has(exports, "default")) exports.default = {};
|
|
294
|
+
// returns undefined, when accessing named exports, if default is not an object
|
|
295
|
+
// but is still present inside hasOwnKeys, this is Node behaviour for CJS
|
|
284
296
|
if (moduleExports !== SYMBOL_NOT_DEFINED && isPrimitive(moduleExports)) {
|
|
285
297
|
defineExport(exports, p, () => void 0);
|
|
286
298
|
return true;
|
|
@@ -304,6 +316,7 @@ class ViteNodeRunner {
|
|
|
304
316
|
return cjsExports;
|
|
305
317
|
}
|
|
306
318
|
};
|
|
319
|
+
// Vite hot context
|
|
307
320
|
let hotContext;
|
|
308
321
|
if (this.options.createHotContext) Object.defineProperty(meta, "hot", {
|
|
309
322
|
enumerable: true,
|
|
@@ -316,11 +329,20 @@ class ViteNodeRunner {
|
|
|
316
329
|
hotContext = value;
|
|
317
330
|
}
|
|
318
331
|
});
|
|
332
|
+
// Be careful when changing this
|
|
333
|
+
// changing context will change amount of code added on line :114 (vm.runInThisContext)
|
|
334
|
+
// this messes up sourcemaps for coverage
|
|
335
|
+
// adjust `WRAPPER_LENGTH` variable in packages/coverage-v8/src/provider.ts if you do change this
|
|
319
336
|
const context = this.prepareContext({
|
|
320
337
|
__vite_ssr_import__: request,
|
|
321
338
|
__vite_ssr_dynamic_import__: request,
|
|
322
339
|
__vite_ssr_exports__: exports,
|
|
323
340
|
__vite_ssr_exportAll__: (obj) => exportAll(exports, obj),
|
|
341
|
+
__vite_ssr_exportName__: (name, getter) => Object.defineProperty(exports, name, {
|
|
342
|
+
enumerable: true,
|
|
343
|
+
configurable: true,
|
|
344
|
+
get: getter
|
|
345
|
+
}),
|
|
324
346
|
__vite_ssr_import_meta__: meta,
|
|
325
347
|
require: createRequire(href),
|
|
326
348
|
exports: cjsExports,
|
|
@@ -329,6 +351,7 @@ class ViteNodeRunner {
|
|
|
329
351
|
__dirname
|
|
330
352
|
});
|
|
331
353
|
debugExecute(__filename);
|
|
354
|
+
// remove shebang
|
|
332
355
|
if (transformed[0] === "#") transformed = transformed.replace(/^#!.*/, (s) => " ".repeat(s.length));
|
|
333
356
|
await this.runModule(context, transformed);
|
|
334
357
|
return exports;
|
|
@@ -342,6 +365,7 @@ class ViteNodeRunner {
|
|
|
342
365
|
}
|
|
343
366
|
async runModule(context, transformed) {
|
|
344
367
|
var _this$options$moduleE;
|
|
368
|
+
// add 'use strict' since ESM enables it by default
|
|
345
369
|
const codeDefinition = `'use strict';async (${Object.keys(context).join(",")})=>{{`;
|
|
346
370
|
const code = `${codeDefinition}${transformed}\n}}`;
|
|
347
371
|
const options = {
|
|
@@ -362,6 +386,8 @@ class ViteNodeRunner {
|
|
|
362
386
|
*/
|
|
363
387
|
shouldInterop(path, mod) {
|
|
364
388
|
if (this.options.interopDefault === false) return false;
|
|
389
|
+
// never interop ESM modules
|
|
390
|
+
// TODO: should also skip for `.js` with `type="module"`
|
|
365
391
|
return !path.endsWith(".mjs") && "default" in mod;
|
|
366
392
|
}
|
|
367
393
|
importExternalModule(path) {
|
|
@@ -413,6 +439,7 @@ function interopModule(mod) {
|
|
|
413
439
|
defaultExport
|
|
414
440
|
};
|
|
415
441
|
}
|
|
442
|
+
// keep consistency with Vite on how exports are defined
|
|
416
443
|
function defineExport(exports, key, value) {
|
|
417
444
|
Object.defineProperty(exports, key, {
|
|
418
445
|
enumerable: true,
|
|
@@ -421,6 +448,8 @@ function defineExport(exports, key, value) {
|
|
|
421
448
|
});
|
|
422
449
|
}
|
|
423
450
|
function exportAll(exports, sourceModule) {
|
|
451
|
+
// #1120 when a module exports itself it causes
|
|
452
|
+
// call stack error
|
|
424
453
|
if (exports === sourceModule) return;
|
|
425
454
|
if (isPrimitive(sourceModule) || Array.isArray(sourceModule) || sourceModule instanceof Promise) return;
|
|
426
455
|
for (const key in sourceModule) if (key !== "default" && !(key in exports)) try {
|
package/dist/hmr.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ declare module "vite" {
|
|
|
21
21
|
declare function createHmrEmitter(): HMREmitter;
|
|
22
22
|
declare function viteNodeHmrPlugin(): Plugin;
|
|
23
23
|
|
|
24
|
+
/* eslint-disable no-console */
|
|
25
|
+
|
|
24
26
|
type ModuleNamespace = Record<string, any> & {
|
|
25
27
|
[Symbol.toStringTag]: "Module"
|
|
26
28
|
};
|
|
@@ -30,6 +32,7 @@ interface HotModule {
|
|
|
30
32
|
callbacks: HotCallback[];
|
|
31
33
|
}
|
|
32
34
|
interface HotCallback {
|
|
35
|
+
// the dependencies must be fetchable paths
|
|
33
36
|
deps: string[];
|
|
34
37
|
fn: (modules: (ModuleNamespace | undefined)[]) => void;
|
|
35
38
|
}
|
package/dist/server.cjs
CHANGED
|
@@ -34,6 +34,7 @@ function _interopNamespaceDefault(e) {
|
|
|
34
34
|
|
|
35
35
|
var esModuleLexer__namespace = /*#__PURE__*/_interopNamespaceDefault(esModuleLexer);
|
|
36
36
|
|
|
37
|
+
/* eslint-disable no-console */
|
|
37
38
|
function hashCode(s) {
|
|
38
39
|
return s.split("").reduce((a, b) => {
|
|
39
40
|
a = (a << 5) - a + b.charCodeAt(0);
|
|
@@ -128,6 +129,7 @@ function guessCJSversion(id) {
|
|
|
128
129
|
]) if (fs.existsSync(i)) return i;
|
|
129
130
|
}
|
|
130
131
|
}
|
|
132
|
+
// The code from https://github.com/unjs/mlly/blob/c5bcca0cda175921344fd6de1bc0c499e73e5dac/src/syntax.ts#L51-L98
|
|
131
133
|
async function isValidNodeImport(id) {
|
|
132
134
|
const extension = pathe.extname(id);
|
|
133
135
|
if (BUILTIN_EXTENSIONS.has(extension)) return true;
|
|
@@ -152,12 +154,17 @@ async function shouldExternalize(id, options, cache = _defaultExternalizeCache)
|
|
|
152
154
|
}
|
|
153
155
|
async function _shouldExternalize(id, options) {
|
|
154
156
|
if (utils.isNodeBuiltin(id)) return id;
|
|
157
|
+
// data: should be processed by native import,
|
|
158
|
+
// since it is a feature of ESM.
|
|
159
|
+
// also externalize network imports since nodejs allows it when --experimental-network-imports
|
|
155
160
|
if (id.startsWith("data:") || /^(?:https?:)?\/\//.test(id)) return id;
|
|
156
161
|
id = patchWindowsImportPath(id);
|
|
157
162
|
const moduleDirectories = (options === null || options === void 0 ? void 0 : options.moduleDirectories) || ["/node_modules/"];
|
|
158
163
|
if (matchExternalizePattern(id, moduleDirectories, options === null || options === void 0 ? void 0 : options.inline)) return false;
|
|
159
164
|
if ((options === null || options === void 0 ? void 0 : options.inlineFiles) && (options === null || options === void 0 ? void 0 : options.inlineFiles.includes(id))) return false;
|
|
160
165
|
if (matchExternalizePattern(id, moduleDirectories, options === null || options === void 0 ? void 0 : options.external)) return id;
|
|
166
|
+
// Unless the user explicitly opted to inline them, externalize Vite deps.
|
|
167
|
+
// They are too big to inline by default.
|
|
161
168
|
if ((options === null || options === void 0 ? void 0 : options.cacheDir) && id.includes(options.cacheDir)) return id;
|
|
162
169
|
const isLibraryModule = moduleDirectories.some((dir) => id.includes(dir));
|
|
163
170
|
const guessCJS = isLibraryModule && (options === null || options === void 0 ? void 0 : options.fallbackCJS);
|
|
@@ -204,13 +211,18 @@ class ViteNodeServer {
|
|
|
204
211
|
externalizeCache = new Map();
|
|
205
212
|
debugger;
|
|
206
213
|
constructor(server, options = {}) {
|
|
214
|
+
var _options$deps3;
|
|
207
215
|
this.server = server;
|
|
208
216
|
this.options = options;
|
|
209
|
-
var _options$deps3;
|
|
210
217
|
const ssrOptions = server.config.ssr;
|
|
211
218
|
options.deps ?? (options.deps = {});
|
|
212
219
|
options.deps.cacheDir = pathe.relative(server.config.root, options.deps.cacheDir || server.config.cacheDir);
|
|
213
220
|
if (ssrOptions) {
|
|
221
|
+
// we don't externalize ssr, because it has different semantics in Vite
|
|
222
|
+
// if (ssrOptions.external) {
|
|
223
|
+
// options.deps.external ??= []
|
|
224
|
+
// options.deps.external.push(...ssrOptions.external)
|
|
225
|
+
// }
|
|
214
226
|
if (ssrOptions.noExternal === true) {
|
|
215
227
|
var _options$deps;
|
|
216
228
|
(_options$deps = options.deps).inline ?? (_options$deps.inline = true);
|
|
@@ -240,6 +252,7 @@ class ViteNodeServer {
|
|
|
240
252
|
if (!dir.endsWith("/")) dir += "/";
|
|
241
253
|
return pathe.normalize(dir);
|
|
242
254
|
});
|
|
255
|
+
// always add node_modules as a module directory
|
|
243
256
|
if (!options.deps.moduleDirectories.includes("/node_modules/")) options.deps.moduleDirectories.push("/node_modules/");
|
|
244
257
|
}
|
|
245
258
|
shouldExternalize(id) {
|
|
@@ -293,6 +306,7 @@ class ViteNodeServer {
|
|
|
293
306
|
const moduleId = utils.normalizeModuleId(id);
|
|
294
307
|
this.assertMode(mode);
|
|
295
308
|
const promiseMap = this.fetchPromiseMap[mode];
|
|
309
|
+
// reuse transform for concurrent requests
|
|
296
310
|
if (!promiseMap.has(moduleId)) promiseMap.set(moduleId, this._fetchModule(moduleId, mode).finally(() => {
|
|
297
311
|
promiseMap.delete(moduleId);
|
|
298
312
|
}));
|
|
@@ -302,6 +316,7 @@ class ViteNodeServer {
|
|
|
302
316
|
const mode = transformMode || this.getTransformMode(id);
|
|
303
317
|
this.assertMode(mode);
|
|
304
318
|
const promiseMap = this.transformPromiseMap[mode];
|
|
319
|
+
// reuse transform for concurrent requests
|
|
305
320
|
if (!promiseMap.has(id)) promiseMap.set(id, this._transformRequest(id, filepath, mode).finally(() => {
|
|
306
321
|
promiseMap.delete(id);
|
|
307
322
|
}));
|
|
@@ -327,6 +342,7 @@ class ViteNodeServer {
|
|
|
327
342
|
if (module) return module;
|
|
328
343
|
const _modules = this.server.moduleGraph.getModulesByFile(file);
|
|
329
344
|
if (!_modules || !_modules.size) return null;
|
|
345
|
+
// find the latest changed module
|
|
330
346
|
const modules = [..._modules];
|
|
331
347
|
let mod = modules[0];
|
|
332
348
|
let latestMax = -1;
|
|
@@ -354,6 +370,9 @@ class ViteNodeServer {
|
|
|
354
370
|
const { path: filePath } = utils.toFilePath(id, this.server.config.root);
|
|
355
371
|
const moduleNode = this.getChangedModule(id, filePath);
|
|
356
372
|
const cache = this.fetchCaches[transformMode].get(filePath);
|
|
373
|
+
// lastUpdateTimestamp is the timestamp that marks the last time the module was changed
|
|
374
|
+
// if lastUpdateTimestamp is 0, then the module was not changed since the server started
|
|
375
|
+
// we test "timestamp === 0" for expressiveness, but it's not necessary
|
|
357
376
|
const timestamp = moduleNode ? Math.max(moduleNode.lastHMRTimestamp, moduleNode.lastInvalidationTimestamp) : 0;
|
|
358
377
|
if (cache && (timestamp === 0 || cache.timestamp >= timestamp)) return cache.result;
|
|
359
378
|
const time = Date.now();
|
|
@@ -401,6 +420,8 @@ class ViteNodeServer {
|
|
|
401
420
|
if (result) return result;
|
|
402
421
|
}
|
|
403
422
|
if (transformMode === "web") {
|
|
423
|
+
// for components like Vue, we want to use the client side
|
|
424
|
+
// plugins but then convert the code to be consumed by the server
|
|
404
425
|
result = await this.server.transformRequest(id);
|
|
405
426
|
if (result) result = await this.server.ssrTransform(result.code, result.map, id);
|
|
406
427
|
} else result = await this.server.transformRequest(id, { ssr: true });
|