vite 5.0.4 → 5.0.6

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.
@@ -27,11 +27,11 @@ import { createHash as createHash$2 } from 'node:crypto';
27
27
  import { promises } from 'node:dns';
28
28
  import { CLIENT_ENTRY, VALID_ID_PREFIX, NULL_BYTE_PLACEHOLDER, OPTIMIZABLE_ENTRY_RE, FS_PREFIX, wildcardHosts, loopbackHosts, CLIENT_PUBLIC_PATH, ENV_PUBLIC_PATH, ENV_ENTRY, DEP_VERSION_RE, SPECIAL_QUERY_RE, DEFAULT_MAIN_FIELDS, DEFAULT_EXTENSIONS, CSS_LANGS_RE, ESBUILD_MODULES_TARGET, KNOWN_ASSET_TYPES, VITE_PACKAGE_DIR, DEFAULT_DEV_PORT, CLIENT_DIR, JS_TYPES_RE, VERSION as VERSION$1, DEFAULT_PREVIEW_PORT, DEFAULT_ASSETS_RE, DEFAULT_CONFIG_FILES } from '../constants.js';
29
29
  import require$$0$a from 'crypto';
30
- import { Buffer as Buffer$1 } from 'node:buffer';
31
30
  import require$$0$8, { createRequire as createRequire$2 } from 'module';
32
31
  import assert$1 from 'node:assert';
33
32
  import process$1 from 'node:process';
34
33
  import v8 from 'node:v8';
34
+ import { Buffer as Buffer$1 } from 'node:buffer';
35
35
  import { VERSION } from 'rollup';
36
36
  import { parseAstAsync, parseAst } from 'rollup/parseAst';
37
37
  import * as qs from 'querystring';
@@ -2769,7 +2769,17 @@ function serialize(obj, indent, baseIndent) {
2769
2769
  return `${obj}n`;
2770
2770
  return stringify$8(obj);
2771
2771
  }
2772
+ // isWellFormed exists from Node.js 20
2773
+ const hasStringIsWellFormed = 'isWellFormed' in String.prototype;
2774
+ function isWellFormedString(input) {
2775
+ // @ts-expect-error String::isWellFormed exists from ES2024. tsconfig lib is set to ES6
2776
+ if (hasStringIsWellFormed)
2777
+ return input.isWellFormed();
2778
+ // https://github.com/tc39/proposal-is-usv-string/blob/main/README.md#algorithm
2779
+ return !/\p{Surrogate}/u.test(input);
2780
+ }
2772
2781
  const dataToEsm = function dataToEsm(data, options = {}) {
2782
+ var _a, _b;
2773
2783
  const t = options.compact ? '' : 'indent' in options ? options.indent : '\t';
2774
2784
  const _ = options.compact ? '' : ' ';
2775
2785
  const n = options.compact ? '' : '\n';
@@ -2784,8 +2794,17 @@ const dataToEsm = function dataToEsm(data, options = {}) {
2784
2794
  const magic = _ || (/^[{[\-\/]/.test(code) ? '' : ' '); // eslint-disable-line no-useless-escape
2785
2795
  return `export default${magic}${code};`;
2786
2796
  }
2797
+ let maxUnderbarPrefixLength = 0;
2798
+ for (const key of Object.keys(data)) {
2799
+ const underbarPrefixLength = (_b = (_a = key.match(/^(_+)/)) === null || _a === void 0 ? void 0 : _a[0].length) !== null && _b !== void 0 ? _b : 0;
2800
+ if (underbarPrefixLength > maxUnderbarPrefixLength) {
2801
+ maxUnderbarPrefixLength = underbarPrefixLength;
2802
+ }
2803
+ }
2804
+ const arbitraryNamePrefix = `${'_'.repeat(maxUnderbarPrefixLength + 1)}arbitrary`;
2787
2805
  let namedExportCode = '';
2788
2806
  const defaultExportRows = [];
2807
+ const arbitraryNameExportRows = [];
2789
2808
  for (const [key, value] of Object.entries(data)) {
2790
2809
  if (key === makeLegalIdentifier(key)) {
2791
2810
  if (options.objectShorthand)
@@ -2796,9 +2815,18 @@ const dataToEsm = function dataToEsm(data, options = {}) {
2796
2815
  }
2797
2816
  else {
2798
2817
  defaultExportRows.push(`${stringify$8(key)}:${_}${serialize(value, options.compact ? null : t, '')}`);
2818
+ if (options.includeArbitraryNames && isWellFormedString(key)) {
2819
+ const variableName = `${arbitraryNamePrefix}${arbitraryNameExportRows.length}`;
2820
+ namedExportCode += `${declarationType} ${variableName}${_}=${_}${serialize(value, options.compact ? null : t, '')};${n}`;
2821
+ arbitraryNameExportRows.push(`${variableName} as ${JSON.stringify(key)}`);
2822
+ }
2799
2823
  }
2800
2824
  }
2801
- return `${namedExportCode}export default${_}{${n}${t}${defaultExportRows.join(`,${n}${t}`)}${n}};${n}`;
2825
+ const arbitraryExportCode = arbitraryNameExportRows.length > 0
2826
+ ? `export${_}{${n}${t}${arbitraryNameExportRows.join(`,${n}${t}`)}${n}};${n}`
2827
+ : '';
2828
+ const defaultExportCode = `export default${_}{${n}${t}${defaultExportRows.join(`,${n}${t}`)}${n}};${n}`;
2829
+ return `${namedExportCode}${arbitraryExportCode}${defaultExportCode}`;
2802
2830
  };
2803
2831
 
2804
2832
  var path$l = require$$0$4;
@@ -12069,7 +12097,7 @@ function normalizePath$3(id) {
12069
12097
  }
12070
12098
  function fsPathFromId(id) {
12071
12099
  const fsPath = normalizePath$3(id.startsWith(FS_PREFIX) ? id.slice(FS_PREFIX.length) : id);
12072
- return fsPath[0] === '/' || fsPath.match(VOLUME_RE) ? fsPath : `/${fsPath}`;
12100
+ return fsPath[0] === '/' || VOLUME_RE.test(fsPath) ? fsPath : `/${fsPath}`;
12073
12101
  }
12074
12102
  function fsPathFromUrl(url) {
12075
12103
  return fsPathFromId(cleanUrl(url));
@@ -12391,6 +12419,27 @@ function copyDir(srcDir, destDir) {
12391
12419
  }
12392
12420
  }
12393
12421
  }
12422
+ async function recursiveReaddir(dir) {
12423
+ if (!fs$l.existsSync(dir)) {
12424
+ return [];
12425
+ }
12426
+ let dirents;
12427
+ try {
12428
+ dirents = await fsp.readdir(dir, { withFileTypes: true });
12429
+ }
12430
+ catch (e) {
12431
+ if (e.code === 'EACCES') {
12432
+ // Ignore permission errors
12433
+ return [];
12434
+ }
12435
+ throw e;
12436
+ }
12437
+ const files = await Promise.all(dirents.map((dirent) => {
12438
+ const res = path$o.resolve(dir, dirent.name);
12439
+ return dirent.isDirectory() ? recursiveReaddir(res) : normalizePath$3(res);
12440
+ }));
12441
+ return files.flat(1);
12442
+ }
12394
12443
  // `fs.realpathSync.native` resolves differently in Windows network drive,
12395
12444
  // causing file read errors. skip for now.
12396
12445
  // https://github.com/nodejs/node/issues/37737
@@ -14611,7 +14660,7 @@ const buildEsbuildPlugin = (config) => {
14611
14660
  // the headers don't modify the sourcemap
14612
14661
  const esbuildCode = res.code;
14613
14662
  const contentIndex = opts.format === 'iife'
14614
- ? esbuildCode.match(IIFE_BEGIN_RE)?.index || 0
14663
+ ? Math.max(esbuildCode.search(IIFE_BEGIN_RE), 0)
14615
14664
  : opts.format === 'umd'
14616
14665
  ? esbuildCode.indexOf(`(function(`) // same for minified or not
14617
14666
  : 0;
@@ -16373,6 +16422,39 @@ function lookup(extn) {
16373
16422
  return mimes$1[!~idx ? tmp : tmp.substring(++idx)];
16374
16423
  }
16375
16424
 
16425
+ const publicFilesMap = new WeakMap();
16426
+ async function initPublicFiles(config) {
16427
+ const fileNames = await recursiveReaddir(config.publicDir);
16428
+ const publicFiles = new Set(fileNames.map((fileName) => fileName.slice(config.publicDir.length)));
16429
+ publicFilesMap.set(config, publicFiles);
16430
+ return publicFiles;
16431
+ }
16432
+ function getPublicFiles(config) {
16433
+ return publicFilesMap.get(config);
16434
+ }
16435
+ function checkPublicFile(url, config) {
16436
+ // note if the file is in /public, the resolver would have returned it
16437
+ // as-is so it's not going to be a fully resolved path.
16438
+ const { publicDir } = config;
16439
+ if (!publicDir || url[0] !== '/') {
16440
+ return;
16441
+ }
16442
+ const fileName = cleanUrl(url);
16443
+ // short-circuit if we have an in-memory publicFiles cache
16444
+ const publicFiles = getPublicFiles(config);
16445
+ if (publicFiles) {
16446
+ return publicFiles.has(fileName)
16447
+ ? normalizePath$3(path$o.join(publicDir, fileName))
16448
+ : undefined;
16449
+ }
16450
+ const publicFile = normalizePath$3(path$o.join(publicDir, fileName));
16451
+ if (!publicFile.startsWith(withTrailingSlash(normalizePath$3(publicDir)))) {
16452
+ // can happen if URL starts with '../'
16453
+ return;
16454
+ }
16455
+ return fs$l.existsSync(publicFile) ? publicFile : undefined;
16456
+ }
16457
+
16376
16458
  // referenceId is base64url but replaces - with $
16377
16459
  const assetUrlRE = /__VITE_ASSET__([\w$]+)__(?:\$_(.*?)__)?/g;
16378
16460
  const rawRE = /(?:\?|&)raw(?:&|$)/;
@@ -16522,24 +16604,6 @@ function assetPlugin(config) {
16522
16604
  },
16523
16605
  };
16524
16606
  }
16525
- function checkPublicFile(url, { publicDir }) {
16526
- // note if the file is in /public, the resolver would have returned it
16527
- // as-is so it's not going to be a fully resolved path.
16528
- if (!publicDir || url[0] !== '/') {
16529
- return;
16530
- }
16531
- const publicFile = path$o.join(publicDir, cleanUrl(url));
16532
- if (!normalizePath$3(publicFile).startsWith(withTrailingSlash(normalizePath$3(publicDir)))) {
16533
- // can happen if URL starts with '../'
16534
- return;
16535
- }
16536
- if (fs$l.existsSync(publicFile)) {
16537
- return publicFile;
16538
- }
16539
- else {
16540
- return;
16541
- }
16542
- }
16543
16607
  async function fileToUrl$1(id, config, ctx) {
16544
16608
  if (config.command === 'serve') {
16545
16609
  return fileToDevUrl(id, config);
@@ -17115,32 +17179,43 @@ const debug$g = createDebugger('vite:sourcemap', {
17115
17179
  // false positive "missing source" warning. We also check for certain
17116
17180
  // prefixes used for special handling in esbuildDepPlugin.
17117
17181
  const virtualSourceRE = /^(?:dep:|browser-external:|virtual:)|\0/;
17118
- async function injectSourcesContent(map, file, logger) {
17182
+ async function computeSourceRoute(map, file) {
17119
17183
  let sourceRoot;
17120
17184
  try {
17121
17185
  // The source root is undefined for virtual modules and permission errors.
17122
17186
  sourceRoot = await fsp.realpath(path$o.resolve(path$o.dirname(file), map.sourceRoot || ''));
17123
17187
  }
17124
17188
  catch { }
17189
+ return sourceRoot;
17190
+ }
17191
+ async function injectSourcesContent(map, file, logger) {
17192
+ let sourceRootPromise;
17125
17193
  const missingSources = [];
17126
17194
  const sourcesContent = map.sourcesContent || [];
17127
- await Promise.all(map.sources.map(async (sourcePath, index) => {
17128
- let content = null;
17129
- if (sourcePath && !virtualSourceRE.test(sourcePath)) {
17130
- sourcePath = decodeURI(sourcePath);
17131
- if (sourceRoot) {
17132
- sourcePath = path$o.resolve(sourceRoot, sourcePath);
17133
- }
17134
- // inject content from source file when sourcesContent is null
17135
- content =
17136
- sourcesContent[index] ??
17137
- (await fsp.readFile(sourcePath, 'utf-8').catch(() => {
17138
- missingSources.push(sourcePath);
17139
- return null;
17140
- }));
17195
+ const sourcesContentPromises = [];
17196
+ for (let index = 0; index < map.sources.length; index++) {
17197
+ const sourcePath = map.sources[index];
17198
+ if (!sourcesContent[index] &&
17199
+ sourcePath &&
17200
+ !virtualSourceRE.test(sourcePath)) {
17201
+ sourcesContentPromises.push((async () => {
17202
+ // inject content from source file when sourcesContent is null
17203
+ sourceRootPromise ??= computeSourceRoute(map, file);
17204
+ const sourceRoot = await sourceRootPromise;
17205
+ let resolvedSourcePath = decodeURI(sourcePath);
17206
+ if (sourceRoot) {
17207
+ resolvedSourcePath = path$o.resolve(sourceRoot, resolvedSourcePath);
17208
+ }
17209
+ sourcesContent[index] = await fsp
17210
+ .readFile(resolvedSourcePath, 'utf-8')
17211
+ .catch(() => {
17212
+ missingSources.push(resolvedSourcePath);
17213
+ return null;
17214
+ });
17215
+ })());
17141
17216
  }
17142
- sourcesContent[index] = content;
17143
- }));
17217
+ }
17218
+ await Promise.all(sourcesContentPromises);
17144
17219
  map.sourcesContent = sourcesContent;
17145
17220
  // Use this command…
17146
17221
  // DEBUG="vite:sourcemap" vite build
@@ -28496,7 +28571,7 @@ function resolvePlugin(resolveOptions) {
28496
28571
  // Optimized files could not yet exist in disk, resolve to the full path
28497
28572
  // Inject the current browserHash version if the path doesn't have one
28498
28573
  if (!resolveOptions.isBuild &&
28499
- !normalizedFsPath.match(DEP_VERSION_RE)) {
28574
+ !DEP_VERSION_RE.test(normalizedFsPath)) {
28500
28575
  const browserHash = optimizedDepInfoFromFile(depsOptimizer.metadata, normalizedFsPath)?.browserHash;
28501
28576
  if (browserHash) {
28502
28577
  return injectQuery(normalizedFsPath, `v=${browserHash}`);
@@ -28655,7 +28730,7 @@ function ensureVersionQuery(resolved, id, options, depsOptimizer) {
28655
28730
  // Use the original id to do the check as the resolved id may be the real
28656
28731
  // file path after symlinks resolution
28657
28732
  const isNodeModule = isInNodeModules$1(id) || isInNodeModules$1(resolved);
28658
- if (isNodeModule && !resolved.match(DEP_VERSION_RE)) {
28733
+ if (isNodeModule && !DEP_VERSION_RE.test(resolved)) {
28659
28734
  const versionHash = depsOptimizer.metadata.browserHash;
28660
28735
  if (versionHash && isOptimizable(resolved, depsOptimizer.options)) {
28661
28736
  resolved = injectQuery(resolved, `v=${versionHash}`);
@@ -37858,7 +37933,7 @@ function loadEnv(mode, envDir, prefixes = 'VITE_') {
37858
37933
  }
37859
37934
  function resolveEnvPrefix({ envPrefix = 'VITE_', }) {
37860
37935
  envPrefix = arraify(envPrefix);
37861
- if (envPrefix.some((prefix) => prefix === '')) {
37936
+ if (envPrefix.includes('')) {
37862
37937
  throw new Error(`envPrefix option contains value '', which could lead unexpected exposure of sensitive information.`);
37863
37938
  }
37864
37939
  return envPrefix;
@@ -37937,7 +38012,7 @@ function polyfill() {
37937
38012
  const htmlProxyRE$1 = /\?html-proxy=?(?:&inline-css)?(?:&style-attr)?&index=(\d+)\.(js|css)$/;
37938
38013
  const inlineCSSRE$1 = /__VITE_INLINE_CSS__([a-z\d]{8}_\d+)__/g;
37939
38014
  // Do not allow preceding '.', but do allow preceding '...' for spread operations
37940
- const inlineImportRE = /(?<!(?<!\.\.)\.)\bimport\s*\(("(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*')\)/g;
38015
+ const inlineImportRE = /(?<!(?<!\.\.)\.)\bimport\s*\(("(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*')\)/dg;
37941
38016
  const htmlLangRE = /\.(?:html|htm)$/;
37942
38017
  const importMapRE = /[ \t]*<script[^>]*type\s*=\s*(?:"importmap"|'importmap'|importmap)[^>]*>.*?<\/script>/is;
37943
38018
  const moduleScriptRE = /[ \t]*<script[^>]*type\s*=\s*(?:"module"|'module'|module)[^>]*>/i;
@@ -38559,10 +38634,9 @@ function extractImportExpressionFromClassicScript(scriptTextNode) {
38559
38634
  let match;
38560
38635
  inlineImportRE.lastIndex = 0;
38561
38636
  while ((match = inlineImportRE.exec(cleanCode))) {
38562
- const { 1: url, index } = match;
38563
- const startUrl = cleanCode.indexOf(url, index);
38564
- const start = startUrl + 1;
38565
- const end = start + url.length - 2;
38637
+ const [, [urlStart, urlEnd]] = match.indices;
38638
+ const start = urlStart + 1;
38639
+ const end = urlEnd - 1;
38566
38640
  scriptUrls.push({
38567
38641
  start: start + startOffset,
38568
38642
  end: end + startOffset,
@@ -38573,11 +38647,11 @@ function extractImportExpressionFromClassicScript(scriptTextNode) {
38573
38647
  }
38574
38648
  function preImportMapHook(config) {
38575
38649
  return (html, ctx) => {
38576
- const importMapIndex = html.match(importMapRE)?.index;
38577
- if (importMapIndex === undefined)
38650
+ const importMapIndex = html.search(importMapRE);
38651
+ if (importMapIndex < 0)
38578
38652
  return;
38579
- const importMapAppendIndex = html.match(importMapAppendRE)?.index;
38580
- if (importMapAppendIndex === undefined)
38653
+ const importMapAppendIndex = html.search(importMapAppendRE);
38654
+ if (importMapAppendIndex < 0)
38581
38655
  return;
38582
38656
  if (importMapAppendIndex < importMapIndex) {
38583
38657
  const relativeHtml = normalizePath$3(path$o.relative(config.root, ctx.filename));
@@ -39663,8 +39737,8 @@ function createCachedImport(imp) {
39663
39737
  return cached;
39664
39738
  };
39665
39739
  }
39666
- const importPostcssImport = createCachedImport(() => import('./dep-nbvvoiwS.js').then(function (n) { return n.i; }));
39667
- const importPostcssModules = createCachedImport(() => import('./dep-GiiHpyM6.js').then(function (n) { return n.i; }));
39740
+ const importPostcssImport = createCachedImport(() => import('./dep-I1uDMLJL.js').then(function (n) { return n.i; }));
39741
+ const importPostcssModules = createCachedImport(() => import('./dep-Sacttr-6.js').then(function (n) { return n.i; }));
39668
39742
  const importPostcss = createCachedImport(() => import('postcss'));
39669
39743
  /**
39670
39744
  * @experimental
@@ -39672,12 +39746,12 @@ const importPostcss = createCachedImport(() => import('postcss'));
39672
39746
  async function preprocessCSS(code, filename, config) {
39673
39747
  return await compileCSS(filename, code, config);
39674
39748
  }
39675
- const postcssReturnsVirtualFilesRE = /^<.+>$/;
39676
39749
  async function formatPostcssSourceMap(rawMap, file) {
39677
39750
  const inputFileDir = path$o.dirname(file);
39678
39751
  const sources = rawMap.sources.map((source) => {
39679
39752
  const cleanSource = cleanUrl(decodeURIComponent(source));
39680
- if (postcssReturnsVirtualFilesRE.test(cleanSource)) {
39753
+ // postcss virtual files
39754
+ if (cleanSource[0] === '<' && cleanSource[cleanSource.length - 1] === '>') {
39681
39755
  return `\0${cleanSource}`;
39682
39756
  }
39683
39757
  return normalizePath$3(path$o.resolve(inputFileDir, cleanSource));
@@ -39729,7 +39803,7 @@ async function resolvePostcssConfig(config) {
39729
39803
  else {
39730
39804
  const searchPath = typeof inlineOptions === 'string' ? inlineOptions : config.root;
39731
39805
  result = postcssrc({}, searchPath).catch((e) => {
39732
- if (!/No PostCSS Config found/.test(e.message)) {
39806
+ if (!e.message.includes('No PostCSS Config found')) {
39733
39807
  if (e instanceof Error) {
39734
39808
  const { name, message, stack } = e;
39735
39809
  e.name = 'Failed to load PostCSS config';
@@ -39943,6 +40017,8 @@ function resolveMinifyCssEsbuildOptions(options) {
39943
40017
  return { ...base, minify: true };
39944
40018
  }
39945
40019
  }
40020
+ const atImportRE = /@import(?:\s*(?:url\([^)]*\)|"(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*').*?|[^;]*);/g;
40021
+ const atCharsetRE = /@charset(?:\s*(?:"(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*').*?|[^;]*);/g;
39946
40022
  async function hoistAtRules(css) {
39947
40023
  const s = new MagicString(css);
39948
40024
  const cleanCss = emptyCssComments(css);
@@ -39951,7 +40027,7 @@ async function hoistAtRules(css) {
39951
40027
  // CSS @import can only appear at top of the file. We need to hoist all @import
39952
40028
  // to top when multiple files are concatenated.
39953
40029
  // match until semicolon that's not in quotes
39954
- const atImportRE = /@import(?:\s*(?:url\([^)]*\)|"(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*').*?|[^;]*);/g;
40030
+ atImportRE.lastIndex = 0;
39955
40031
  while ((match = atImportRE.exec(cleanCss))) {
39956
40032
  s.remove(match.index, match.index + match[0].length);
39957
40033
  // Use `appendLeft` instead of `prepend` to preserve original @import order
@@ -39959,7 +40035,7 @@ async function hoistAtRules(css) {
39959
40035
  }
39960
40036
  // #6333
39961
40037
  // CSS @charset must be the top-first in the file, hoist the first to top
39962
- const atCharsetRE = /@charset(?:\s*(?:"(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*').*?|[^;]*);/g;
40038
+ atCharsetRE.lastIndex = 0;
39963
40039
  let foundCharset = false;
39964
40040
  while ((match = atCharsetRE.exec(cleanCss))) {
39965
40041
  s.remove(match.index, match.index + match[0].length);
@@ -40470,8 +40546,8 @@ const convertTargets = (esbuildTarget) => {
40470
40546
  for (const entry of entriesWithoutES) {
40471
40547
  if (entry === 'esnext')
40472
40548
  continue;
40473
- const index = entry.match(versionRE)?.index;
40474
- if (index) {
40549
+ const index = entry.search(versionRE);
40550
+ if (index >= 0) {
40475
40551
  const browser = map[entry.slice(0, index)];
40476
40552
  if (browser === false)
40477
40553
  continue; // No mapping available
@@ -40893,16 +40969,24 @@ function jsonPlugin(options = {}, isBuild) {
40893
40969
  };
40894
40970
  }
40895
40971
  catch (e) {
40896
- const errorMessageList = /\d+/.exec(e.message);
40897
- const position = errorMessageList && parseInt(errorMessageList[0], 10);
40972
+ const position = extractJsonErrorPosition(e.message, json.length);
40898
40973
  const msg = position
40899
- ? `, invalid JSON syntax found at line ${position}`
40974
+ ? `, invalid JSON syntax found at position ${position}`
40900
40975
  : `.`;
40901
- this.error(`Failed to parse JSON file` + msg, e.idx);
40976
+ this.error(`Failed to parse JSON file` + msg, position);
40902
40977
  }
40903
40978
  },
40904
40979
  };
40905
40980
  }
40981
+ function extractJsonErrorPosition(errorMessage, inputLength) {
40982
+ if (errorMessage.startsWith('Unexpected end of JSON input')) {
40983
+ return inputLength - 1;
40984
+ }
40985
+ const errorMessageList = /at position (\d+)/.exec(errorMessage);
40986
+ return errorMessageList
40987
+ ? Math.max(parseInt(errorMessageList[1], 10) - 1, 0)
40988
+ : undefined;
40989
+ }
40906
40990
 
40907
40991
  const ERR_OPTIMIZE_DEPS_PROCESSING_ERROR = 'ERR_OPTIMIZE_DEPS_PROCESSING_ERROR';
40908
40992
  const ERR_OUTDATED_OPTIMIZED_DEP = 'ERR_OUTDATED_OPTIMIZED_DEP';
@@ -48590,7 +48674,7 @@ function sirv (dir, opts={}) {
48590
48674
  }
48591
48675
 
48592
48676
  const knownJavascriptExtensionRE = /\.[tj]sx?$/;
48593
- const sirvOptions = ({ getHeaders, shouldServe, }) => {
48677
+ const sirvOptions = ({ getHeaders, }) => {
48594
48678
  return {
48595
48679
  dev: true,
48596
48680
  etag: true,
@@ -48611,19 +48695,33 @@ const sirvOptions = ({ getHeaders, shouldServe, }) => {
48611
48695
  }
48612
48696
  }
48613
48697
  },
48614
- shouldServe,
48615
48698
  };
48616
48699
  };
48617
- function servePublicMiddleware(server) {
48700
+ function servePublicMiddleware(server, publicFiles) {
48618
48701
  const dir = server.config.publicDir;
48619
48702
  const serve = sirv(dir, sirvOptions({
48620
48703
  getHeaders: () => server.config.server.headers,
48621
- shouldServe: (filePath) => shouldServeFile(filePath, dir),
48622
48704
  }));
48705
+ const toFilePath = (url) => {
48706
+ let filePath = cleanUrl(url);
48707
+ if (filePath.indexOf('%') !== -1) {
48708
+ try {
48709
+ filePath = decodeURI(filePath);
48710
+ }
48711
+ catch (err) {
48712
+ /* malform uri */
48713
+ }
48714
+ }
48715
+ return normalizePath$3(filePath);
48716
+ };
48623
48717
  // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
48624
48718
  return function viteServePublicMiddleware(req, res, next) {
48625
- // skip import request and internal requests `/@fs/ /@vite-client` etc...
48626
- if (isImportRequest(req.url) || isInternalRequest(req.url)) {
48719
+ // To avoid the performance impact of `existsSync` on every request, we check against an
48720
+ // in-memory set of known public files. This set is updated on restarts.
48721
+ // also skip import request and internal requests `/@fs/ /@vite-client` etc...
48722
+ if (!publicFiles.has(toFilePath(req.url)) ||
48723
+ isImportRequest(req.url) ||
48724
+ isInternalRequest(req.url)) {
48627
48725
  return next();
48628
48726
  }
48629
48727
  serve(req, res, next);
@@ -51373,6 +51471,8 @@ function bindCLIShortcuts(server, opts) {
51373
51471
  if (loggedKeys.has(shortcut.key))
51374
51472
  continue;
51375
51473
  loggedKeys.add(shortcut.key);
51474
+ if (shortcut.action == null)
51475
+ continue;
51376
51476
  server.config.logger.info(colors$1.dim(' press ') +
51377
51477
  colors$1.bold(`${shortcut.key} + enter`) +
51378
51478
  colors$1.dim(` to ${shortcut.description}`));
@@ -51380,7 +51480,7 @@ function bindCLIShortcuts(server, opts) {
51380
51480
  return;
51381
51481
  }
51382
51482
  const shortcut = shortcuts.find((shortcut) => shortcut.key === input);
51383
- if (!shortcut)
51483
+ if (!shortcut || shortcut.action == null)
51384
51484
  return;
51385
51485
  actionRunning = true;
51386
51486
  await shortcut.action(server);
@@ -58682,7 +58782,6 @@ const processNodeUrl = (url, useSrcSetReplacer, config, htmlPath, originalUrl, s
58682
58782
  const devHtmlHook = async (html, { path: htmlPath, filename, server, originalUrl }) => {
58683
58783
  const { config, moduleGraph, watcher } = server;
58684
58784
  const base = config.base || '/';
58685
- htmlPath = decodeURI(htmlPath);
58686
58785
  let proxyModulePath;
58687
58786
  let proxyModuleUrl;
58688
58787
  const trailingSlash = htmlPath.endsWith('/');
@@ -58702,7 +58801,9 @@ const devHtmlHook = async (html, { path: htmlPath, filename, server, originalUrl
58702
58801
  }
58703
58802
  const s = new MagicString(html);
58704
58803
  let inlineModuleIndex = -1;
58705
- const proxyCacheUrl = cleanUrl(proxyModulePath).replace(normalizePath$3(config.root), '');
58804
+ // The key to the proxyHtml cache is decoded, as it will be compared
58805
+ // against decoded URLs by the HTML plugins.
58806
+ const proxyCacheUrl = decodeURI(cleanUrl(proxyModulePath).replace(normalizePath$3(config.root), ''));
58706
58807
  const styleUrl = [];
58707
58808
  const inlineStyles = [];
58708
58809
  const addInlineModule = (node, ext) => {
@@ -58873,7 +58974,13 @@ function preTransformRequest(server, url, base) {
58873
58974
  if (!server.config.server.preTransformRequests)
58874
58975
  return;
58875
58976
  // transform all url as non-ssr as html includes client-side assets only
58876
- url = unwrapId(stripBase(url, base));
58977
+ try {
58978
+ url = unwrapId(stripBase(decodeURI(url), base));
58979
+ }
58980
+ catch {
58981
+ // ignore
58982
+ return;
58983
+ }
58877
58984
  server.warmupRequest(url);
58878
58985
  }
58879
58986
 
@@ -59487,6 +59594,7 @@ function createServer(inlineConfig = {}) {
59487
59594
  }
59488
59595
  async function _createServer(inlineConfig = {}, options) {
59489
59596
  const config = await resolveConfig(inlineConfig, 'serve');
59597
+ const initPublicFilesPromise = initPublicFiles(config);
59490
59598
  const { root, server: serverConfig } = config;
59491
59599
  const httpsOptions = await resolveHttpsConfig(config.server.https);
59492
59600
  const { middlewareMode } = serverConfig;
@@ -59685,6 +59793,7 @@ async function _createServer(inlineConfig = {}, options) {
59685
59793
  process.stdin.on('end', exitProcess);
59686
59794
  }
59687
59795
  }
59796
+ const publicFiles = await initPublicFilesPromise;
59688
59797
  const onHMRUpdate = async (file, configOnly) => {
59689
59798
  if (serverConfig.hmr !== false) {
59690
59799
  try {
@@ -59701,6 +59810,9 @@ async function _createServer(inlineConfig = {}, options) {
59701
59810
  const onFileAddUnlink = async (file, isUnlink) => {
59702
59811
  file = normalizePath$3(file);
59703
59812
  await container.watchChange(file, { event: isUnlink ? 'delete' : 'create' });
59813
+ if (config.publicDir && file.startsWith(config.publicDir)) {
59814
+ publicFiles[isUnlink ? 'delete' : 'add'](file.slice(config.publicDir.length));
59815
+ }
59704
59816
  await handleFileAddUnlink(file, server, isUnlink);
59705
59817
  await onHMRUpdate(file, true);
59706
59818
  };
@@ -59772,7 +59884,7 @@ async function _createServer(inlineConfig = {}, options) {
59772
59884
  // this applies before the transform middleware so that these files are served
59773
59885
  // as-is without transforms.
59774
59886
  if (config.publicDir) {
59775
- middlewares.use(servePublicMiddleware(server));
59887
+ middlewares.use(servePublicMiddleware(server, publicFiles));
59776
59888
  }
59777
59889
  // main transform middleware
59778
59890
  middlewares.use(transformMiddleware(server));
@@ -60266,6 +60378,11 @@ function isNodeWithinCircularImports(node, nodeChain, currentChain = [node], tra
60266
60378
  // Node may import itself which is safe
60267
60379
  if (importer === node)
60268
60380
  continue;
60381
+ // a PostCSS plugin like Tailwind JIT may register
60382
+ // any file as a dependency to a CSS file.
60383
+ // But in that case, the actual dependency chain is separate.
60384
+ if (isCSSRequest(importer.url))
60385
+ continue;
60269
60386
  // Check circular imports
60270
60387
  const importerIndex = nodeChain.indexOf(importer);
60271
60388
  if (importerIndex > -1) {
@@ -60930,7 +61047,8 @@ function webWorkerPlugin(config) {
60930
61047
  : null,
60931
61048
  });
60932
61049
  };
60933
- if (code.match(workerAssetUrlRE)) {
61050
+ workerAssetUrlRE.lastIndex = 0;
61051
+ if (workerAssetUrlRE.test(code)) {
60934
61052
  const toRelativeRuntime = createToImportMetaURLBasedRelativeRuntime(outputOptions.format, config.isWorker);
60935
61053
  let match;
60936
61054
  s = new MagicString(code);
@@ -61088,9 +61206,8 @@ function importAnalysisPlugin(config) {
61088
61206
  return null;
61089
61207
  }
61090
61208
  const ssr = options?.ssr === true;
61091
- const prettyImporter = prettifyUrl(importer, root);
61092
61209
  if (canSkipImportAnalysis(importer)) {
61093
- debug$4?.(colors$1.dim(`[skipped] ${prettyImporter}`));
61210
+ debug$4?.(colors$1.dim(`[skipped] ${prettifyUrl(importer, root)}`));
61094
61211
  return null;
61095
61212
  }
61096
61213
  const start = performance.now();
@@ -61120,7 +61237,7 @@ function importAnalysisPlugin(config) {
61120
61237
  }
61121
61238
  if (!imports.length && !this._addedImports) {
61122
61239
  importerModule.isSelfAccepting = false;
61123
- debug$4?.(`${timeFrom(start)} ${colors$1.dim(`[no imports] ${prettyImporter}`)}`);
61240
+ debug$4?.(`${timeFrom(start)} ${colors$1.dim(`[no imports] ${prettifyUrl(importer, root)}`)}`);
61124
61241
  return source;
61125
61242
  }
61126
61243
  let hasHMR = false;
@@ -61202,7 +61319,7 @@ function importAnalysisPlugin(config) {
61202
61319
  // query can break 3rd party plugin's extension checks.
61203
61320
  if ((isRelative || isSelfImport) &&
61204
61321
  !hasImportInQueryParamsRE.test(url) &&
61205
- !url.match(DEP_VERSION_RE)) {
61322
+ !DEP_VERSION_RE.test(url)) {
61206
61323
  const versionMatch = importer.match(DEP_VERSION_RE);
61207
61324
  if (versionMatch) {
61208
61325
  url = injectQuery(url, versionMatch[1]);
@@ -61320,7 +61437,7 @@ function importAnalysisPlugin(config) {
61320
61437
  if (url !== specifier) {
61321
61438
  let rewriteDone = false;
61322
61439
  if (depsOptimizer?.isOptimizedDepFile(resolvedId) &&
61323
- !resolvedId.match(optimizedDepChunkRE$1)) {
61440
+ !optimizedDepChunkRE$1.test(resolvedId)) {
61324
61441
  // for optimized cjs deps, support named imports by rewriting named imports to const assignments.
61325
61442
  // internal optimized chunks don't need es interop and are excluded
61326
61443
  // The browserHash in resolvedId could be stale in which case there will be a full
@@ -61331,7 +61448,7 @@ function importAnalysisPlugin(config) {
61331
61448
  // Non-entry dynamic imports from dependencies will reach here as there isn't
61332
61449
  // optimize info for them, but they don't need es interop. If the request isn't
61333
61450
  // a dynamic import, then it is an internal Vite error
61334
- if (!file.match(optimizedDepDynamicRE$1)) {
61451
+ if (!optimizedDepDynamicRE$1.test(file)) {
61335
61452
  config.logger.error(colors$1.red(`Vite Error, ${url} optimized info should be defined`));
61336
61453
  }
61337
61454
  }
@@ -61427,7 +61544,7 @@ function importAnalysisPlugin(config) {
61427
61544
  ? `[accepts-exports]`
61428
61545
  : acceptedUrls.size
61429
61546
  ? `[accepts-deps]`
61430
- : `[detected api usage]`} ${prettyImporter}`);
61547
+ : `[detected api usage]`} ${prettifyUrl(importer, root)}`);
61431
61548
  // inject hot context
61432
61549
  str().prepend(`import { createHotContext as __vite__createHotContext } from "${clientPublicPath}";` +
61433
61550
  `import.meta.hot = __vite__createHotContext(${JSON.stringify(normalizeHmrUrl(importerModule.url))});`);
@@ -61477,7 +61594,7 @@ function importAnalysisPlugin(config) {
61477
61594
  handlePrunedModules(prunedImports, server);
61478
61595
  }
61479
61596
  }
61480
- debug$4?.(`${timeFrom(start)} ${colors$1.dim(`[${importedUrls.size} imports rewritten] ${prettyImporter}`)}`);
61597
+ debug$4?.(`${timeFrom(start)} ${colors$1.dim(`[${importedUrls.size} imports rewritten] ${prettifyUrl(importer, root)}`)}`);
61481
61598
  if (s) {
61482
61599
  return transformStableResult(s, importer, config);
61483
61600
  }
@@ -61997,20 +62114,17 @@ function workerImportMetaUrlPlugin(config) {
61997
62114
  const query = parseRequest(id);
61998
62115
  let s;
61999
62116
  const cleanString = stripLiteral(code);
62000
- const workerImportMetaUrlRE = /\bnew\s+(?:Worker|SharedWorker)\s*\(\s*(new\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*\))/g;
62117
+ const workerImportMetaUrlRE = /\bnew\s+(?:Worker|SharedWorker)\s*\(\s*(new\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*\))/dg;
62001
62118
  let match;
62002
62119
  while ((match = workerImportMetaUrlRE.exec(cleanString))) {
62003
- const { 0: allExp, 1: exp, 2: emptyUrl, index } = match;
62004
- const urlIndex = allExp.indexOf(exp) + index;
62005
- const urlStart = cleanString.indexOf(emptyUrl, index);
62006
- const urlEnd = urlStart + emptyUrl.length;
62120
+ const [[, endIndex], [expStart, expEnd], [urlStart, urlEnd]] = match.indices;
62007
62121
  const rawUrl = code.slice(urlStart, urlEnd);
62008
62122
  // potential dynamic template string
62009
62123
  if (rawUrl[0] === '`' && rawUrl.includes('${')) {
62010
- this.error(`\`new URL(url, import.meta.url)\` is not supported in dynamic template string.`, urlIndex);
62124
+ this.error(`\`new URL(url, import.meta.url)\` is not supported in dynamic template string.`, expStart);
62011
62125
  }
62012
62126
  s ||= new MagicString(code);
62013
- const workerType = getWorkerType(code, cleanString, index + allExp.length);
62127
+ const workerType = getWorkerType(code, cleanString, endIndex);
62014
62128
  const url = rawUrl.slice(1, -1);
62015
62129
  let file;
62016
62130
  if (url[0] === '.') {
@@ -62039,7 +62153,7 @@ function workerImportMetaUrlPlugin(config) {
62039
62153
  builtUrl = injectQuery(builtUrl, WORKER_FILE_ID);
62040
62154
  builtUrl = injectQuery(builtUrl, `type=${workerType}`);
62041
62155
  }
62042
- s.update(urlIndex, urlIndex + exp.length,
62156
+ s.update(expStart, expEnd,
62043
62157
  // add `'' +` to skip vite:asset-import-meta-url plugin
62044
62158
  `new URL('' + ${JSON.stringify(builtUrl)}, import.meta.url)`);
62045
62159
  }
@@ -62083,13 +62197,11 @@ function assetImportMetaUrlPlugin(config) {
62083
62197
  code.includes('new URL') &&
62084
62198
  code.includes(`import.meta.url`)) {
62085
62199
  let s;
62086
- const assetImportMetaUrlRE = /\bnew\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*(?:,\s*)?\)/g;
62200
+ const assetImportMetaUrlRE = /\bnew\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*(?:,\s*)?\)/dg;
62087
62201
  const cleanString = stripLiteral(code);
62088
62202
  let match;
62089
62203
  while ((match = assetImportMetaUrlRE.exec(cleanString))) {
62090
- const { 0: exp, 1: emptyUrl, index } = match;
62091
- const urlStart = cleanString.indexOf(emptyUrl, index);
62092
- const urlEnd = urlStart + emptyUrl.length;
62204
+ const [[startIndex, endIndex], [urlStart, urlEnd]] = match.indices;
62093
62205
  const rawUrl = code.slice(urlStart, urlEnd);
62094
62206
  if (!s)
62095
62207
  s = new MagicString(code);
@@ -62118,7 +62230,7 @@ function assetImportMetaUrlPlugin(config) {
62118
62230
  // A hack to allow 'as' & 'query' exist at the same time
62119
62231
  query: injectQuery(queryString, 'url'),
62120
62232
  };
62121
- s.update(index, index + exp.length, `new URL((import.meta.glob(${JSON.stringify(pattern)}, ${JSON.stringify(globOptions)}))[${pureUrl}], import.meta.url)`);
62233
+ s.update(startIndex, endIndex, `new URL((import.meta.glob(${JSON.stringify(pattern)}, ${JSON.stringify(globOptions)}))[${pureUrl}], import.meta.url)`);
62122
62234
  continue;
62123
62235
  }
62124
62236
  }
@@ -62159,11 +62271,11 @@ function assetImportMetaUrlPlugin(config) {
62159
62271
  }
62160
62272
  }
62161
62273
  if (!builtUrl) {
62162
- const rawExp = code.slice(index, index + exp.length);
62274
+ const rawExp = code.slice(startIndex, endIndex);
62163
62275
  config.logger.warnOnce(`\n${rawExp} doesn't exist at build time, it will remain unchanged to be resolved at runtime`);
62164
62276
  builtUrl = url;
62165
62277
  }
62166
- s.update(index, index + exp.length, `new URL(${JSON.stringify(builtUrl)}, import.meta.url)`);
62278
+ s.update(startIndex, endIndex, `new URL(${JSON.stringify(builtUrl)}, import.meta.url)`);
62167
62279
  }
62168
62280
  if (s) {
62169
62281
  return transformStableResult(s, id, config);
@@ -63433,9 +63545,10 @@ function esbuildScanPlugin(config, container, depImports, missing, entries) {
63433
63545
  '@vite/client',
63434
63546
  '@vite/env',
63435
63547
  ];
63548
+ const isUnlessEntry = (path) => !entries.includes(path);
63436
63549
  const externalUnlessEntry = ({ path }) => ({
63437
63550
  path,
63438
- external: !entries.includes(path),
63551
+ external: isUnlessEntry(path),
63439
63552
  });
63440
63553
  const doTransformGlobImport = async (contents, id, loader) => {
63441
63554
  let transpiledContents;
@@ -63640,19 +63753,32 @@ function esbuildScanPlugin(config, container, depImports, missing, entries) {
63640
63753
  // should be faster than doing it in the catch-all via js
63641
63754
  // they are done after the bare import resolve because a package name
63642
63755
  // may end with these extensions
63756
+ const setupExternalize = (filter, doExternalize) => {
63757
+ build.onResolve({ filter }, ({ path }) => {
63758
+ return {
63759
+ path,
63760
+ external: doExternalize(path),
63761
+ };
63762
+ });
63763
+ // onResolve is not called for glob imports.
63764
+ // we need to add that here as well until esbuild calls onResolve for glob imports.
63765
+ // https://github.com/evanw/esbuild/issues/3317
63766
+ build.onLoad({ filter, namespace: 'file' }, () => {
63767
+ const externalOnLoadResult = {
63768
+ loader: 'js',
63769
+ contents: 'export default {}',
63770
+ };
63771
+ return externalOnLoadResult;
63772
+ });
63773
+ };
63643
63774
  // css
63644
- build.onResolve({ filter: CSS_LANGS_RE }, externalUnlessEntry);
63775
+ setupExternalize(CSS_LANGS_RE, isUnlessEntry);
63645
63776
  // json & wasm
63646
- build.onResolve({ filter: /\.(json|json5|wasm)$/ }, externalUnlessEntry);
63777
+ setupExternalize(/\.(json|json5|wasm)$/, isUnlessEntry);
63647
63778
  // known asset types
63648
- build.onResolve({
63649
- filter: new RegExp(`\\.(${KNOWN_ASSET_TYPES.join('|')})$`),
63650
- }, externalUnlessEntry);
63779
+ setupExternalize(new RegExp(`\\.(${KNOWN_ASSET_TYPES.join('|')})$`), isUnlessEntry);
63651
63780
  // known vite query types: ?worker, ?raw
63652
- build.onResolve({ filter: SPECIAL_QUERY_RE }, ({ path }) => ({
63653
- path,
63654
- external: true,
63655
- }));
63781
+ setupExternalize(SPECIAL_QUERY_RE, () => true);
63656
63782
  // catch all -------------------------------------------------------------
63657
63783
  build.onResolve({
63658
63784
  filter: /.*/,
@@ -64775,7 +64901,7 @@ function runOptimizeDeps(resolvedConfig, depsInfo, ssr = resolvedConfig.command
64775
64901
  });
64776
64902
  }
64777
64903
  for (const o of Object.keys(meta.outputs)) {
64778
- if (!o.match(jsMapExtensionRE)) {
64904
+ if (!jsMapExtensionRE.test(o)) {
64779
64905
  const id = path$o
64780
64906
  .relative(processingCacheDirOutputPath, o)
64781
64907
  .replace(jsExtensionRE, '');
@@ -65343,7 +65469,7 @@ const isModernFlag = `__VITE_IS_MODERN__`;
65343
65469
  const preloadMethod = `__vitePreload`;
65344
65470
  const preloadMarker = `__VITE_PRELOAD__`;
65345
65471
  const preloadHelperId = '\0vite/preload-helper.js';
65346
- const preloadMarkerWithQuote = new RegExp(`['"]${preloadMarker}['"]`);
65472
+ const preloadMarkerWithQuote = new RegExp(`['"]${preloadMarker}['"]`, 'g');
65347
65473
  const dynamicImportPrefixRE = /import\s*\(/;
65348
65474
  // TODO: abstract
65349
65475
  const optimizedDepChunkRE = /\/chunk-[A-Z\d]{8}\.js/;
@@ -65353,11 +65479,9 @@ function toRelativePath(filename, importer) {
65353
65479
  return relPath[0] === '.' ? relPath : `./${relPath}`;
65354
65480
  }
65355
65481
  function indexOfMatchInSlice(str, reg, pos = 0) {
65356
- if (pos !== 0) {
65357
- str = str.slice(pos);
65358
- }
65359
- const matcher = str.match(reg);
65360
- return matcher?.index !== undefined ? matcher.index + pos : -1;
65482
+ reg.lastIndex = pos;
65483
+ const result = reg.exec(str);
65484
+ return result?.index ?? -1;
65361
65485
  }
65362
65486
  /**
65363
65487
  * Helper for preloading CSS and direct imports of async chunks in parallel to
@@ -65370,51 +65494,52 @@ function detectScriptRel() {
65370
65494
  : 'preload';
65371
65495
  }
65372
65496
  function preload(baseModule, deps, importerUrl) {
65497
+ let promise = Promise.resolve();
65373
65498
  // @ts-expect-error __VITE_IS_MODERN__ will be replaced with boolean later
65374
- if (!__VITE_IS_MODERN__ || !deps || deps.length === 0) {
65375
- return baseModule();
65376
- }
65377
- const links = document.getElementsByTagName('link');
65378
- return Promise.all(deps.map((dep) => {
65379
- // @ts-expect-error assetsURL is declared before preload.toString()
65380
- dep = assetsURL(dep, importerUrl);
65381
- if (dep in seen)
65382
- return;
65383
- seen[dep] = true;
65384
- const isCss = dep.endsWith('.css');
65385
- const cssSelector = isCss ? '[rel="stylesheet"]' : '';
65386
- const isBaseRelative = !!importerUrl;
65387
- // check if the file is already preloaded by SSR markup
65388
- if (isBaseRelative) {
65389
- // When isBaseRelative is true then we have `importerUrl` and `dep` is
65390
- // already converted to an absolute URL by the `assetsURL` function
65391
- for (let i = links.length - 1; i >= 0; i--) {
65392
- const link = links[i];
65393
- // The `links[i].href` is an absolute URL thanks to browser doing the work
65394
- // for us. See https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes:idl-domstring-5
65395
- if (link.href === dep && (!isCss || link.rel === 'stylesheet')) {
65396
- return;
65499
+ if (__VITE_IS_MODERN__ && deps && deps.length > 0) {
65500
+ const links = document.getElementsByTagName('link');
65501
+ promise = Promise.all(deps.map((dep) => {
65502
+ // @ts-expect-error assetsURL is declared before preload.toString()
65503
+ dep = assetsURL(dep, importerUrl);
65504
+ if (dep in seen)
65505
+ return;
65506
+ seen[dep] = true;
65507
+ const isCss = dep.endsWith('.css');
65508
+ const cssSelector = isCss ? '[rel="stylesheet"]' : '';
65509
+ const isBaseRelative = !!importerUrl;
65510
+ // check if the file is already preloaded by SSR markup
65511
+ if (isBaseRelative) {
65512
+ // When isBaseRelative is true then we have `importerUrl` and `dep` is
65513
+ // already converted to an absolute URL by the `assetsURL` function
65514
+ for (let i = links.length - 1; i >= 0; i--) {
65515
+ const link = links[i];
65516
+ // The `links[i].href` is an absolute URL thanks to browser doing the work
65517
+ // for us. See https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes:idl-domstring-5
65518
+ if (link.href === dep && (!isCss || link.rel === 'stylesheet')) {
65519
+ return;
65520
+ }
65397
65521
  }
65398
65522
  }
65399
- }
65400
- else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) {
65401
- return;
65402
- }
65403
- const link = document.createElement('link');
65404
- link.rel = isCss ? 'stylesheet' : scriptRel;
65405
- if (!isCss) {
65406
- link.as = 'script';
65407
- link.crossOrigin = '';
65408
- }
65409
- link.href = dep;
65410
- document.head.appendChild(link);
65411
- if (isCss) {
65412
- return new Promise((res, rej) => {
65413
- link.addEventListener('load', res);
65414
- link.addEventListener('error', () => rej(new Error(`Unable to preload CSS for ${dep}`)));
65415
- });
65416
- }
65417
- }))
65523
+ else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) {
65524
+ return;
65525
+ }
65526
+ const link = document.createElement('link');
65527
+ link.rel = isCss ? 'stylesheet' : scriptRel;
65528
+ if (!isCss) {
65529
+ link.as = 'script';
65530
+ link.crossOrigin = '';
65531
+ }
65532
+ link.href = dep;
65533
+ document.head.appendChild(link);
65534
+ if (isCss) {
65535
+ return new Promise((res, rej) => {
65536
+ link.addEventListener('load', res);
65537
+ link.addEventListener('error', () => rej(new Error(`Unable to preload CSS for ${dep}`)));
65538
+ });
65539
+ }
65540
+ }));
65541
+ }
65542
+ return promise
65418
65543
  .then(() => baseModule())
65419
65544
  .catch((err) => {
65420
65545
  const e = new Event('vite:preloadError', { cancelable: true });
@@ -65565,7 +65690,7 @@ function buildImportAnalysisPlugin(config) {
65565
65690
  const [url, resolvedId] = await normalizeUrl(specifier, start);
65566
65691
  if (url !== specifier) {
65567
65692
  if (depsOptimizer.isOptimizedDepFile(resolvedId) &&
65568
- !resolvedId.match(optimizedDepChunkRE)) {
65693
+ !optimizedDepChunkRE.test(resolvedId)) {
65569
65694
  const file = cleanUrl(resolvedId); // Remove ?v={hash}
65570
65695
  const needsInterop = await optimizedDepNeedsInterop(depsOptimizer.metadata, file, config, ssr);
65571
65696
  let rewriteDone = false;
@@ -65573,7 +65698,7 @@ function buildImportAnalysisPlugin(config) {
65573
65698
  // Non-entry dynamic imports from dependencies will reach here as there isn't
65574
65699
  // optimize info for them, but they don't need es interop. If the request isn't
65575
65700
  // a dynamic import, then it is an internal Vite error
65576
- if (!file.match(optimizedDepDynamicRE)) {
65701
+ if (!optimizedDepDynamicRE.test(file)) {
65577
65702
  config.logger.error(colors$1.red(`Vite Error, ${url} optimized info should be defined`));
65578
65703
  }
65579
65704
  }
@@ -66395,7 +66520,7 @@ function onRollupWarning(warning, warn, config) {
66395
66520
  const id = warning.id;
66396
66521
  const exporter = warning.exporter;
66397
66522
  // throw unless it's commonjs external...
66398
- if (!id || !/\?commonjs-external$/.test(id)) {
66523
+ if (!id || !id.endsWith('?commonjs-external')) {
66399
66524
  throw new Error(`[vite]: Rollup failed to resolve import "${exporter}" from "${id}".\n` +
66400
66525
  `This is most likely unintended because it can break your application at runtime.\n` +
66401
66526
  `If you do want to externalize this module explicitly add it to\n` +