vite 6.0.0-alpha.2 → 6.0.0-alpha.4

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.
@@ -117,12 +117,12 @@ declare class ModuleRunner {
117
117
  */
118
118
  moduleCache: ModuleCacheMap;
119
119
  hmrClient?: HMRClient;
120
- private idToUrlMap;
121
- private fileToIdMap;
122
- private envProxy;
123
- private transport;
124
- private _destroyed;
125
- private _resetSourceMapSupport?;
120
+ private readonly urlToIdMap;
121
+ private readonly fileToIdMap;
122
+ private readonly envProxy;
123
+ private readonly transport;
124
+ private readonly resetSourceMapSupport?;
125
+ private destroyed;
126
126
  constructor(options: ModuleRunnerOptions, evaluator: ModuleEvaluator, debug?: ModuleRunnerDebugger | undefined);
127
127
  /**
128
128
  * URL to execute. Accepts file path, server path or id relative to the root.
@@ -141,12 +141,11 @@ declare class ModuleRunner {
141
141
  * Returns `true` if the runtime has been destroyed by calling `destroy()` method.
142
142
  */
143
143
  isDestroyed(): boolean;
144
- private invalidateFiles;
145
144
  private normalizeEntryUrl;
146
145
  private processImport;
147
146
  private cachedRequest;
148
147
  private cachedModule;
149
- protected directRequest(id: string, fetchResult: ResolvedResult, _callstack: string[]): Promise<any>;
148
+ protected directRequest(id: string, mod: ModuleCache, _callstack: string[]): Promise<any>;
150
149
  }
151
150
 
152
151
  interface RetrieveFileHandler {
@@ -217,7 +216,8 @@ interface ModuleCache {
217
216
  exports?: any;
218
217
  evaluated?: boolean;
219
218
  map?: DecodedMap;
220
- meta?: FetchResult;
219
+ meta?: ResolvedResult;
220
+ timestamp?: number;
221
221
  /**
222
222
  * Module ids that imports this module
223
223
  */
@@ -314,7 +314,8 @@ declare class ModuleCacheMap extends Map<string, ModuleCache> {
314
314
  get(fsPath: string): ModuleCache;
315
315
  deleteByModuleId(modulePath: string): boolean;
316
316
  delete(fsPath: string): boolean;
317
- invalidate(id: string): void;
317
+ invalidateUrl(id: string): void;
318
+ invalidateModule(module: ModuleCache): void;
318
319
  /**
319
320
  * Invalidate modules that dependent on the given modules, up to the main entry
320
321
  */
@@ -77,7 +77,15 @@ const isAbsolute = function(p) {
77
77
  }, dirname = function(p) {
78
78
  const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1);
79
79
  return segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0]) && (segments[0] += "/"), segments.join("/") || (isAbsolute(p) ? "/" : ".");
80
- }, decodeBase64 = typeof atob < "u" ? atob : (str) => Buffer.from(str, "base64").toString("utf-8"), CHAR_FORWARD_SLASH = 47, CHAR_BACKWARD_SLASH = 92, percentRegEx = /%/g, backslashRegEx = /\\/g, newlineRegEx = /\n/g, carriageReturnRegEx = /\r/g, tabRegEx = /\t/g, questionRegex = /\?/g, hashRegex = /#/g;
80
+ }, decodeBase64 = typeof atob < "u" ? atob : (str) => Buffer.from(str, "base64").toString("utf-8"), CHAR_FORWARD_SLASH = 47, CHAR_BACKWARD_SLASH = 92, percentRegEx = /%/g, backslashRegEx = /\\/g, newlineRegEx = /\n/g, carriageReturnRegEx = /\r/g, tabRegEx = /\t/g, questionRegex = /\?/g, hashRegex = /#/g, timestampRegex = /[?&]t=(\d{13})(&?)/;
81
+ function parseUrl(url) {
82
+ const idQuery = url.split("?")[1];
83
+ let timestamp = 0;
84
+ return {
85
+ query: idQuery ? ("?" + idQuery).replace(timestampRegex, (substring, tsString, nextItem) => (timestamp = Number(tsString), substring[0] === "?" && nextItem === "&" ? "?" : "")) : "",
86
+ timestamp
87
+ };
88
+ }
81
89
  function encodePathChars(filepath) {
82
90
  return filepath.indexOf("%") !== -1 && (filepath = filepath.replace(percentRegEx, "%25")), !isWindows && filepath.indexOf("\\") !== -1 && (filepath = filepath.replace(backslashRegEx, "%5C")), filepath.indexOf(`
83
91
  `) !== -1 && (filepath = filepath.replace(newlineRegEx, "%0A")), filepath.indexOf("\r") !== -1 && (filepath = filepath.replace(carriageReturnRegEx, "%0D")), filepath.indexOf(" ") !== -1 && (filepath = filepath.replace(tabRegEx, "%09")), filepath;
@@ -251,7 +259,8 @@ class ModuleCacheMap extends Map {
251
259
  const mod = super.get(modulePath);
252
260
  return mod.imports || Object.assign(mod, {
253
261
  imports: /* @__PURE__ */ new Set(),
254
- importers: /* @__PURE__ */ new Set()
262
+ importers: /* @__PURE__ */ new Set(),
263
+ timestamp: 0
255
264
  }), mod;
256
265
  }
257
266
  get(fsPath) {
@@ -263,8 +272,11 @@ class ModuleCacheMap extends Map {
263
272
  delete(fsPath) {
264
273
  return this.deleteByModuleId(this.normalize(fsPath));
265
274
  }
266
- invalidate(id) {
275
+ invalidateUrl(id) {
267
276
  const module = this.get(id);
277
+ this.invalidateModule(module);
278
+ }
279
+ invalidateModule(module) {
268
280
  module.evaluated = !1, module.meta = void 0, module.map = void 0, module.promise = void 0, module.exports = void 0, module.imports?.clear();
269
281
  }
270
282
  /**
@@ -277,7 +289,7 @@ class ModuleCacheMap extends Map {
277
289
  continue;
278
290
  invalidated.add(id);
279
291
  const mod = super.get(id);
280
- mod?.importers && this.invalidateDepTree(mod.importers, invalidated), this.invalidate(id);
292
+ mod?.importers && this.invalidateDepTree(mod.importers, invalidated), this.invalidateUrl(id);
281
293
  }
282
294
  return invalidated;
283
295
  }
@@ -366,7 +378,7 @@ class HMRContext {
366
378
  }), this.send("vite:invalidate", {
367
379
  path: this.ownerPath,
368
380
  message
369
- }), this.hmrClient.logger.debug(`[vite] invalidate ${this.ownerPath}${message ? `: ${message}` : ""}`);
381
+ }), this.hmrClient.logger.debug(`invalidate ${this.ownerPath}${message ? `: ${message}` : ""}`);
370
382
  }
371
383
  on(event, cb) {
372
384
  const addToMap = (map) => {
@@ -451,7 +463,7 @@ class HMRClient {
451
463
  });
452
464
  }
453
465
  warnFailedUpdate(err, path) {
454
- err.message.includes("fetch") || this.logger.error(err), this.logger.error(`[hmr] Failed to reload ${path}. This could be due to syntax errors or importing non-existent modules. (see errors above)`);
466
+ err.message.includes("fetch") || this.logger.error(err), this.logger.error(`Failed to reload ${path}. This could be due to syntax errors or importing non-existent modules. (see errors above)`);
455
467
  }
456
468
  updateQueue = [];
457
469
  pendingUpdateQueue = !1;
@@ -486,7 +498,7 @@ class HMRClient {
486
498
  for (const { deps, fn } of qualifiedCallbacks)
487
499
  fn(deps.map((dep) => dep === acceptedPath ? fetchedModule : void 0));
488
500
  const loggedPath = isSelfUpdate ? path : `${acceptedPath} via ${path}`;
489
- this.logger.debug(`[vite] hot updated: ${loggedPath}`);
501
+ this.logger.debug(`hot updated: ${loggedPath}`);
490
502
  };
491
503
  }
492
504
  }
@@ -517,6 +529,9 @@ const ssrModuleExportsKey = "__vite_ssr_exports__", ssrImportKey = "__vite_ssr_i
517
529
  }, silentConsole = {
518
530
  debug: noop,
519
531
  error: noop
532
+ }, hmrLogger = {
533
+ debug: (...msg) => console.log("[vite]", ...msg),
534
+ error: (error) => console.log("[vite]", error)
520
535
  };
521
536
  function createHMRHandler(runner) {
522
537
  const queue = new Queue();
@@ -527,13 +542,13 @@ async function handleHMRPayload(runner, payload) {
527
542
  if (!(!hmrClient || runner.isDestroyed()))
528
543
  switch (payload.type) {
529
544
  case "connected":
530
- hmrClient.logger.debug("[vite] connected."), hmrClient.messenger.flush();
545
+ hmrClient.logger.debug("connected."), hmrClient.messenger.flush();
531
546
  break;
532
547
  case "update":
533
548
  await hmrClient.notifyListeners("vite:beforeUpdate", payload), await Promise.all(payload.updates.map(async (update) => {
534
549
  if (update.type === "js-update")
535
550
  return update.acceptedPath = unwrapId(update.acceptedPath), update.path = unwrapId(update.path), hmrClient.queueUpdate(update);
536
- hmrClient.logger.error("[vite] css hmr is not supported in runner mode.");
551
+ hmrClient.logger.error("css hmr is not supported in runner mode.");
537
552
  })), await hmrClient.notifyListeners("vite:afterUpdate", payload);
538
553
  break;
539
554
  case "custom": {
@@ -544,7 +559,7 @@ async function handleHMRPayload(runner, payload) {
544
559
  const { triggeredBy } = payload, clearEntrypoints = triggeredBy ? getModulesEntrypoints(runner, getModulesByFile(runner, slash(triggeredBy))) : findAllEntrypoints(runner);
545
560
  if (!clearEntrypoints.size)
546
561
  break;
547
- hmrClient.logger.debug("[vite] program reload"), await hmrClient.notifyListeners("vite:beforeFullReload", payload), runner.moduleCache.clear();
562
+ hmrClient.logger.debug("program reload"), await hmrClient.notifyListeners("vite:beforeFullReload", payload), runner.moduleCache.clear();
548
563
  for (const id of clearEntrypoints)
549
564
  await runner.import(id);
550
565
  break;
@@ -555,7 +570,7 @@ async function handleHMRPayload(runner, payload) {
555
570
  case "error": {
556
571
  await hmrClient.notifyListeners("vite:error", payload);
557
572
  const err = payload.err;
558
- hmrClient.logger.error(`[vite] Internal Server Error
573
+ hmrClient.logger.error(`Internal Server Error
559
574
  ${err.message}
560
575
  ${err.stack}`);
561
576
  break;
@@ -826,7 +841,7 @@ class ModuleRunner {
826
841
  */
827
842
  moduleCache;
828
843
  hmrClient;
829
- idToUrlMap = /* @__PURE__ */ new Map();
844
+ urlToIdMap = /* @__PURE__ */ new Map();
830
845
  fileToIdMap = /* @__PURE__ */ new Map();
831
846
  envProxy = new Proxy({}, {
832
847
  get(_, p) {
@@ -834,10 +849,13 @@ class ModuleRunner {
834
849
  }
835
850
  });
836
851
  transport;
837
- _destroyed = !1;
838
- _resetSourceMapSupport;
852
+ resetSourceMapSupport;
853
+ destroyed = !1;
839
854
  constructor(options, evaluator, debug) {
840
- this.options = options, this.evaluator = evaluator, this.debug = debug, this.moduleCache = options.moduleCache ?? new ModuleCacheMap(options.root), this.transport = options.transport, typeof options.hmr == "object" && (this.hmrClient = new HMRClient(options.hmr.logger === !1 ? silentConsole : options.hmr.logger || console, options.hmr.connection, ({ acceptedPath, invalidates }) => (this.moduleCache.invalidate(acceptedPath), invalidates && this.invalidateFiles(invalidates), this.import(acceptedPath))), options.hmr.connection.onUpdate(createHMRHandler(this))), options.sourcemapInterceptor !== !1 && (this._resetSourceMapSupport = enableSourceMapSupport(this));
855
+ this.options = options, this.evaluator = evaluator, this.debug = debug, this.moduleCache = options.moduleCache ?? new ModuleCacheMap(options.root), this.transport = options.transport, typeof options.hmr == "object" && (this.hmrClient = new HMRClient(options.hmr.logger === !1 ? silentConsole : options.hmr.logger || hmrLogger, options.hmr.connection, ({ acceptedPath, explicitImportRequired, timestamp }) => {
856
+ const [acceptedPathWithoutQuery, query] = acceptedPath.split("?"), url = acceptedPathWithoutQuery + `?${explicitImportRequired ? "import&" : ""}t=${timestamp}${query ? `&${query}` : ""}`;
857
+ return this.import(url);
858
+ }), options.hmr.connection.onUpdate(createHMRHandler(this))), options.sourcemapInterceptor !== !1 && (this.resetSourceMapSupport = enableSourceMapSupport(this));
841
859
  }
842
860
  /**
843
861
  * URL to execute. Accepts file path, server path or id relative to the root.
@@ -851,27 +869,20 @@ class ModuleRunner {
851
869
  * Clear all caches including HMR listeners.
852
870
  */
853
871
  clearCache() {
854
- this.moduleCache.clear(), this.idToUrlMap.clear(), this.hmrClient?.clear();
872
+ this.moduleCache.clear(), this.urlToIdMap.clear(), this.hmrClient?.clear();
855
873
  }
856
874
  /**
857
875
  * Clears all caches, removes all HMR listeners, and resets source map support.
858
876
  * This method doesn't stop the HMR connection.
859
877
  */
860
878
  async destroy() {
861
- this._resetSourceMapSupport?.(), this.clearCache(), this.hmrClient = void 0, this._destroyed = !0;
879
+ this.resetSourceMapSupport?.(), this.clearCache(), this.hmrClient = void 0, this.destroyed = !0;
862
880
  }
863
881
  /**
864
882
  * Returns `true` if the runtime has been destroyed by calling `destroy()` method.
865
883
  */
866
884
  isDestroyed() {
867
- return this._destroyed;
868
- }
869
- // map files to modules and invalidate them
870
- invalidateFiles(files) {
871
- files.forEach((file) => {
872
- const ids = this.fileToIdMap.get(file);
873
- ids && ids.forEach((id) => this.moduleCache.invalidate(id));
874
- });
885
+ return this.destroyed;
875
886
  }
876
887
  // we don't use moduleCache.normalize because this URL doesn't have to follow the same rules
877
888
  // this URL is something that user passes down manually, and is later resolved by fetchModule
@@ -889,10 +900,10 @@ class ModuleRunner {
889
900
  const { id, type } = fetchResult;
890
901
  return type !== "module" && type !== "commonjs" ? exports : (analyzeImportedModDifference(exports, id, type, metadata), proxyGuardOnlyEsm(exports, id, metadata));
891
902
  }
892
- async cachedRequest(id, fetchedModule, callstack = [], metadata) {
893
- const moduleId = fetchedModule.id, mod = this.moduleCache.getByModuleId(moduleId), { imports, importers } = mod, importee = callstack[callstack.length - 1];
903
+ async cachedRequest(id, mod, callstack = [], metadata) {
904
+ const meta = mod.meta, moduleId = meta.id, { imports, importers } = mod, importee = callstack[callstack.length - 1];
894
905
  if (importee && importers.add(importee), (callstack.includes(moduleId) || Array.from(imports.values()).some((i) => importers.has(i))) && mod.exports)
895
- return this.processImport(mod.exports, fetchedModule, metadata);
906
+ return this.processImport(mod.exports, meta, metadata);
896
907
  let debugTimer;
897
908
  this.debug && (debugTimer = setTimeout(() => {
898
909
  const getStack = () => `stack:
@@ -903,35 +914,35 @@ ${getStack()}`);
903
914
  }, 2e3));
904
915
  try {
905
916
  if (mod.promise)
906
- return this.processImport(await mod.promise, fetchedModule, metadata);
907
- const promise = this.directRequest(id, fetchedModule, callstack);
908
- return mod.promise = promise, mod.evaluated = !1, this.processImport(await promise, fetchedModule, metadata);
917
+ return this.processImport(await mod.promise, meta, metadata);
918
+ const promise = this.directRequest(id, mod, callstack);
919
+ return mod.promise = promise, mod.evaluated = !1, this.processImport(await promise, meta, metadata);
909
920
  } finally {
910
921
  mod.evaluated = !0, debugTimer && clearTimeout(debugTimer);
911
922
  }
912
923
  }
913
- async cachedModule(id, importer) {
914
- if (this._destroyed)
915
- throw new Error("[vite] Vite runtime has been destroyed.");
916
- const normalized = this.idToUrlMap.get(id);
924
+ async cachedModule(url, importer) {
925
+ if (this.destroyed)
926
+ throw new Error("Vite module runner has been destroyed.");
927
+ const normalized = this.urlToIdMap.get(url);
917
928
  if (normalized) {
918
929
  const mod2 = this.moduleCache.getByModuleId(normalized);
919
930
  if (mod2.meta)
920
- return mod2.meta;
931
+ return mod2;
921
932
  }
922
- this.debug?.("[module runner] fetching", id);
923
- const fetchedModule = id.startsWith("data:") ? { externalize: id, type: "builtin" } : await this.transport.fetchModule(id, importer), idQuery = id.split("?")[1], query = idQuery ? `?${idQuery}` : "", file = "file" in fetchedModule ? fetchedModule.file : void 0, fullFile = file ? `${file}${query}` : id, moduleId = this.moduleCache.normalize(fullFile), mod = this.moduleCache.getByModuleId(moduleId);
924
- if (fetchedModule.id = moduleId, mod.meta = fetchedModule, file) {
933
+ this.debug?.("[module runner] fetching", url);
934
+ const fetchedModule = url.startsWith("data:") ? { externalize: url, type: "builtin" } : await this.transport.fetchModule(url, importer), { query, timestamp } = parseUrl(url), file = "file" in fetchedModule ? fetchedModule.file : void 0, fileId = file ? `${file}${query}` : url, moduleId = this.moduleCache.normalize(fileId), mod = this.moduleCache.getByModuleId(moduleId);
935
+ if (mod.timestamp != null && timestamp > 0 && mod.timestamp < timestamp && this.moduleCache.invalidateModule(mod), fetchedModule.id = moduleId, mod.meta = fetchedModule, mod.timestamp = timestamp, file) {
925
936
  const fileModules = this.fileToIdMap.get(file) || [];
926
937
  fileModules.push(moduleId), this.fileToIdMap.set(file, fileModules);
927
938
  }
928
- return this.idToUrlMap.set(id, moduleId), this.idToUrlMap.set(unwrapId(id), moduleId), fetchedModule;
939
+ return this.urlToIdMap.set(url, moduleId), this.urlToIdMap.set(unwrapId(url), moduleId), mod;
929
940
  }
930
941
  // override is allowed, consider this a public API
931
- async directRequest(id, fetchResult, _callstack) {
932
- const moduleId = fetchResult.id, callstack = [..._callstack, moduleId], mod = this.moduleCache.getByModuleId(moduleId), request = async (dep, metadata) => {
933
- const fetchedModule = await this.cachedModule(dep, moduleId);
934
- return this.moduleCache.getByModuleId(fetchedModule.id).importers.add(moduleId), mod.imports.add(fetchedModule.id), this.cachedRequest(dep, fetchedModule, callstack, metadata);
942
+ async directRequest(id, mod, _callstack) {
943
+ const fetchResult = mod.meta, moduleId = fetchResult.id, callstack = [..._callstack, moduleId], request = async (dep, metadata) => {
944
+ const importer = "file" in fetchResult && fetchResult.file || moduleId, fetchedModule = await this.cachedModule(dep, importer), resolvedId = fetchedModule.meta.id;
945
+ return this.moduleCache.getByModuleId(resolvedId).importers.add(moduleId), mod.imports.add(resolvedId), this.cachedRequest(dep, fetchedModule, callstack, metadata);
935
946
  }, dynamicRequest = async (dep) => (dep = String(dep), dep[0] === "." && (dep = posixResolve(posixDirname(id), dep)), request(dep, { isDynamicImport: !0 }));
936
947
  if ("externalize" in fetchResult) {
937
948
  const { externalize } = fetchResult;
@@ -2956,9 +2956,9 @@ const isObject$2 = val => val && typeof val === 'object' && !Array.isArray(val);
2956
2956
  * @api public
2957
2957
  */
2958
2958
 
2959
- const picomatch$1 = (glob, options, returnState = false) => {
2959
+ const picomatch$2 = (glob, options, returnState = false) => {
2960
2960
  if (Array.isArray(glob)) {
2961
- const fns = glob.map(input => picomatch$1(input, options, returnState));
2961
+ const fns = glob.map(input => picomatch$2(input, options, returnState));
2962
2962
  const arrayMatcher = str => {
2963
2963
  for (const isMatch of fns) {
2964
2964
  const state = isMatch(str);
@@ -2978,8 +2978,8 @@ const picomatch$1 = (glob, options, returnState = false) => {
2978
2978
  const opts = options || {};
2979
2979
  const posix = utils.isWindows(options);
2980
2980
  const regex = isState
2981
- ? picomatch$1.compileRe(glob, options)
2982
- : picomatch$1.makeRe(glob, options, false, true);
2981
+ ? picomatch$2.compileRe(glob, options)
2982
+ : picomatch$2.makeRe(glob, options, false, true);
2983
2983
 
2984
2984
  const state = regex.state;
2985
2985
  delete regex.state;
@@ -2987,11 +2987,11 @@ const picomatch$1 = (glob, options, returnState = false) => {
2987
2987
  let isIgnored = () => false;
2988
2988
  if (opts.ignore) {
2989
2989
  const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };
2990
- isIgnored = picomatch$1(opts.ignore, ignoreOpts, returnState);
2990
+ isIgnored = picomatch$2(opts.ignore, ignoreOpts, returnState);
2991
2991
  }
2992
2992
 
2993
2993
  const matcher = (input, returnObject = false) => {
2994
- const { isMatch, match, output } = picomatch$1.test(input, regex, options, { glob, posix });
2994
+ const { isMatch, match, output } = picomatch$2.test(input, regex, options, { glob, posix });
2995
2995
  const result = { glob, state, regex, posix, input, output, match, isMatch };
2996
2996
 
2997
2997
  if (typeof opts.onResult === 'function') {
@@ -3041,7 +3041,7 @@ const picomatch$1 = (glob, options, returnState = false) => {
3041
3041
  * @api public
3042
3042
  */
3043
3043
 
3044
- picomatch$1.test = (input, regex, options, { glob, posix } = {}) => {
3044
+ picomatch$2.test = (input, regex, options, { glob, posix } = {}) => {
3045
3045
  if (typeof input !== 'string') {
3046
3046
  throw new TypeError('Expected input to be a string');
3047
3047
  }
@@ -3062,7 +3062,7 @@ picomatch$1.test = (input, regex, options, { glob, posix } = {}) => {
3062
3062
 
3063
3063
  if (match === false || opts.capture === true) {
3064
3064
  if (opts.matchBase === true || opts.basename === true) {
3065
- match = picomatch$1.matchBase(input, regex, options, posix);
3065
+ match = picomatch$2.matchBase(input, regex, options, posix);
3066
3066
  } else {
3067
3067
  match = regex.exec(output);
3068
3068
  }
@@ -3085,8 +3085,8 @@ picomatch$1.test = (input, regex, options, { glob, posix } = {}) => {
3085
3085
  * @api public
3086
3086
  */
3087
3087
 
3088
- picomatch$1.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
3089
- const regex = glob instanceof RegExp ? glob : picomatch$1.makeRe(glob, options);
3088
+ picomatch$2.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
3089
+ const regex = glob instanceof RegExp ? glob : picomatch$2.makeRe(glob, options);
3090
3090
  return regex.test(path$1.basename(input));
3091
3091
  };
3092
3092
 
@@ -3107,7 +3107,7 @@ picomatch$1.matchBase = (input, glob, options, posix = utils.isWindows(options))
3107
3107
  * @api public
3108
3108
  */
3109
3109
 
3110
- picomatch$1.isMatch = (str, patterns, options) => picomatch$1(patterns, options)(str);
3110
+ picomatch$2.isMatch = (str, patterns, options) => picomatch$2(patterns, options)(str);
3111
3111
 
3112
3112
  /**
3113
3113
  * Parse a glob pattern to create the source string for a regular
@@ -3123,8 +3123,8 @@ picomatch$1.isMatch = (str, patterns, options) => picomatch$1(patterns, options)
3123
3123
  * @api public
3124
3124
  */
3125
3125
 
3126
- picomatch$1.parse = (pattern, options) => {
3127
- if (Array.isArray(pattern)) return pattern.map(p => picomatch$1.parse(p, options));
3126
+ picomatch$2.parse = (pattern, options) => {
3127
+ if (Array.isArray(pattern)) return pattern.map(p => picomatch$2.parse(p, options));
3128
3128
  return parse$1(pattern, { ...options, fastpaths: false });
3129
3129
  };
3130
3130
 
@@ -3155,7 +3155,7 @@ picomatch$1.parse = (pattern, options) => {
3155
3155
  * @api public
3156
3156
  */
3157
3157
 
3158
- picomatch$1.scan = (input, options) => scan(input, options);
3158
+ picomatch$2.scan = (input, options) => scan(input, options);
3159
3159
 
3160
3160
  /**
3161
3161
  * Compile a regular expression from the `state` object returned by the
@@ -3169,7 +3169,7 @@ picomatch$1.scan = (input, options) => scan(input, options);
3169
3169
  * @api public
3170
3170
  */
3171
3171
 
3172
- picomatch$1.compileRe = (state, options, returnOutput = false, returnState = false) => {
3172
+ picomatch$2.compileRe = (state, options, returnOutput = false, returnState = false) => {
3173
3173
  if (returnOutput === true) {
3174
3174
  return state.output;
3175
3175
  }
@@ -3183,7 +3183,7 @@ picomatch$1.compileRe = (state, options, returnOutput = false, returnState = fal
3183
3183
  source = `^(?!${source}).*$`;
3184
3184
  }
3185
3185
 
3186
- const regex = picomatch$1.toRegex(source, options);
3186
+ const regex = picomatch$2.toRegex(source, options);
3187
3187
  if (returnState === true) {
3188
3188
  regex.state = state;
3189
3189
  }
@@ -3210,7 +3210,7 @@ picomatch$1.compileRe = (state, options, returnOutput = false, returnState = fal
3210
3210
  * @api public
3211
3211
  */
3212
3212
 
3213
- picomatch$1.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
3213
+ picomatch$2.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
3214
3214
  if (!input || typeof input !== 'string') {
3215
3215
  throw new TypeError('Expected a non-empty string');
3216
3216
  }
@@ -3225,7 +3225,7 @@ picomatch$1.makeRe = (input, options = {}, returnOutput = false, returnState = f
3225
3225
  parsed = parse$1(input, options);
3226
3226
  }
3227
3227
 
3228
- return picomatch$1.compileRe(parsed, options, returnOutput, returnState);
3228
+ return picomatch$2.compileRe(parsed, options, returnOutput, returnState);
3229
3229
  };
3230
3230
 
3231
3231
  /**
@@ -3245,7 +3245,7 @@ picomatch$1.makeRe = (input, options = {}, returnOutput = false, returnState = f
3245
3245
  * @api public
3246
3246
  */
3247
3247
 
3248
- picomatch$1.toRegex = (source, options) => {
3248
+ picomatch$2.toRegex = (source, options) => {
3249
3249
  try {
3250
3250
  const opts = options || {};
3251
3251
  return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));
@@ -3260,17 +3260,17 @@ picomatch$1.toRegex = (source, options) => {
3260
3260
  * @return {Object}
3261
3261
  */
3262
3262
 
3263
- picomatch$1.constants = constants;
3263
+ picomatch$2.constants = constants;
3264
3264
 
3265
3265
  /**
3266
3266
  * Expose "picomatch"
3267
3267
  */
3268
3268
 
3269
- var picomatch_1 = picomatch$1;
3269
+ var picomatch_1 = picomatch$2;
3270
3270
 
3271
3271
  var picomatch = picomatch_1;
3272
3272
 
3273
- var pm = /*@__PURE__*/getDefaultExportFromCjs(picomatch);
3273
+ var picomatch$1 = /*@__PURE__*/getDefaultExportFromCjs(picomatch);
3274
3274
 
3275
3275
  // Helper since Typescript can't detect readonly arrays with Array.isArray
3276
3276
  function isArray(arg) {
@@ -3310,7 +3310,7 @@ const createFilter$1 = function createFilter(include, exclude, options) {
3310
3310
  test: (what) => {
3311
3311
  // this refactor is a tad overly verbose but makes for easy debugging
3312
3312
  const pattern = getMatcherString(id, resolutionBase);
3313
- const fn = pm(pattern, { dot: true });
3313
+ const fn = picomatch$1(pattern, { dot: true });
3314
3314
  const result = fn(what);
3315
3315
  return result;
3316
3316
  }
@@ -5435,12 +5435,14 @@ function createLogger(level = 'info', options = {}) {
5435
5435
  const clear = canClearScreen ? clearScreen : () => { };
5436
5436
  function format(type, msg, options = {}) {
5437
5437
  if (options.timestamp) {
5438
- const tag = type === 'info'
5439
- ? colors.cyan(colors.bold(prefix))
5438
+ const color = type === 'info'
5439
+ ? colors.cyan
5440
5440
  : type === 'warn'
5441
- ? colors.yellow(colors.bold(prefix))
5442
- : colors.red(colors.bold(prefix));
5443
- return `${colors.dim(getTimeFormatter().format(new Date()))} ${tag} ${msg}`;
5441
+ ? colors.yellow
5442
+ : colors.red;
5443
+ const tag = color(colors.bold(prefix));
5444
+ const environment = options.environment ? options.environment + ' ' : '';
5445
+ return `${colors.dim(getTimeFormatter().format(new Date()))} ${tag} ${environment}${msg}`;
5444
5446
  }
5445
5447
  else {
5446
5448
  return msg;
@@ -5568,18 +5570,55 @@ function searchForWorkspaceRoot(current, root = searchForPackageRoot(current)) {
5568
5570
  return searchForWorkspaceRoot(dir, root);
5569
5571
  }
5570
5572
 
5573
+ const safeModulePathsCache = new WeakMap();
5574
+ function isSafeModulePath(config, filePath) {
5575
+ let safeModulePaths = safeModulePathsCache.get(config);
5576
+ if (!safeModulePaths) {
5577
+ safeModulePaths = new Set();
5578
+ safeModulePathsCache.set(config, safeModulePaths);
5579
+ }
5580
+ return safeModulePaths.has(filePath);
5581
+ }
5582
+ const fsDenyGlobCache = new WeakMap();
5583
+ function fsDenyGlob(config, filePath) {
5584
+ let matcher = fsDenyGlobCache.get(config);
5585
+ if (!matcher) {
5586
+ (matcher = picomatch$1(
5587
+ // matchBase: true does not work as it's documented
5588
+ // https://github.com/micromatch/picomatch/issues/89
5589
+ // convert patterns without `/` on our side for now
5590
+ config.server.fs.deny.map((pattern) => pattern.includes('/') ? pattern : `**/${pattern}`), {
5591
+ matchBase: false,
5592
+ nocase: true,
5593
+ dot: true,
5594
+ })),
5595
+ fsDenyGlobCache.set(config, matcher);
5596
+ }
5597
+ return matcher(filePath);
5598
+ }
5571
5599
  /**
5572
5600
  * Check if the url is allowed to be served, via the `server.fs` config.
5601
+ * @deprecate use isFileLoadingAllowed
5573
5602
  */
5574
5603
  function isFileServingAllowed(url, server) {
5575
- if (!server.config.server.fs.strict)
5604
+ const { config } = server;
5605
+ if (!config.server.fs.strict)
5606
+ return true;
5607
+ const filePath = fsPathFromUrl(url);
5608
+ return isFileLoadingAllowed(config, filePath);
5609
+ }
5610
+ function isUriInFilePath(uri, filePath) {
5611
+ return isSameFileUri(uri, filePath) || isParentDirectory(uri, filePath);
5612
+ }
5613
+ function isFileLoadingAllowed(config, filePath) {
5614
+ const { fs } = config.server;
5615
+ if (!fs.strict)
5576
5616
  return true;
5577
- const file = fsPathFromUrl(url);
5578
- if (server._fsDenyGlob(file))
5617
+ if (fsDenyGlob(config, filePath))
5579
5618
  return false;
5580
- if (server._safeModulesPath.has(file))
5619
+ if (isSafeModulePath(config, filePath))
5581
5620
  return true;
5582
- if (server.config.server.fs.allow.some((uri) => isSameFileUri(uri, file) || isParentDirectory(uri, file)))
5621
+ if (fs.allow.some((uri) => isUriInFilePath(uri, filePath)))
5583
5622
  return true;
5584
5623
  return false;
5585
5624
  }
package/index.cjs CHANGED
@@ -6,6 +6,7 @@ warnCjsUsage()
6
6
  module.exports.defineConfig = (config) => config
7
7
 
8
8
  // proxy cjs utils (sync functions)
9
+ // eslint-disable-next-line n/no-missing-require -- will be generated by build
9
10
  Object.assign(module.exports, require('./dist/node-cjs/publicUtils.cjs'))
10
11
 
11
12
  // async functions, can be redirect from ESM build
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite",
3
- "version": "6.0.0-alpha.2",
3
+ "version": "6.0.0-alpha.4",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": "Evan You",
@@ -114,7 +114,7 @@
114
114
  "http-proxy": "^1.18.1",
115
115
  "launch-editor-middleware": "^2.6.1",
116
116
  "lightningcss": "^1.24.1",
117
- "magic-string": "^0.30.9",
117
+ "magic-string": "^0.30.10",
118
118
  "micromatch": "^4.0.5",
119
119
  "mlly": "^1.6.1",
120
120
  "mrmime": "^2.0.0",
@@ -131,7 +131,7 @@
131
131
  "rollup-plugin-dts": "^6.1.0",
132
132
  "rollup-plugin-esbuild": "^6.1.1",
133
133
  "rollup-plugin-license": "^3.3.1",
134
- "sass": "^1.74.1",
134
+ "sass": "^1.75.0",
135
135
  "sirv": "^2.0.4",
136
136
  "source-map-support": "^0.5.21",
137
137
  "strip-ansi": "^7.1.0",