vite-node 4.0.0-beta.9 → 5.0.0-beta.2

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.
@@ -1,22 +1,25 @@
1
1
  import assert from 'node:assert';
2
2
  import { existsSync, promises } from 'node:fs';
3
3
  import { performance } from 'node:perf_hooks';
4
+ import process from 'node:process';
4
5
  import { pathToFileURL } from 'node:url';
5
6
  import createDebug from 'debug';
6
7
  import { resolve, join, extname, dirname, relative, normalize } from 'pathe';
7
8
  import { version } from 'vite';
8
- import { s } from './chunk-browser.mjs';
9
+ import { C } from './chunk-index.js';
9
10
  import * as esModuleLexer from 'es-module-lexer';
10
- import { KNOWN_ASSET_RE } from './constants.mjs';
11
- import { isNodeBuiltin, slash, findNearestPackageData, toArray, withTrailingSlash, normalizeModuleId, toFilePath } from './utils.mjs';
12
- import { withInlineSourcemap } from './source-map.mjs';
11
+ import { KNOWN_ASSET_RE } from './constants.js';
12
+ import { isNodeBuiltin, slash, findNearestPackageData, toArray, withTrailingSlash, normalizeModuleId, toFilePath } from './utils.js';
13
+ import { withInlineSourcemap } from './source-map.js';
13
14
  import 'node:module';
15
+ import 'node:buffer';
14
16
  import 'node:path';
15
17
 
16
18
  /* eslint-disable no-console */
17
19
  function hashCode(s) {
18
20
  return s.split("").reduce((a, b) => {
19
- return a = (a << 5) - a + b.charCodeAt(0), a & a;
21
+ a = (a << 5) - a + b.charCodeAt(0);
22
+ return a & a;
20
23
  }, 0);
21
24
  }
22
25
  class Debugger {
@@ -24,25 +27,27 @@ class Debugger {
24
27
  initPromise;
25
28
  externalizeMap = /* @__PURE__ */ new Map();
26
29
  constructor(root, options) {
27
- if (this.options = options, options.dumpModules) this.dumpDir = resolve(root, options.dumpModules === true ? ".vite-node/dump" : options.dumpModules);
28
- if (this.dumpDir) if (options.loadDumppedModules) console.info(s.gray(`[vite-node] [debug] load modules from ${this.dumpDir}`));
29
- else console.info(s.gray(`[vite-node] [debug] dump modules to ${this.dumpDir}`));
30
+ this.options = options;
31
+ if (options.dumpModules) this.dumpDir = resolve(root, options.dumpModules === true ? ".vite-node/dump" : options.dumpModules);
32
+ if (this.dumpDir) if (options.loadDumppedModules) console.info(C.gray(`[vite-node] [debug] load modules from ${this.dumpDir}`));
33
+ else console.info(C.gray(`[vite-node] [debug] dump modules to ${this.dumpDir}`));
30
34
  this.initPromise = this.clearDump();
31
35
  }
32
36
  async clearDump() {
33
- if (this.dumpDir) {
34
- if (!this.options.loadDumppedModules && existsSync(this.dumpDir)) await promises.rm(this.dumpDir, {
35
- recursive: true,
36
- force: true
37
- });
38
- await promises.mkdir(this.dumpDir, { recursive: true });
39
- }
37
+ if (!this.dumpDir) return;
38
+ if (!this.options.loadDumppedModules && existsSync(this.dumpDir)) await promises.rm(this.dumpDir, {
39
+ recursive: true,
40
+ force: true
41
+ });
42
+ await promises.mkdir(this.dumpDir, { recursive: true });
40
43
  }
41
44
  encodeId(id) {
42
45
  return `${id.replace(/[^\w@\-]/g, "_").replace(/_+/g, "_")}-${hashCode(id)}.js`;
43
46
  }
44
47
  async recordExternalize(id, path) {
45
- this.dumpDir && (this.externalizeMap.set(id, path), await this.writeInfo());
48
+ if (!this.dumpDir) return;
49
+ this.externalizeMap.set(id, path);
50
+ await this.writeInfo();
46
51
  }
47
52
  async dumpFile(id, result) {
48
53
  if (!result || !this.dumpDir) return;
@@ -53,11 +58,11 @@ class Debugger {
53
58
  async loadDump(id) {
54
59
  if (!this.dumpDir) return null;
55
60
  await this.initPromise;
56
- const name = this.encodeId(id), path = join(this.dumpDir, name);
61
+ const name = this.encodeId(id);
62
+ const path = join(this.dumpDir, name);
57
63
  if (!existsSync(path)) return null;
58
- const code = await promises.readFile(path, "utf-8");
59
64
  return {
60
- code: code.replace(/^\/\/.*\n/, ""),
65
+ code: (await promises.readFile(path, "utf-8")).replace(/^\/\/.*\n/, ""),
61
66
  map: void 0
62
67
  };
63
68
  }
@@ -76,12 +81,16 @@ const BUILTIN_EXTENSIONS = new Set([
76
81
  ".cjs",
77
82
  ".node",
78
83
  ".wasm"
79
- ]), ESM_EXT_RE = /\.(es|esm|esm-browser|esm-bundler|es6|module)\.js$/, ESM_FOLDER_RE = /\/(es|esm)\/(.*\.js)$/, defaultInline = [
84
+ ]);
85
+ const ESM_EXT_RE = /\.(es|esm|esm-browser|esm-bundler|es6|module)\.js$/;
86
+ const ESM_FOLDER_RE = /\/(es|esm)\/(.*\.js)$/;
87
+ const defaultInline = [
80
88
  /virtual:/,
81
89
  /\.[mc]?ts$/,
82
90
  /[?&](init|raw|url|inline)\b/,
83
91
  KNOWN_ASSET_RE
84
- ], depsExternal = [/\/node_modules\/.*\.cjs\.js$/, /\/node_modules\/.*\.mjs$/];
92
+ ];
93
+ const depsExternal = [/\/node_modules\/.*\.cjs\.js$/, /\/node_modules\/.*\.mjs$/];
85
94
  function guessCJSversion(id) {
86
95
  if (id.match(ESM_EXT_RE)) {
87
96
  for (const i of [
@@ -106,12 +115,12 @@ async function isValidNodeImport(id) {
106
115
  if (BUILTIN_EXTENSIONS.has(extension)) return true;
107
116
  if (extension !== ".js") return false;
108
117
  id = id.replace("file:///", "");
109
- const package_ = await findNearestPackageData(dirname(id));
110
- if (package_.type === "module") return true;
118
+ if ((await findNearestPackageData(dirname(id))).type === "module") return true;
111
119
  if (/\.(?:\w+-)?esm?(?:-\w+)?\.js$|\/esm?\//.test(id)) return false;
112
120
  try {
113
121
  await esModuleLexer.init;
114
- const code = await promises.readFile(id, "utf8"), [, , , hasModuleSyntax] = esModuleLexer.parse(code);
122
+ const code = await promises.readFile(id, "utf8");
123
+ const [, , , hasModuleSyntax] = esModuleLexer.parse(code);
115
124
  return !hasModuleSyntax;
116
125
  } catch {
117
126
  return false;
@@ -123,18 +132,25 @@ async function shouldExternalize(id, options, cache = _defaultExternalizeCache)
123
132
  return cache.get(id);
124
133
  }
125
134
  async function _shouldExternalize(id, options) {
135
+ if (isNodeBuiltin(id)) return id;
126
136
  // data: should be processed by native import,
127
137
  // since it is a feature of ESM.
128
138
  // also externalize network imports since nodejs allows it when --experimental-network-imports
129
- if (isNodeBuiltin(id) || id.startsWith("data:") || /^(?:https?:)?\/\//.test(id)) return id;
139
+ if (id.startsWith("data:") || /^(?:https?:)?\/\//.test(id)) return id;
130
140
  id = patchWindowsImportPath(id);
131
141
  const moduleDirectories = (options === null || options === void 0 ? void 0 : options.moduleDirectories) || ["/node_modules/"];
132
- if (matchExternalizePattern(id, moduleDirectories, options === null || options === void 0 ? void 0 : options.inline) || (options === null || options === void 0 ? void 0 : options.inlineFiles) && (options === null || options === void 0 ? void 0 : options.inlineFiles.includes(id))) return false;
142
+ if (matchExternalizePattern(id, moduleDirectories, options === null || options === void 0 ? void 0 : options.inline)) return false;
143
+ if ((options === null || options === void 0 ? void 0 : options.inlineFiles) && (options === null || options === void 0 ? void 0 : options.inlineFiles.includes(id))) return false;
144
+ if (matchExternalizePattern(id, moduleDirectories, options === null || options === void 0 ? void 0 : options.external)) return id;
133
145
  // Unless the user explicitly opted to inline them, externalize Vite deps.
134
146
  // They are too big to inline by default.
135
- if (matchExternalizePattern(id, moduleDirectories, options === null || options === void 0 ? void 0 : options.external) || (options === null || options === void 0 ? void 0 : options.cacheDir) && id.includes(options.cacheDir)) return id;
136
- const isLibraryModule = moduleDirectories.some((dir) => id.includes(dir)), guessCJS = isLibraryModule && (options === null || options === void 0 ? void 0 : options.fallbackCJS);
137
- return id = guessCJS ? guessCJSversion(id) || id : id, matchExternalizePattern(id, moduleDirectories, defaultInline) ? false : matchExternalizePattern(id, moduleDirectories, depsExternal) || isLibraryModule && await isValidNodeImport(id) ? id : false;
147
+ if ((options === null || options === void 0 ? void 0 : options.cacheDir) && id.includes(options.cacheDir)) return id;
148
+ const isLibraryModule = moduleDirectories.some((dir) => id.includes(dir));
149
+ id = isLibraryModule && (options === null || options === void 0 ? void 0 : options.fallbackCJS) ? guessCJSversion(id) || id : id;
150
+ if (matchExternalizePattern(id, moduleDirectories, defaultInline)) return false;
151
+ if (matchExternalizePattern(id, moduleDirectories, depsExternal)) return id;
152
+ if (isLibraryModule && await isValidNodeImport(id)) return id;
153
+ return false;
138
154
  }
139
155
  function matchExternalizePattern(id, moduleDirectories, patterns) {
140
156
  if (patterns == null) return false;
@@ -145,7 +161,9 @@ function matchExternalizePattern(id, moduleDirectories, patterns) {
145
161
  return false;
146
162
  }
147
163
  function patchWindowsImportPath(path) {
148
- return path.match(/^\w:\\/) ? `file:///${slash(path)}` : path.match(/^\w:\//) ? `file:///${path}` : path;
164
+ if (path.match(/^\w:\\/)) return `file:///${slash(path)}`;
165
+ else if (path.match(/^\w:\//)) return `file:///${path}`;
166
+ else return path;
149
167
  }
150
168
 
151
169
  const debugRequest = createDebug("vite-node:server:request");
@@ -172,9 +190,12 @@ class ViteNodeServer {
172
190
  debugger;
173
191
  constructor(server, options = {}) {
174
192
  var _options$deps3;
175
- this.server = server, this.options = options;
193
+ this.server = server;
194
+ this.options = options;
176
195
  const ssrOptions = server.config.ssr;
177
- if (options.deps ?? (options.deps = {}), options.deps.cacheDir = relative(server.config.root, options.deps.cacheDir || server.config.cacheDir), ssrOptions) {
196
+ options.deps ?? (options.deps = {});
197
+ options.deps.cacheDir = relative(server.config.root, options.deps.cacheDir || server.config.cacheDir);
198
+ if (ssrOptions) {
178
199
  // we don't externalize ssr, because it has different semantics in Vite
179
200
  // if (ssrOptions.external) {
180
201
  // options.deps.external ??= []
@@ -201,24 +222,32 @@ class ViteNodeServer {
201
222
  return [resolvedId, pathToFileURL(resolvedId).href];
202
223
  });
203
224
  (_options$deps3 = options.deps).moduleDirectories ?? (_options$deps3.moduleDirectories = []);
204
- const envValue = process.env.VITE_NODE_DEPS_MODULE_DIRECTORIES || process.env.npm_config_VITE_NODE_DEPS_MODULE_DIRECTORIES, customModuleDirectories = envValue === null || envValue === void 0 ? void 0 : envValue.split(",");
225
+ const envValue = process.env.VITE_NODE_DEPS_MODULE_DIRECTORIES || process.env.npm_config_VITE_NODE_DEPS_MODULE_DIRECTORIES;
226
+ const customModuleDirectories = envValue === null || envValue === void 0 ? void 0 : envValue.split(",");
205
227
  if (customModuleDirectories) options.deps.moduleDirectories.push(...customModuleDirectories);
206
- // always add node_modules as a module directory
207
- if (options.deps.moduleDirectories = options.deps.moduleDirectories.map((dir) => {
228
+ options.deps.moduleDirectories = options.deps.moduleDirectories.map((dir) => {
208
229
  if (!dir.startsWith("/")) dir = `/${dir}`;
209
230
  if (!dir.endsWith("/")) dir += "/";
210
231
  return normalize(dir);
211
- }), !options.deps.moduleDirectories.includes("/node_modules/")) options.deps.moduleDirectories.push("/node_modules/");
232
+ });
233
+ // always add node_modules as a module directory
234
+ if (!options.deps.moduleDirectories.includes("/node_modules/")) options.deps.moduleDirectories.push("/node_modules/");
212
235
  }
213
236
  shouldExternalize(id) {
214
237
  return shouldExternalize(id, this.options.deps, this.externalizeCache);
215
238
  }
216
239
  getTotalDuration() {
217
- const ssrDurations = [...this.durations.ssr.values()].flat(), webDurations = [...this.durations.web.values()].flat();
240
+ const ssrDurations = [...this.durations.ssr.values()].flat();
241
+ const webDurations = [...this.durations.web.values()].flat();
218
242
  return [...ssrDurations, ...webDurations].reduce((a, b) => a + b, 0);
219
243
  }
220
244
  async ensureExists(id) {
221
- return this.existingOptimizedDeps.has(id) ? true : existsSync(id) ? (this.existingOptimizedDeps.add(id), true) : new Promise((resolve) => {
245
+ if (this.existingOptimizedDeps.has(id)) return true;
246
+ if (existsSync(id)) {
247
+ this.existingOptimizedDeps.add(id);
248
+ return true;
249
+ }
250
+ return new Promise((resolve) => {
222
251
  setTimeout(() => {
223
252
  this.ensureExists(id).then(() => {
224
253
  resolve(true);
@@ -273,25 +302,32 @@ class ViteNodeServer {
273
302
  }
274
303
  async transformModule(id, transformMode) {
275
304
  if (transformMode !== "web") throw new Error("`transformModule` only supports `transformMode: \"web\"`.");
276
- const normalizedId = normalizeModuleId(id), mod = this.server.moduleGraph.getModuleById(normalizedId), result = (mod === null || mod === void 0 ? void 0 : mod.transformResult) || await this.server.transformRequest(normalizedId);
305
+ const normalizedId = normalizeModuleId(id);
306
+ const mod = this.server.moduleGraph.getModuleById(normalizedId);
307
+ const result = (mod === null || mod === void 0 ? void 0 : mod.transformResult) || await this.server.transformRequest(normalizedId);
277
308
  return { code: result === null || result === void 0 ? void 0 : result.code };
278
309
  }
279
310
  getTransformMode(id) {
280
311
  var _this$options$transfo, _this$options$transfo2;
281
312
  const withoutQuery = id.split("?")[0];
282
- return !((_this$options$transfo = this.options.transformMode) === null || _this$options$transfo === void 0 || (_this$options$transfo = _this$options$transfo.web) === null || _this$options$transfo === void 0) && _this$options$transfo.some((r) => withoutQuery.match(r)) ? "web" : !((_this$options$transfo2 = this.options.transformMode) === null || _this$options$transfo2 === void 0 || (_this$options$transfo2 = _this$options$transfo2.ssr) === null || _this$options$transfo2 === void 0) && _this$options$transfo2.some((r) => withoutQuery.match(r)) || withoutQuery.match(/\.([cm]?[jt]sx?|json)$/) ? "ssr" : "web";
313
+ if ((_this$options$transfo = this.options.transformMode) === null || _this$options$transfo === void 0 || (_this$options$transfo = _this$options$transfo.web) === null || _this$options$transfo === void 0 ? void 0 : _this$options$transfo.some((r) => withoutQuery.match(r))) return "web";
314
+ if ((_this$options$transfo2 = this.options.transformMode) === null || _this$options$transfo2 === void 0 || (_this$options$transfo2 = _this$options$transfo2.ssr) === null || _this$options$transfo2 === void 0 ? void 0 : _this$options$transfo2.some((r) => withoutQuery.match(r))) return "ssr";
315
+ if (withoutQuery.match(/\.([cm]?[jt]sx?|json)$/)) return "ssr";
316
+ return "web";
283
317
  }
284
318
  getChangedModule(id, file) {
285
319
  const module = this.server.moduleGraph.getModuleById(id) || this.server.moduleGraph.getModuleById(file);
286
320
  if (module) return module;
287
321
  const _modules = this.server.moduleGraph.getModulesByFile(file);
288
322
  if (!_modules || !_modules.size) return null;
289
- // find the latest changed module
290
- const modules = [..._modules];
291
- let mod = modules[0], latestMax = -1;
323
+ let mod = [..._modules][0];
324
+ let latestMax = -1;
292
325
  for (const m of _modules) {
293
326
  const timestamp = Math.max(m.lastHMRTimestamp, m.lastInvalidationTimestamp);
294
- if (timestamp > latestMax) latestMax = timestamp, mod = m;
327
+ if (timestamp > latestMax) {
328
+ latestMax = timestamp;
329
+ mod = m;
330
+ }
295
331
  }
296
332
  return mod;
297
333
  }
@@ -304,18 +340,29 @@ class ViteNodeServer {
304
340
  const timeout = setTimeout(() => {
305
341
  throw new Error(`ViteNodeServer: ${id} not found. This is a bug, please report it.`);
306
342
  }, 5e3);
307
- await this.ensureExists(id), clearTimeout(timeout);
343
+ await this.ensureExists(id);
344
+ clearTimeout(timeout);
308
345
  }
309
- const { path: filePath } = toFilePath(id, this.server.config.root), moduleNode = this.getChangedModule(id, filePath), cache = this.fetchCaches[transformMode].get(filePath), timestamp = moduleNode ? Math.max(moduleNode.lastHMRTimestamp, moduleNode.lastInvalidationTimestamp) : 0;
346
+ const { path: filePath } = toFilePath(id, this.server.config.root);
347
+ const moduleNode = this.getChangedModule(id, filePath);
348
+ const cache = this.fetchCaches[transformMode].get(filePath);
349
+ // lastUpdateTimestamp is the timestamp that marks the last time the module was changed
350
+ // if lastUpdateTimestamp is 0, then the module was not changed since the server started
351
+ // we test "timestamp === 0" for expressiveness, but it's not necessary
352
+ const timestamp = moduleNode ? Math.max(moduleNode.lastHMRTimestamp, moduleNode.lastInvalidationTimestamp) : 0;
310
353
  if (cache && (timestamp === 0 || cache.timestamp >= timestamp)) return cache.result;
311
- const time = Date.now(), externalize = await this.shouldExternalize(filePath);
354
+ const time = Date.now();
355
+ const externalize = await this.shouldExternalize(filePath);
312
356
  let duration;
313
357
  if (externalize) {
314
358
  var _this$debugger;
315
- result = { externalize }, (_this$debugger = this.debugger) === null || _this$debugger === void 0 || _this$debugger.recordExternalize(id, externalize);
359
+ result = { externalize };
360
+ (_this$debugger = this.debugger) === null || _this$debugger === void 0 || _this$debugger.recordExternalize(id, externalize);
316
361
  } else {
317
- const start = performance.now(), r = await this._transformRequest(id, filePath, transformMode);
318
- duration = performance.now() - start, result = {
362
+ const start = performance.now();
363
+ const r = await this._transformRequest(id, filePath, transformMode);
364
+ duration = performance.now() - start;
365
+ result = {
319
366
  code: r === null || r === void 0 ? void 0 : r.code,
320
367
  map: r === null || r === void 0 ? void 0 : r.map
321
368
  };
@@ -324,8 +371,12 @@ class ViteNodeServer {
324
371
  duration,
325
372
  timestamp: time,
326
373
  result
327
- }, durations = this.durations[transformMode].get(filePath) || [];
328
- return this.durations[transformMode].set(filePath, [...durations, duration ?? 0]), this.fetchCaches[transformMode].set(filePath, cacheEntry), this.fetchCache.set(filePath, cacheEntry), result;
374
+ };
375
+ const durations = this.durations[transformMode].get(filePath) || [];
376
+ this.durations[transformMode].set(filePath, [...durations, duration ?? 0]);
377
+ this.fetchCaches[transformMode].set(filePath, cacheEntry);
378
+ this.fetchCache.set(filePath, cacheEntry);
379
+ return result;
329
380
  }
330
381
  async processTransformResult(filepath, result) {
331
382
  const mod = this.server.moduleGraph.getModuleById(filepath);
@@ -341,13 +392,16 @@ class ViteNodeServer {
341
392
  let result = null;
342
393
  if ((_this$options$debug = this.options.debug) === null || _this$options$debug === void 0 ? void 0 : _this$options$debug.loadDumppedModules) {
343
394
  var _this$debugger2;
344
- if (result = await ((_this$debugger2 = this.debugger) === null || _this$debugger2 === void 0 ? void 0 : _this$debugger2.loadDump(id)) ?? null, result) return result;
395
+ result = await ((_this$debugger2 = this.debugger) === null || _this$debugger2 === void 0 ? void 0 : _this$debugger2.loadDump(id)) ?? null;
396
+ if (result) return result;
345
397
  }
346
398
  if (transformMode === "web") {
347
- if (result = await this.server.transformRequest(id), result) result = await this.server.ssrTransform(result.code, result.map, id);
399
+ // for components like Vue, we want to use the client side
400
+ // plugins but then convert the code to be consumed by the server
401
+ result = await this.server.transformRequest(id);
402
+ if (result) result = await this.server.ssrTransform(result.code, result.map, id);
348
403
  } else result = await this.server.transformRequest(id, { ssr: true });
349
- const sourcemap = this.options.sourcemap ?? "inline";
350
- if (sourcemap === "inline" && result) result = await this.processTransformResult(filepath, result);
404
+ if ((this.options.sourcemap ?? "inline") === "inline" && result) result = await this.processTransformResult(filepath, result);
351
405
  if ((_this$options$debug2 = this.options.debug) === null || _this$options$debug2 === void 0 ? void 0 : _this$options$debug2.dumpModules) {
352
406
  var _this$debugger3;
353
407
  await ((_this$debugger3 = this.debugger) === null || _this$debugger3 === void 0 ? void 0 : _this$debugger3.dumpFile(id, result));