vitest 0.34.1 → 0.34.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.
Files changed (42) hide show
  1. package/LICENSE.md +28 -0
  2. package/dist/browser.d.ts +3 -3
  3. package/dist/browser.js +1 -1
  4. package/dist/child.js +11 -6
  5. package/dist/{chunk-api-setup.644415c3.js → chunk-api-setup.3b016b1c.js} +26 -16
  6. package/dist/{chunk-install-pkg.dd40cbef.js → chunk-install-pkg.a036014e.js} +8 -4
  7. package/dist/{chunk-integrations-globals.877c84db.js → chunk-integrations-globals.7f4b17bf.js} +5 -4
  8. package/dist/cli.js +11 -7
  9. package/dist/config.cjs +3 -1
  10. package/dist/config.d.ts +3 -3
  11. package/dist/config.js +3 -1
  12. package/dist/coverage.d.ts +3 -3
  13. package/dist/entry-vm.js +5 -4
  14. package/dist/entry.js +5 -4
  15. package/dist/environments.d.ts +3 -3
  16. package/dist/environments.js +11 -2
  17. package/dist/execute.d.ts +139 -0
  18. package/dist/execute.js +1 -1
  19. package/dist/index.d.ts +10 -9
  20. package/dist/index.js +6 -5
  21. package/dist/loader.js +9 -528
  22. package/dist/node.d.ts +4 -4
  23. package/dist/node.js +8 -4
  24. package/dist/{types-3c7dbfa5.d.ts → reporters-2ff87305.d.ts} +72 -5
  25. package/dist/reporters.d.ts +16 -0
  26. package/dist/reporters.js +16 -0
  27. package/dist/runners.d.ts +3 -3
  28. package/dist/runners.js +4 -3
  29. package/dist/{vendor-environments.443ecd82.js → vendor-environments.8eb4d407.js} +28 -10
  30. package/dist/{vendor-execute.9ab1c1a7.js → vendor-execute.a63e187f.js} +416 -211
  31. package/dist/vendor-index.0b5b3600.js +2062 -0
  32. package/dist/{vendor-index.087d1af7.js → vendor-index.29282562.js} +1 -1
  33. package/dist/{vendor-index.eff408fd.js → vendor-index.7178e7a2.js} +1 -1
  34. package/dist/{vendor-node.caa511fc.js → vendor-node.5ce5f335.js} +302 -2757
  35. package/dist/vendor-reporters.f6975b8d.js +2584 -0
  36. package/dist/vendor-tasks.f9d75aed.js +14 -0
  37. package/dist/{vendor-vi.271667ef.js → vendor-vi.597d9e06.js} +3 -2
  38. package/dist/vm.js +14 -6
  39. package/dist/worker.js +12 -6
  40. package/package.json +11 -7
  41. package/reporters.d.ts +1 -0
  42. package/dist/vendor-source-map.e6c1997b.js +0 -747
@@ -1,12 +1,12 @@
1
1
  import { pathToFileURL, fileURLToPath } from 'node:url';
2
2
  import vm from 'node:vm';
3
3
  import { ModuleCacheMap, ViteNodeRunner, DEFAULT_REQUEST_STUBS } from 'vite-node/client';
4
- import { isNodeBuiltin, getCachedData, setCacheData, isInternalRequest, isPrimitive } from 'vite-node/utils';
4
+ import { isNodeBuiltin, isPrimitive, toArray, getCachedData, setCacheData, isInternalRequest } from 'vite-node/utils';
5
5
  import { resolve, isAbsolute, dirname, join, basename, extname, normalize, relative } from 'pathe';
6
6
  import { processError } from '@vitest/utils/error';
7
7
  import { d as distDir } from './vendor-paths.84fc7a99.js';
8
8
  import { g as getWorkerState } from './vendor-global.97e4527c.js';
9
- import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
9
+ import { existsSync, readdirSync, statSync, readFileSync } from 'node:fs';
10
10
  import { getColors, getType } from '@vitest/utils';
11
11
  import { b as getAllMockableProperties } from './vendor-base.9c08bbd0.js';
12
12
  import { dirname as dirname$1 } from 'node:path';
@@ -317,11 +317,13 @@ ${c.green(`vi.mock("${mockpath}", async () => {
317
317
  return exports;
318
318
  }
319
319
  if (typeof mock === "function" && !callstack.includes(mockPath) && !callstack.includes(url)) {
320
- callstack.push(mockPath);
321
- const result = await this.callFunctionMock(mockPath, mock);
322
- const indexMock = callstack.indexOf(mockPath);
323
- callstack.splice(indexMock, 1);
324
- return result;
320
+ try {
321
+ callstack.push(mockPath);
322
+ return await this.callFunctionMock(mockPath, mock);
323
+ } finally {
324
+ const indexMock = callstack.indexOf(mockPath);
325
+ callstack.splice(indexMock, 1);
326
+ }
325
327
  }
326
328
  if (typeof mock === "string" && !callstack.includes(mock))
327
329
  return mock;
@@ -334,17 +336,20 @@ ${c.green(`vi.mock("${mockpath}", async () => {
334
336
  }
335
337
  }
336
338
 
337
- const SyntheticModule = vm.SyntheticModule;
338
- const SourceTextModule = vm.SourceTextModule;
339
339
  const _require = createRequire(import.meta.url);
340
- const nativeResolve = import.meta.resolve;
341
- const dataURIRegex = /^data:(?<mime>text\/javascript|application\/json|application\/wasm)(?:;(?<encoding>charset=utf-8|base64))?,(?<code>.*)$/;
342
- class ExternalModulesExecutor {
340
+ class CommonjsExecutor {
341
+ context;
342
+ requireCache = /* @__PURE__ */ new Map();
343
+ publicRequireCache = this.createProxyCache();
344
+ moduleCache = /* @__PURE__ */ new Map();
345
+ builtinCache = /* @__PURE__ */ Object.create(null);
346
+ extensions = /* @__PURE__ */ Object.create(null);
347
+ fs;
348
+ Module;
343
349
  constructor(options) {
344
- this.options = options;
345
350
  this.context = options.context;
351
+ this.fs = options.fileMap;
346
352
  const primitives = vm.runInContext("({ Object, Array, Error })", this.context);
347
- this.primitives = primitives;
348
353
  const executor = this;
349
354
  this.Module = class Module$1 {
350
355
  exports;
@@ -360,7 +365,7 @@ class ExternalModulesExecutor {
360
365
  constructor(id, parent) {
361
366
  this.exports = primitives.Object.create(Object.prototype);
362
367
  this.require = Module$1.createRequire(id);
363
- this.path = dirname$1(id);
368
+ this.path = dirname(id);
364
369
  this.id = id;
365
370
  this.filename = id;
366
371
  this.loaded = false;
@@ -370,12 +375,12 @@ class ExternalModulesExecutor {
370
375
  const cjsModule = Module$1.wrap(code);
371
376
  const script = new vm.Script(cjsModule, {
372
377
  filename,
373
- importModuleDynamically: executor.importModuleDynamically
378
+ importModuleDynamically: options.importModuleDynamically
374
379
  });
375
380
  script.identifier = filename;
376
381
  const fn = script.runInContext(executor.context);
377
- const __dirname = dirname$1(filename);
378
- executor.requireCache[filename] = this;
382
+ const __dirname = dirname(filename);
383
+ executor.requireCache.set(filename, this);
379
384
  try {
380
385
  fn(this.exports, this.require, this, filename, __dirname);
381
386
  return this.exports;
@@ -427,121 +432,14 @@ class ExternalModulesExecutor {
427
432
  this.extensions[".js"] = this.requireJs;
428
433
  this.extensions[".json"] = this.requireJson;
429
434
  }
430
- requireCache = /* @__PURE__ */ Object.create(null);
431
- builtinCache = /* @__PURE__ */ Object.create(null);
432
- moduleCache = /* @__PURE__ */ new Map();
433
- extensions = /* @__PURE__ */ Object.create(null);
434
- esmLinkMap = /* @__PURE__ */ new WeakMap();
435
- context;
436
- fsCache = /* @__PURE__ */ new Map();
437
- fsBufferCache = /* @__PURE__ */ new Map();
438
- Module;
439
- primitives;
440
435
  requireJs = (m, filename) => {
441
- const content = this.readFile(filename);
436
+ const content = this.fs.readFile(filename);
442
437
  m._compile(content, filename);
443
438
  };
444
439
  requireJson = (m, filename) => {
445
- const code = this.readFile(filename);
440
+ const code = this.fs.readFile(filename);
446
441
  m.exports = JSON.parse(code);
447
442
  };
448
- importModuleDynamically = async (specifier, referencer) => {
449
- const module = await this.resolveModule(specifier, referencer.identifier);
450
- return this.evaluateModule(module);
451
- };
452
- resolveModule = async (specifier, referencer) => {
453
- const identifier = await this.resolveAsync(specifier, referencer);
454
- return await this.createModule(identifier);
455
- };
456
- async resolveAsync(specifier, parent) {
457
- return nativeResolve(specifier, parent);
458
- }
459
- readFile(path) {
460
- const cached = this.fsCache.get(path);
461
- if (cached)
462
- return cached;
463
- const source = readFileSync(path, "utf-8");
464
- this.fsCache.set(path, source);
465
- return source;
466
- }
467
- readBuffer(path) {
468
- const cached = this.fsBufferCache.get(path);
469
- if (cached)
470
- return cached;
471
- const buffer = readFileSync(path);
472
- this.fsBufferCache.set(path, buffer);
473
- return buffer;
474
- }
475
- findNearestPackageData(basedir) {
476
- var _a;
477
- const originalBasedir = basedir;
478
- const packageCache = this.options.packageCache;
479
- while (basedir) {
480
- const cached = getCachedData(packageCache, basedir, originalBasedir);
481
- if (cached)
482
- return cached;
483
- const pkgPath = join(basedir, "package.json");
484
- try {
485
- if ((_a = statSync(pkgPath, { throwIfNoEntry: false })) == null ? void 0 : _a.isFile()) {
486
- const pkgData = JSON.parse(this.readFile(pkgPath));
487
- if (packageCache)
488
- setCacheData(packageCache, pkgData, basedir, originalBasedir);
489
- return pkgData;
490
- }
491
- } catch {
492
- }
493
- const nextBasedir = dirname$1(basedir);
494
- if (nextBasedir === basedir)
495
- break;
496
- basedir = nextBasedir;
497
- }
498
- return null;
499
- }
500
- wrapSynteticModule(identifier, exports) {
501
- const moduleKeys = Object.keys(exports).filter((key) => key !== "default");
502
- const m = new SyntheticModule(
503
- [...moduleKeys, "default"],
504
- () => {
505
- for (const key of moduleKeys)
506
- m.setExport(key, exports[key]);
507
- m.setExport("default", exports);
508
- },
509
- {
510
- context: this.context,
511
- identifier
512
- }
513
- );
514
- return m;
515
- }
516
- async evaluateModule(m) {
517
- if (m.status === "unlinked") {
518
- this.esmLinkMap.set(
519
- m,
520
- m.link(
521
- (identifier, referencer) => this.resolveModule(identifier, referencer.identifier)
522
- )
523
- );
524
- }
525
- await this.esmLinkMap.get(m);
526
- if (m.status === "linked")
527
- await m.evaluate();
528
- return m;
529
- }
530
- findLongestRegisteredExtension(filename) {
531
- const name = basename(filename);
532
- let currentExtension;
533
- let index;
534
- let startIndex = 0;
535
- while ((index = name.indexOf(".", startIndex)) !== -1) {
536
- startIndex = index + 1;
537
- if (index === 0)
538
- continue;
539
- currentExtension = name.slice(index);
540
- if (this.extensions[currentExtension])
541
- return currentExtension;
542
- }
543
- return ".js";
544
- }
545
443
  createRequire = (filename) => {
546
444
  const _require2 = createRequire(filename);
547
445
  const require = (id) => {
@@ -549,7 +447,7 @@ class ExternalModulesExecutor {
549
447
  const ext = extname(resolved);
550
448
  if (ext === ".node" || isNodeBuiltin(resolved))
551
449
  return this.requireCoreModule(resolved);
552
- const module = this.createCommonJSNodeModule(resolved);
450
+ const module = new this.Module(resolved);
553
451
  return this.loadCommonJSModule(module, resolved);
554
452
  };
555
453
  require.resolve = _require2.resolve;
@@ -559,16 +457,29 @@ class ExternalModulesExecutor {
559
457
  },
560
458
  configurable: true
561
459
  });
562
- require.main = _require2.main;
563
- require.cache = this.requireCache;
460
+ require.main = void 0;
461
+ require.cache = this.publicRequireCache;
564
462
  return require;
565
463
  };
566
- createCommonJSNodeModule(filename) {
567
- return new this.Module(filename);
464
+ createProxyCache() {
465
+ return new Proxy(/* @__PURE__ */ Object.create(null), {
466
+ defineProperty: () => true,
467
+ deleteProperty: () => true,
468
+ set: () => true,
469
+ get: (_, key) => this.requireCache.get(key),
470
+ has: (_, key) => this.requireCache.has(key),
471
+ ownKeys: () => Array.from(this.requireCache.keys()),
472
+ getOwnPropertyDescriptor() {
473
+ return {
474
+ configurable: true,
475
+ enumerable: true
476
+ };
477
+ }
478
+ });
568
479
  }
569
480
  // very naive implementation for Node.js require
570
481
  loadCommonJSModule(module, filename) {
571
- const cached = this.requireCache[filename];
482
+ const cached = this.requireCache.get(filename);
572
483
  if (cached)
573
484
  return cached.exports;
574
485
  const extension = this.findLongestRegisteredExtension(filename);
@@ -576,44 +487,106 @@ class ExternalModulesExecutor {
576
487
  loader(module, filename);
577
488
  return module.exports;
578
489
  }
579
- async createEsmModule(fileUrl, code) {
580
- const cached = this.moduleCache.get(fileUrl);
581
- if (cached)
582
- return cached;
583
- const [urlPath] = fileUrl.split("?");
584
- if (CSS_LANGS_RE.test(urlPath) || KNOWN_ASSET_RE.test(urlPath)) {
585
- const path = normalize(urlPath);
586
- let name = path.split("/node_modules/").pop() || "";
587
- if (name == null ? void 0 : name.startsWith("@"))
588
- name = name.split("/").slice(0, 2).join("/");
589
- else
590
- name = name.split("/")[0];
591
- const ext = extname(path);
592
- let error = `[vitest] Cannot import ${fileUrl}. At the moment, importing ${ext} files inside external dependencies is not allowed. `;
593
- if (name) {
594
- const c = getColors();
595
- error += `As a temporary workaround you can try to inline the package by updating your config:
490
+ findLongestRegisteredExtension(filename) {
491
+ const name = basename(filename);
492
+ let currentExtension;
493
+ let index;
494
+ let startIndex = 0;
495
+ while ((index = name.indexOf(".", startIndex)) !== -1) {
496
+ startIndex = index + 1;
497
+ if (index === 0)
498
+ continue;
499
+ currentExtension = name.slice(index);
500
+ if (this.extensions[currentExtension])
501
+ return currentExtension;
502
+ }
503
+ return ".js";
504
+ }
505
+ require(identifier) {
506
+ const ext = extname(identifier);
507
+ if (ext === ".node" || isNodeBuiltin(identifier))
508
+ return this.requireCoreModule(identifier);
509
+ const module = new this.Module(identifier);
510
+ return this.loadCommonJSModule(module, identifier);
511
+ }
512
+ requireCoreModule(identifier) {
513
+ const normalized = identifier.replace(/^node:/, "");
514
+ if (this.builtinCache[normalized])
515
+ return this.builtinCache[normalized].exports;
516
+ const moduleExports = _require(identifier);
517
+ if (identifier === "node:module" || identifier === "module") {
518
+ const module = new this.Module("/module.js");
519
+ module.exports = this.Module;
520
+ this.builtinCache[normalized] = module;
521
+ return module.exports;
522
+ }
523
+ this.builtinCache[normalized] = _require.cache[normalized];
524
+ return moduleExports;
525
+ }
526
+ }
596
527
 
597
- ${c.gray(c.dim("// vitest.config.js"))}
598
- ${c.green(`export default {
599
- test: {
600
- deps: {
601
- optimizer: {
602
- web: {
603
- include: [
604
- ${c.yellow(c.bold(`"${name}"`))}
605
- ]
528
+ function interopCommonJsModule(interopDefault, mod) {
529
+ if (isPrimitive(mod) || Array.isArray(mod) || mod instanceof Promise) {
530
+ return {
531
+ keys: [],
532
+ moduleExports: {},
533
+ defaultExport: mod
534
+ };
535
+ }
536
+ if (interopDefault !== false && "__esModule" in mod && !isPrimitive(mod.default)) {
537
+ const defaultKets = Object.keys(mod.default);
538
+ const moduleKeys = Object.keys(mod);
539
+ const allKeys = /* @__PURE__ */ new Set([...defaultKets, ...moduleKeys]);
540
+ allKeys.delete("default");
541
+ return {
542
+ keys: Array.from(allKeys),
543
+ moduleExports: new Proxy(mod, {
544
+ get(mod2, prop) {
545
+ var _a;
546
+ return mod2[prop] ?? ((_a = mod2.default) == null ? void 0 : _a[prop]);
606
547
  }
607
- }
608
- }
548
+ }),
549
+ defaultExport: mod
550
+ };
609
551
  }
552
+ return {
553
+ keys: Object.keys(mod).filter((key) => key !== "default"),
554
+ moduleExports: mod,
555
+ defaultExport: mod
556
+ };
610
557
  }
611
- `)}`;
612
- }
613
- throw new this.primitives.Error(error);
558
+ const SyntheticModule$1 = vm.SyntheticModule;
559
+ const SourceTextModule = vm.SourceTextModule;
560
+
561
+ const dataURIRegex = /^data:(?<mime>text\/javascript|application\/json|application\/wasm)(?:;(?<encoding>charset=utf-8|base64))?,(?<code>.*)$/;
562
+ class EsmExecutor {
563
+ constructor(executor, options) {
564
+ this.executor = executor;
565
+ this.context = options.context;
566
+ }
567
+ moduleCache = /* @__PURE__ */ new Map();
568
+ esmLinkMap = /* @__PURE__ */ new WeakMap();
569
+ context;
570
+ async evaluateModule(m) {
571
+ if (m.status === "unlinked") {
572
+ this.esmLinkMap.set(
573
+ m,
574
+ m.link(
575
+ (identifier, referencer) => this.executor.resolveModule(identifier, referencer.identifier)
576
+ )
577
+ );
614
578
  }
579
+ await this.esmLinkMap.get(m);
580
+ if (m.status === "linked")
581
+ await m.evaluate();
582
+ return m;
583
+ }
584
+ async createEsModule(fileUrl, code) {
585
+ const cached = this.moduleCache.get(fileUrl);
586
+ if (cached)
587
+ return cached;
615
588
  if (fileUrl.endsWith(".json")) {
616
- const m2 = new SyntheticModule(
589
+ const m2 = new SyntheticModule$1(
617
590
  ["default"],
618
591
  () => {
619
592
  const result = JSON.parse(code);
@@ -628,11 +601,11 @@ ${c.green(`export default {
628
601
  {
629
602
  identifier: fileUrl,
630
603
  context: this.context,
631
- importModuleDynamically: this.importModuleDynamically,
604
+ importModuleDynamically: this.executor.importModuleDynamically,
632
605
  initializeImportMeta: (meta, mod) => {
633
606
  meta.url = mod.identifier;
634
607
  meta.resolve = (specifier, importer) => {
635
- return nativeResolve(specifier, importer ?? mod.identifier);
608
+ return this.executor.resolve(specifier, importer ?? mod.identifier);
636
609
  };
637
610
  }
638
611
  }
@@ -640,20 +613,6 @@ ${c.green(`export default {
640
613
  this.moduleCache.set(fileUrl, m);
641
614
  return m;
642
615
  }
643
- requireCoreModule(identifier) {
644
- const normalized = identifier.replace(/^node:/, "");
645
- if (this.builtinCache[normalized])
646
- return this.builtinCache[normalized].exports;
647
- const moduleExports = _require(identifier);
648
- if (identifier === "node:module" || identifier === "module") {
649
- const module = new this.Module("/module.js");
650
- module.exports = this.Module;
651
- this.builtinCache[normalized] = module;
652
- return module.exports;
653
- }
654
- this.builtinCache[normalized] = _require.cache[normalized];
655
- return moduleExports;
656
- }
657
616
  async loadWebAssemblyModule(source, identifier) {
658
617
  const cached = this.moduleCache.get(identifier);
659
618
  if (cached)
@@ -664,14 +623,14 @@ ${c.green(`export default {
664
623
  const moduleLookup = {};
665
624
  for (const { module } of imports) {
666
625
  if (moduleLookup[module] === void 0) {
667
- const resolvedModule = await this.resolveModule(
626
+ const resolvedModule = await this.executor.resolveModule(
668
627
  module,
669
628
  identifier
670
629
  );
671
630
  moduleLookup[module] = await this.evaluateModule(resolvedModule);
672
631
  }
673
632
  }
674
- const syntheticModule = new SyntheticModule(
633
+ const syntheticModule = new SyntheticModule$1(
675
634
  exports.map(({ name }) => name),
676
635
  () => {
677
636
  const importsObject = {};
@@ -691,11 +650,16 @@ ${c.green(`export default {
691
650
  );
692
651
  return syntheticModule;
693
652
  }
653
+ cacheModule(identifier, module) {
654
+ this.moduleCache.set(identifier, module);
655
+ }
656
+ resolveCachedModule(identifier) {
657
+ return this.moduleCache.get(identifier);
658
+ }
694
659
  async createDataModule(identifier) {
695
660
  const cached = this.moduleCache.get(identifier);
696
661
  if (cached)
697
662
  return cached;
698
- const Error = this.primitives.Error;
699
663
  const match = identifier.match(dataURIRegex);
700
664
  if (!match || !match.groups)
701
665
  throw new Error("Invalid data URI");
@@ -721,7 +685,7 @@ ${c.green(`export default {
721
685
  else
722
686
  throw new Error(`Invalid data URI encoding: ${encoding}`);
723
687
  if (mime === "application/json") {
724
- const module = new SyntheticModule(
688
+ const module = new SyntheticModule$1(
725
689
  ["default"],
726
690
  () => {
727
691
  const obj = JSON.parse(code);
@@ -732,38 +696,269 @@ ${c.green(`export default {
732
696
  this.moduleCache.set(identifier, module);
733
697
  return module;
734
698
  }
735
- return this.createEsmModule(identifier, code);
699
+ return this.createEsModule(identifier, code);
736
700
  }
737
- async createModule(identifier) {
701
+ }
702
+
703
+ const CLIENT_ID = "/@vite/client";
704
+ const CLIENT_FILE = pathToFileURL(CLIENT_ID).href;
705
+ class ViteExecutor {
706
+ constructor(options) {
707
+ this.options = options;
708
+ this.esm = options.esmExecutor;
709
+ }
710
+ esm;
711
+ resolve = (identifier, parent) => {
712
+ if (identifier === CLIENT_ID) {
713
+ if (this.workerState.environment.transformMode === "web")
714
+ return identifier;
715
+ const packageName = this.getPackageName(parent);
716
+ throw new Error(
717
+ `[vitest] Vitest cannot handle ${CLIENT_ID} imported in ${parent} when running in SSR environment. Add "${packageName}" to "ssr.noExternal" if you are using Vite SSR, or to "server.deps.inline" if you are using Vite Node.`
718
+ );
719
+ }
720
+ };
721
+ get workerState() {
722
+ return this.options.context.__vitest_worker__;
723
+ }
724
+ getPackageName(modulePath) {
725
+ const path = normalize(modulePath);
726
+ let name = path.split("/node_modules/").pop() || "";
727
+ if (name == null ? void 0 : name.startsWith("@"))
728
+ name = name.split("/").slice(0, 2).join("/");
729
+ else
730
+ name = name.split("/")[0];
731
+ return name;
732
+ }
733
+ async createViteModule(fileUrl) {
734
+ if (fileUrl === CLIENT_FILE)
735
+ return this.createViteClientModule();
736
+ const cached = this.esm.resolveCachedModule(fileUrl);
737
+ if (cached)
738
+ return cached;
739
+ const result = await this.options.transform(fileUrl, "web");
740
+ if (!result.code)
741
+ throw new Error(`[vitest] Failed to transform ${fileUrl}. Does the file exist?`);
742
+ return this.esm.createEsModule(fileUrl, result.code);
743
+ }
744
+ createViteClientModule() {
745
+ const identifier = CLIENT_ID;
746
+ const cached = this.esm.resolveCachedModule(identifier);
747
+ if (cached)
748
+ return cached;
749
+ const stub = this.options.viteClientModule;
750
+ const moduleKeys = Object.keys(stub);
751
+ const module = new SyntheticModule$1(
752
+ moduleKeys,
753
+ () => {
754
+ moduleKeys.forEach((key) => {
755
+ module.setExport(key, stub[key]);
756
+ });
757
+ },
758
+ { context: this.options.context, identifier }
759
+ );
760
+ this.esm.cacheModule(identifier, module);
761
+ return module;
762
+ }
763
+ canResolve = (fileUrl) => {
764
+ var _a;
765
+ const transformMode = this.workerState.environment.transformMode;
766
+ if (transformMode !== "web")
767
+ return false;
768
+ if (fileUrl === CLIENT_FILE)
769
+ return true;
770
+ const config = ((_a = this.workerState.config.deps) == null ? void 0 : _a.web) || {};
771
+ const [modulePath] = fileUrl.split("?");
772
+ if (config.transformCss && CSS_LANGS_RE.test(modulePath))
773
+ return true;
774
+ if (config.transformAssets && KNOWN_ASSET_RE.test(modulePath))
775
+ return true;
776
+ if (toArray(config.transformGlobPattern).some((pattern) => pattern.test(modulePath)))
777
+ return true;
778
+ return false;
779
+ };
780
+ }
781
+
782
+ const SyntheticModule = vm.SyntheticModule;
783
+ const nativeResolve = import.meta.resolve;
784
+ class ExternalModulesExecutor {
785
+ constructor(options) {
786
+ this.options = options;
787
+ this.context = options.context;
788
+ this.fs = options.fileMap;
789
+ this.esm = new EsmExecutor(this, {
790
+ context: this.context
791
+ });
792
+ this.cjs = new CommonjsExecutor({
793
+ context: this.context,
794
+ importModuleDynamically: this.importModuleDynamically,
795
+ fileMap: options.fileMap
796
+ });
797
+ this.vite = new ViteExecutor({
798
+ esmExecutor: this.esm,
799
+ context: this.context,
800
+ transform: options.transform,
801
+ viteClientModule: options.requestStubs["/@vite/client"]
802
+ });
803
+ this.resolvers = [this.vite.resolve];
804
+ }
805
+ cjs;
806
+ esm;
807
+ vite;
808
+ context;
809
+ fs;
810
+ resolvers = [];
811
+ // dynamic import can be used in both ESM and CJS, so we have it in the executor
812
+ importModuleDynamically = async (specifier, referencer) => {
813
+ const module = await this.resolveModule(specifier, referencer.identifier);
814
+ return this.esm.evaluateModule(module);
815
+ };
816
+ resolveModule = async (specifier, referencer) => {
817
+ const identifier = await this.resolve(specifier, referencer);
818
+ return await this.createModule(identifier);
819
+ };
820
+ async resolve(specifier, parent) {
821
+ for (const resolver of this.resolvers) {
822
+ const id = resolver(specifier, parent);
823
+ if (id)
824
+ return id;
825
+ }
826
+ return nativeResolve(specifier, parent);
827
+ }
828
+ findNearestPackageData(basedir) {
829
+ var _a;
830
+ const originalBasedir = basedir;
831
+ const packageCache = this.options.packageCache;
832
+ while (basedir) {
833
+ const cached = getCachedData(packageCache, basedir, originalBasedir);
834
+ if (cached)
835
+ return cached;
836
+ const pkgPath = join(basedir, "package.json");
837
+ try {
838
+ if ((_a = statSync(pkgPath, { throwIfNoEntry: false })) == null ? void 0 : _a.isFile()) {
839
+ const pkgData = JSON.parse(this.fs.readFile(pkgPath));
840
+ if (packageCache)
841
+ setCacheData(packageCache, pkgData, basedir, originalBasedir);
842
+ return pkgData;
843
+ }
844
+ } catch {
845
+ }
846
+ const nextBasedir = dirname$1(basedir);
847
+ if (nextBasedir === basedir)
848
+ break;
849
+ basedir = nextBasedir;
850
+ }
851
+ return {};
852
+ }
853
+ wrapCoreSynteticModule(identifier, exports) {
854
+ const moduleKeys = Object.keys(exports);
855
+ const m = new SyntheticModule(
856
+ [...moduleKeys, "default"],
857
+ () => {
858
+ for (const key of moduleKeys)
859
+ m.setExport(key, exports[key]);
860
+ m.setExport("default", exports);
861
+ },
862
+ {
863
+ context: this.context,
864
+ identifier
865
+ }
866
+ );
867
+ return m;
868
+ }
869
+ wrapCommonJsSynteticModule(identifier, exports) {
870
+ const { keys, moduleExports, defaultExport } = interopCommonJsModule(this.options.interopDefault, exports);
871
+ const m = new SyntheticModule(
872
+ [...keys, "default"],
873
+ () => {
874
+ for (const key of keys)
875
+ m.setExport(key, moduleExports[key]);
876
+ m.setExport("default", defaultExport);
877
+ },
878
+ {
879
+ context: this.context,
880
+ identifier
881
+ }
882
+ );
883
+ return m;
884
+ }
885
+ getModuleInformation(identifier) {
738
886
  if (identifier.startsWith("data:"))
739
- return this.createDataModule(identifier);
887
+ return { type: "data", url: identifier, path: identifier };
740
888
  const extension = extname(identifier);
741
- if (extension === ".node" || isNodeBuiltin(identifier)) {
742
- const exports2 = this.requireCoreModule(identifier);
743
- return this.wrapSynteticModule(identifier, exports2);
744
- }
889
+ if (extension === ".node" || isNodeBuiltin(identifier))
890
+ return { type: "builtin", url: identifier, path: identifier };
745
891
  const isFileUrl = identifier.startsWith("file://");
746
- const fileUrl = isFileUrl ? identifier : pathToFileURL(identifier).toString();
747
892
  const pathUrl = isFileUrl ? fileURLToPath(identifier.split("?")[0]) : identifier;
748
- if (extension === ".cjs") {
749
- const module2 = this.createCommonJSNodeModule(pathUrl);
750
- const exports2 = this.loadCommonJSModule(module2, pathUrl);
751
- return this.wrapSynteticModule(fileUrl, exports2);
893
+ const fileUrl = isFileUrl ? identifier : pathToFileURL(pathUrl).toString();
894
+ let type;
895
+ if (this.vite.canResolve(fileUrl)) {
896
+ type = "vite";
897
+ } else if (extension === ".mjs") {
898
+ type = "module";
899
+ } else if (extension === ".cjs") {
900
+ type = "commonjs";
901
+ } else {
902
+ const pkgData = this.findNearestPackageData(normalize(pathUrl));
903
+ type = pkgData.type === "module" ? "module" : "commonjs";
904
+ }
905
+ return { type, path: pathUrl, url: fileUrl };
906
+ }
907
+ async createModule(identifier) {
908
+ const { type, url, path } = this.getModuleInformation(identifier);
909
+ switch (type) {
910
+ case "data":
911
+ return this.esm.createDataModule(identifier);
912
+ case "builtin": {
913
+ const exports = this.require(identifier);
914
+ return this.wrapCoreSynteticModule(identifier, exports);
915
+ }
916
+ case "vite":
917
+ return await this.vite.createViteModule(url);
918
+ case "module":
919
+ return await this.esm.createEsModule(url, this.fs.readFile(path));
920
+ case "commonjs": {
921
+ const exports = this.require(path);
922
+ return this.wrapCommonJsSynteticModule(identifier, exports);
923
+ }
924
+ default: {
925
+ const _deadend = type;
926
+ return _deadend;
927
+ }
752
928
  }
753
- if (extension === ".mjs")
754
- return await this.createEsmModule(fileUrl, this.readFile(pathUrl));
755
- const pkgData = this.findNearestPackageData(normalize(pathUrl));
756
- if (pkgData.type === "module")
757
- return await this.createEsmModule(fileUrl, this.readFile(pathUrl));
758
- const module = this.createCommonJSNodeModule(pathUrl);
759
- const exports = this.loadCommonJSModule(module, pathUrl);
760
- return this.wrapSynteticModule(fileUrl, exports);
761
929
  }
762
930
  async import(identifier) {
763
931
  const module = await this.createModule(identifier);
764
- await this.evaluateModule(module);
932
+ await this.esm.evaluateModule(module);
765
933
  return module.namespace;
766
934
  }
935
+ require(identifier) {
936
+ return this.cjs.require(identifier);
937
+ }
938
+ createRequire(identifier) {
939
+ return this.cjs.createRequire(identifier);
940
+ }
941
+ }
942
+
943
+ class FileMap {
944
+ fsCache = /* @__PURE__ */ new Map();
945
+ fsBufferCache = /* @__PURE__ */ new Map();
946
+ readFile(path) {
947
+ const cached = this.fsCache.get(path);
948
+ if (cached)
949
+ return cached;
950
+ const source = readFileSync(path, "utf-8");
951
+ this.fsCache.set(path, source);
952
+ return source;
953
+ }
954
+ readBuffer(path) {
955
+ const cached = this.fsBufferCache.get(path);
956
+ if (cached)
957
+ return cached;
958
+ const buffer = readFileSync(path);
959
+ this.fsBufferCache.set(path, buffer);
960
+ return buffer;
961
+ }
767
962
  }
768
963
 
769
964
  const entryUrl = pathToFileURL(resolve(distDir, "entry.js")).href;
@@ -777,6 +972,7 @@ let _viteNode;
777
972
  const packageCache = /* @__PURE__ */ new Map();
778
973
  const moduleCache = new ModuleCacheMap();
779
974
  const mockMap = /* @__PURE__ */ new Map();
975
+ const fileMap = new FileMap();
780
976
  async function startViteNode(options) {
781
977
  if (_viteNode)
782
978
  return _viteNode;
@@ -818,6 +1014,9 @@ async function startVitestExecutor(options) {
818
1014
  resolveId(id, importer) {
819
1015
  return rpc().resolveId(id, importer, getTransformMode());
820
1016
  },
1017
+ transform(id) {
1018
+ return rpc().transform(id, "web");
1019
+ },
821
1020
  packageCache,
822
1021
  moduleCache,
823
1022
  mockMap,
@@ -860,7 +1059,11 @@ function removeStyle(id) {
860
1059
  }
861
1060
  class VitestExecutor extends ViteNodeRunner {
862
1061
  constructor(options) {
863
- super(options);
1062
+ super({
1063
+ ...options,
1064
+ // interop is done inside the external executor instead
1065
+ interopDefault: options.context ? false : options.interopDefault
1066
+ });
864
1067
  this.options = options;
865
1068
  this.mocker = new VitestMocker(this);
866
1069
  if (!options.context) {
@@ -880,10 +1083,6 @@ class VitestExecutor extends ViteNodeRunner {
880
1083
  Symbol
881
1084
  };
882
1085
  } else {
883
- this.externalModules = new ExternalModulesExecutor({
884
- context: options.context,
885
- packageCache: options.packageCache
886
- });
887
1086
  const clientStub = vm.runInContext(
888
1087
  `(defaultClient) => ({ ...defaultClient, updateStyle: ${updateStyle.toString()}, removeStyle: ${removeStyle.toString()} })`,
889
1088
  options.context
@@ -893,6 +1092,12 @@ class VitestExecutor extends ViteNodeRunner {
893
1092
  "@vite/client": clientStub
894
1093
  };
895
1094
  this.primitives = vm.runInContext("({ Object, Reflect, Symbol })", options.context);
1095
+ this.externalModules = new ExternalModulesExecutor({
1096
+ ...options,
1097
+ fileMap,
1098
+ context: options.context,
1099
+ packageCache: options.packageCache
1100
+ });
896
1101
  }
897
1102
  }
898
1103
  mocker;