vite 5.0.0-beta.15 → 5.0.0-beta.17

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.
@@ -20,11 +20,11 @@ import require$$1$1 from 'http';
20
20
  import require$$0$7 from 'stream';
21
21
  import require$$2 from 'os';
22
22
  import require$$2$1 from 'child_process';
23
+ 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, ASYNC_DISPOSE, DEFAULT_DEV_PORT, CLIENT_DIR, JS_TYPES_RE, VERSION as VERSION$1, DEFAULT_PREVIEW_PORT, DEFAULT_ASSETS_RE, DEFAULT_CONFIG_FILES } from '../constants.js';
23
24
  import os$4 from 'node:os';
24
25
  import { exec } from 'node:child_process';
25
26
  import { createHash as createHash$2 } from 'node:crypto';
26
27
  import { promises } from 'node:dns';
27
- 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';
28
28
  import require$$0$a from 'crypto';
29
29
  import { Buffer as Buffer$1 } from 'node:buffer';
30
30
  import require$$0$8, { createRequire as createRequire$2 } from 'module';
@@ -15712,15 +15712,17 @@ async function urlToBuiltUrl(url, importer, config, pluginContext) {
15712
15712
  // Inspired by https://github.com/iconify/iconify/blob/main/packages/utils/src/svg/url.ts
15713
15713
  function svgToDataURL(content) {
15714
15714
  const stringContent = content.toString();
15715
- // If the SVG contains some text, any transformation is unsafe, and given that double quotes would then
15715
+ // If the SVG contains some text or HTML, any transformation is unsafe, and given that double quotes would then
15716
15716
  // need to be escaped, the gain to use a data URI would be ridiculous if not negative
15717
- if (stringContent.includes('<text')) {
15717
+ if (stringContent.includes('<text') ||
15718
+ stringContent.includes('<foreignObject')) {
15718
15719
  return `data:image/svg+xml;base64,${content.toString('base64')}`;
15719
15720
  }
15720
15721
  else {
15721
15722
  return ('data:image/svg+xml,' +
15722
15723
  stringContent
15723
15724
  .trim()
15725
+ .replaceAll(/>\s+</g, '><')
15724
15726
  .replaceAll('"', "'")
15725
15727
  .replaceAll('%', '%25')
15726
15728
  .replaceAll('#', '%23')
@@ -36951,10 +36953,7 @@ function buildHtmlPlugin(config) {
36951
36953
  preHooks.push(htmlEnvHook(config));
36952
36954
  postHooks.push(postImportMapHook());
36953
36955
  const processedHtml = new Map();
36954
- const isExcludedUrl = (url) => url[0] === '#' ||
36955
- isExternalUrl(url) ||
36956
- isDataUrl(url) ||
36957
- checkPublicFile(url, config);
36956
+ const isExcludedUrl = (url) => url[0] === '#' || isExternalUrl(url) || isDataUrl(url);
36958
36957
  // Same reason with `htmlInlineProxyPlugin`
36959
36958
  isAsyncScriptMap.set(config, new Map());
36960
36959
  return {
@@ -36998,13 +36997,33 @@ function buildHtmlPlugin(config) {
36998
36997
  });
36999
36998
  let js = '';
37000
36999
  const s = new MagicString(html);
37001
- const assetUrls = [];
37002
37000
  const scriptUrls = [];
37003
37001
  const styleUrls = [];
37004
37002
  let inlineModuleIndex = -1;
37005
37003
  let everyScriptIsAsync = true;
37006
37004
  let someScriptsAreAsync = false;
37007
37005
  let someScriptsAreDefer = false;
37006
+ const assetUrlsPromises = [];
37007
+ // for each encountered asset url, rewrite original html so that it
37008
+ // references the post-build location, ignoring empty attributes and
37009
+ // attributes that directly reference named output.
37010
+ const namedOutput = Object.keys(config?.build?.rollupOptions?.input || {});
37011
+ const processAssetUrl = async (url) => {
37012
+ if (url !== '' && // Empty attribute
37013
+ !namedOutput.includes(url) && // Direct reference to named output
37014
+ !namedOutput.includes(removeLeadingSlash(url)) // Allow for absolute references as named output can't be an absolute path
37015
+ ) {
37016
+ try {
37017
+ return await urlToBuiltUrl(url, id, config, this);
37018
+ }
37019
+ catch (e) {
37020
+ if (e.code !== 'ENOENT') {
37021
+ throw e;
37022
+ }
37023
+ }
37024
+ }
37025
+ return url;
37026
+ };
37008
37027
  await traverseHtml(html, id, (node) => {
37009
37028
  if (!nodeIsElement(node)) {
37010
37029
  return;
@@ -37021,7 +37040,7 @@ function buildHtmlPlugin(config) {
37021
37040
  }
37022
37041
  if (isModule) {
37023
37042
  inlineModuleIndex++;
37024
- if (url && !isExcludedUrl(url)) {
37043
+ if (url && !isExcludedUrl(url) && !isPublicFile) {
37025
37044
  // <script type="module" src="..."/>
37026
37045
  // add it as an import
37027
37046
  js += `\nimport ${JSON.stringify(url)}`;
@@ -37059,34 +37078,51 @@ function buildHtmlPlugin(config) {
37059
37078
  for (const p of node.attrs) {
37060
37079
  const attrKey = getAttrKey(p);
37061
37080
  if (p.value && assetAttrs.includes(attrKey)) {
37062
- const attrSourceCodeLocation = node.sourceCodeLocation.attrs[attrKey];
37063
- // assetsUrl may be encodeURI
37064
- const url = decodeURI(p.value);
37065
- if (!isExcludedUrl(url)) {
37066
- if (node.nodeName === 'link' &&
37067
- isCSSRequest(url) &&
37068
- // should not be converted if following attributes are present (#6748)
37069
- !node.attrs.some((p) => p.prefix === undefined &&
37070
- (p.name === 'media' || p.name === 'disabled'))) {
37071
- // CSS references, convert to import
37072
- const importExpression = `\nimport ${JSON.stringify(url)}`;
37073
- styleUrls.push({
37074
- url,
37075
- start: nodeStartWithLeadingWhitespace(node),
37076
- end: node.sourceCodeLocation.endOffset,
37081
+ if (attrKey === 'srcset') {
37082
+ assetUrlsPromises.push((async () => {
37083
+ const processedUrl = await processSrcSet(p.value, async ({ url }) => {
37084
+ const decodedUrl = decodeURI(url);
37085
+ if (!isExcludedUrl(decodedUrl)) {
37086
+ const result = await processAssetUrl(url);
37087
+ return result !== decodedUrl ? result : url;
37088
+ }
37089
+ return url;
37077
37090
  });
37078
- js += importExpression;
37091
+ if (processedUrl !== p.value) {
37092
+ overwriteAttrValue(s, getAttrSourceCodeLocation(node, attrKey), processedUrl);
37093
+ }
37094
+ })());
37095
+ }
37096
+ else {
37097
+ const url = decodeURI(p.value);
37098
+ if (checkPublicFile(url, config)) {
37099
+ overwriteAttrValue(s, getAttrSourceCodeLocation(node, attrKey), toOutputPublicFilePath(url));
37079
37100
  }
37080
- else {
37081
- assetUrls.push({
37082
- attr: p,
37083
- sourceCodeLocation: attrSourceCodeLocation,
37084
- });
37101
+ else if (!isExcludedUrl(url)) {
37102
+ if (node.nodeName === 'link' &&
37103
+ isCSSRequest(url) &&
37104
+ // should not be converted if following attributes are present (#6748)
37105
+ !node.attrs.some((p) => p.prefix === undefined &&
37106
+ (p.name === 'media' || p.name === 'disabled'))) {
37107
+ // CSS references, convert to import
37108
+ const importExpression = `\nimport ${JSON.stringify(url)}`;
37109
+ styleUrls.push({
37110
+ url,
37111
+ start: nodeStartWithLeadingWhitespace(node),
37112
+ end: node.sourceCodeLocation.endOffset,
37113
+ });
37114
+ js += importExpression;
37115
+ }
37116
+ else {
37117
+ assetUrlsPromises.push((async () => {
37118
+ const processedUrl = await processAssetUrl(url);
37119
+ if (processedUrl !== url) {
37120
+ overwriteAttrValue(s, getAttrSourceCodeLocation(node, attrKey), processedUrl);
37121
+ }
37122
+ })());
37123
+ }
37085
37124
  }
37086
37125
  }
37087
- else if (checkPublicFile(url, config)) {
37088
- overwriteAttrValue(s, attrSourceCodeLocation, toOutputPublicFilePath(url));
37089
- }
37090
37126
  }
37091
37127
  }
37092
37128
  }
@@ -37127,38 +37163,15 @@ function buildHtmlPlugin(config) {
37127
37163
  if (someScriptsAreAsync && someScriptsAreDefer) {
37128
37164
  config.logger.warn(`\nMixed async and defer script modules in ${id}, output script will fallback to defer. Every script, including inline ones, need to be marked as async for your output script to be async.`);
37129
37165
  }
37130
- // for each encountered asset url, rewrite original html so that it
37131
- // references the post-build location, ignoring empty attributes and
37132
- // attributes that directly reference named output.
37133
- const namedOutput = Object.keys(config?.build?.rollupOptions?.input || {});
37134
- for (const { attr, sourceCodeLocation } of assetUrls) {
37135
- // assetsUrl may be encodeURI
37136
- const content = decodeURI(attr.value);
37137
- if (content !== '' && // Empty attribute
37138
- !namedOutput.includes(content) && // Direct reference to named output
37139
- !namedOutput.includes(removeLeadingSlash(content)) // Allow for absolute references as named output can't be an absolute path
37140
- ) {
37141
- try {
37142
- const url = attr.prefix === undefined && attr.name === 'srcset'
37143
- ? await processSrcSet(content, ({ url }) => urlToBuiltUrl(url, id, config, this))
37144
- : await urlToBuiltUrl(content, id, config, this);
37145
- overwriteAttrValue(s, sourceCodeLocation, url);
37146
- }
37147
- catch (e) {
37148
- if (e.code !== 'ENOENT') {
37149
- throw e;
37150
- }
37151
- }
37152
- }
37153
- }
37166
+ await Promise.all(assetUrlsPromises);
37154
37167
  // emit <script>import("./aaa")</script> asset
37155
37168
  for (const { start, end, url } of scriptUrls) {
37156
- if (!isExcludedUrl(url)) {
37157
- s.update(start, end, await urlToBuiltUrl(url, id, config, this));
37158
- }
37159
- else if (checkPublicFile(url, config)) {
37169
+ if (checkPublicFile(url, config)) {
37160
37170
  s.update(start, end, toOutputPublicFilePath(url));
37161
37171
  }
37172
+ else if (!isExcludedUrl(url)) {
37173
+ s.update(start, end, await urlToBuiltUrl(url, id, config, this));
37174
+ }
37162
37175
  }
37163
37176
  // ignore <link rel="stylesheet"> if its url can't be resolved
37164
37177
  const resolvedStyleUrls = await Promise.all(styleUrls.map(async (styleUrl) => ({
@@ -37669,20 +37682,22 @@ function incrementIndent(indent = '') {
37669
37682
  function getAttrKey(attr) {
37670
37683
  return attr.prefix === undefined ? attr.name : `${attr.prefix}:${attr.name}`;
37671
37684
  }
37685
+ function getAttrSourceCodeLocation(node, attrKey) {
37686
+ return node.sourceCodeLocation.attrs[attrKey];
37687
+ }
37672
37688
 
37673
37689
  function resolveCSSOptions(options) {
37674
- if (options?.lightningcss) {
37690
+ if (options?.transformer === 'lightningcss') {
37675
37691
  return {
37676
37692
  ...options,
37677
37693
  lightningcss: {
37678
37694
  ...options.lightningcss,
37679
- targets: options.lightningcss.targets ??
37695
+ targets: options.lightningcss?.targets ??
37680
37696
  convertTargets(ESBUILD_MODULES_TARGET),
37681
37697
  },
37682
37698
  };
37683
37699
  }
37684
- // TS doesn't narrow the type with the previous if :/
37685
- return options;
37700
+ return { ...options, lightningcss: undefined };
37686
37701
  }
37687
37702
  const cssModuleRE = new RegExp(`\\.module${CSS_LANGS_RE.source}`);
37688
37703
  const directRequestRE = /[?&]direct\b/;
@@ -38479,8 +38494,8 @@ function createCachedImport(imp) {
38479
38494
  return cached;
38480
38495
  };
38481
38496
  }
38482
- const importPostcssImport = createCachedImport(() => import('./dep-01ZZG1lv.js').then(function (n) { return n.i; }));
38483
- const importPostcssModules = createCachedImport(() => import('./dep-dhvB1mwU.js').then(function (n) { return n.i; }));
38497
+ const importPostcssImport = createCachedImport(() => import('./dep-zjm7Opl5.js').then(function (n) { return n.i; }));
38498
+ const importPostcssModules = createCachedImport(() => import('./dep-pKKs8JVV.js').then(function (n) { return n.i; }));
38484
38499
  const importPostcss = createCachedImport(() => import('postcss'));
38485
38500
  /**
38486
38501
  * @experimental
@@ -39187,7 +39202,9 @@ async function compileLightningCSS(id, src, config, urlReplacer) {
39187
39202
  },
39188
39203
  },
39189
39204
  minify: config.isProduction && !!config.build.cssMinify,
39190
- sourceMap: config.css?.devSourcemap,
39205
+ sourceMap: config.command === 'build'
39206
+ ? !!config.build.sourcemap
39207
+ : config.css?.devSourcemap,
39191
39208
  analyzeDependencies: true,
39192
39209
  cssModules: cssModuleRE.test(id)
39193
39210
  ? config.css?.lightningcss?.cssModules ?? true
@@ -39757,7 +39774,6 @@ function optimizedDepsPlugin(config) {
39757
39774
  // something unexpected has happened. In this case, Vite
39758
39775
  // returns an empty response that will error.
39759
39776
  throwProcessingError(id);
39760
- return;
39761
39777
  }
39762
39778
  const newMetadata = depsOptimizer.metadata;
39763
39779
  if (metadata !== newMetadata) {
@@ -47731,10 +47747,14 @@ async function loadAndTransform(id, url, server, options, timestamp, mod, resolv
47731
47747
  }
47732
47748
  if (code == null) {
47733
47749
  const isPublicFile = checkPublicFile(url, config);
47750
+ let publicDirName = path$o.relative(config.root, config.publicDir);
47751
+ if (publicDirName[0] !== '.')
47752
+ publicDirName = '/' + publicDirName;
47734
47753
  const msg = isPublicFile
47735
- ? `This file is in /public and will be copied as-is during build without ` +
47736
- `going through the plugin transforms, and therefore should not be ` +
47737
- `imported from source code. It can only be referenced via HTML tags.`
47754
+ ? `This file is in ${publicDirName} and will be copied as-is during ` +
47755
+ `build without going through the plugin transforms, and therefore ` +
47756
+ `should not be imported from source code. It can only be referenced ` +
47757
+ `via HTML tags.`
47738
47758
  : `Does the file exist?`;
47739
47759
  const importerMod = server.moduleGraph.idToModuleMap
47740
47760
  .get(id)
@@ -54910,31 +54930,33 @@ function createWebSocketServer(server, config, httpsOptions) {
54910
54930
  });
54911
54931
  });
54912
54932
  },
54933
+ [ASYNC_DISPOSE]() {
54934
+ return this.close();
54935
+ },
54913
54936
  };
54914
54937
  }
54915
54938
 
54916
54939
  // this middleware is only active when (base !== '/')
54917
- function baseMiddleware({ config, }) {
54940
+ function baseMiddleware(rawBase, middlewareMode) {
54918
54941
  // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
54919
54942
  return function viteBaseMiddleware(req, res, next) {
54920
54943
  const url = req.url;
54921
- const parsed = new URL(url, 'http://vitejs.dev');
54922
- const path = parsed.pathname || '/';
54923
- const base = config.rawBase;
54924
- if (path.startsWith(base)) {
54944
+ const pathname = cleanUrl(url);
54945
+ const base = rawBase;
54946
+ if (pathname.startsWith(base)) {
54925
54947
  // rewrite url to remove base. this ensures that other middleware does
54926
54948
  // not need to consider base being prepended or not
54927
54949
  req.url = stripBase(url, base);
54928
54950
  return next();
54929
54951
  }
54930
54952
  // skip redirect and error fallback on middleware mode, #4057
54931
- if (config.server.middlewareMode) {
54953
+ if (middlewareMode) {
54932
54954
  return next();
54933
54955
  }
54934
- if (path === '/' || path === '/index.html') {
54956
+ if (pathname === '/' || pathname === '/index.html') {
54935
54957
  // redirect root visit to based url with search and hash
54936
54958
  res.writeHead(302, {
54937
- Location: base + (parsed.search || '') + (parsed.hash || ''),
54959
+ Location: base + url.slice(pathname.length),
54938
54960
  });
54939
54961
  res.end();
54940
54962
  return;
@@ -57110,19 +57132,7 @@ function doesProxyContextMatchUrl(context, url) {
57110
57132
  }
57111
57133
 
57112
57134
  const debug$6 = createDebugger('vite:html-fallback');
57113
- function htmlFallbackMiddleware(root, spaFallback, mounted = false) {
57114
- // When this middleware is mounted on a route, we need to re-assign `req.url` with a
57115
- // leading `.` to signal a relative rewrite. Returning with a leading `/` returns a
57116
- // buggy `req.url`. e.g.:
57117
- //
57118
- // mount /foo/bar:
57119
- // req.url = /index.html
57120
- // final = /foo/barindex.html
57121
- //
57122
- // mount /foo/bar:
57123
- // req.url = ./index.html
57124
- // final = /foo/bar/index.html
57125
- const prepend = mounted ? '.' : '';
57135
+ function htmlFallbackMiddleware(root, spaFallback) {
57126
57136
  // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
57127
57137
  return function viteHtmlFallbackMiddleware(req, res, next) {
57128
57138
  if (
@@ -57146,7 +57156,7 @@ function htmlFallbackMiddleware(root, spaFallback, mounted = false) {
57146
57156
  const filePath = path$o.join(root, pathname);
57147
57157
  if (fs$l.existsSync(filePath)) {
57148
57158
  debug$6?.(`Rewriting ${req.method} ${req.url} to ${url}`);
57149
- req.url = prepend + url;
57159
+ req.url = url;
57150
57160
  return next();
57151
57161
  }
57152
57162
  }
@@ -57156,7 +57166,7 @@ function htmlFallbackMiddleware(root, spaFallback, mounted = false) {
57156
57166
  if (fs$l.existsSync(filePath)) {
57157
57167
  const newUrl = url + 'index.html';
57158
57168
  debug$6?.(`Rewriting ${req.method} ${req.url} to ${newUrl}`);
57159
- req.url = prepend + newUrl;
57169
+ req.url = newUrl;
57160
57170
  return next();
57161
57171
  }
57162
57172
  }
@@ -57166,13 +57176,13 @@ function htmlFallbackMiddleware(root, spaFallback, mounted = false) {
57166
57176
  if (fs$l.existsSync(filePath)) {
57167
57177
  const newUrl = url + '.html';
57168
57178
  debug$6?.(`Rewriting ${req.method} ${req.url} to ${newUrl}`);
57169
- req.url = prepend + newUrl;
57179
+ req.url = newUrl;
57170
57180
  return next();
57171
57181
  }
57172
57182
  }
57173
57183
  if (spaFallback) {
57174
57184
  debug$6?.(`Rewriting ${req.method} ${req.url} to /index.html`);
57175
- req.url = prepend + '/index.html';
57185
+ req.url = '/index.html';
57176
57186
  }
57177
57187
  next();
57178
57188
  };
@@ -57237,7 +57247,6 @@ function send(req, res, content, type, options) {
57237
57247
  const debugCache = createDebugger('vite:cache');
57238
57248
  const knownIgnoreList = new Set(['/', '/favicon.ico']);
57239
57249
  function transformMiddleware(server) {
57240
- const { config: { root, logger }, moduleGraph, } = server;
57241
57250
  // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
57242
57251
  return async function viteTransformMiddleware(req, res, next) {
57243
57252
  if (req.method !== 'GET' || knownIgnoreList.has(req.url)) {
@@ -57261,10 +57270,10 @@ function transformMiddleware(server) {
57261
57270
  // means that the dependency has already been pre-bundled and loaded
57262
57271
  const sourcemapPath = url.startsWith(FS_PREFIX)
57263
57272
  ? fsPathFromId(url)
57264
- : normalizePath$3(path$o.resolve(root, url.slice(1)));
57273
+ : normalizePath$3(path$o.resolve(server.config.root, url.slice(1)));
57265
57274
  try {
57266
57275
  const map = JSON.parse(await fsp.readFile(sourcemapPath, 'utf-8'));
57267
- applySourcemapIgnoreList(map, sourcemapPath, server.config.server.sourcemapIgnoreList, logger);
57276
+ applySourcemapIgnoreList(map, sourcemapPath, server.config.server.sourcemapIgnoreList, server.config.logger);
57268
57277
  return send(req, res, JSON.stringify(map), 'json', {
57269
57278
  headers: server.config.server.headers,
57270
57279
  });
@@ -57289,8 +57298,7 @@ function transformMiddleware(server) {
57289
57298
  }
57290
57299
  else {
57291
57300
  const originalUrl = url.replace(/\.map($|\?)/, '$1');
57292
- const map = (await moduleGraph.getModuleByUrl(originalUrl, false))
57293
- ?.transformResult?.map;
57301
+ const map = (await server.moduleGraph.getModuleByUrl(originalUrl, false))?.transformResult?.map;
57294
57302
  if (map) {
57295
57303
  return send(req, res, JSON.stringify(map), 'json', {
57296
57304
  headers: server.config.server.headers,
@@ -57328,7 +57336,7 @@ function transformMiddleware(server) {
57328
57336
  `Files in the public directory are served at the root path.\n` +
57329
57337
  `Instead of ${colors$1.cyan(url)}, use ${colors$1.cyan(url.replace(publicPath, '/'))}.`;
57330
57338
  }
57331
- logger.warn(colors$1.yellow(warning));
57339
+ server.config.logger.warn(colors$1.yellow(warning));
57332
57340
  }
57333
57341
  }
57334
57342
  if (isJSRequest(url) ||
@@ -57350,9 +57358,9 @@ function transformMiddleware(server) {
57350
57358
  // check if we can return 304 early
57351
57359
  const ifNoneMatch = req.headers['if-none-match'];
57352
57360
  if (ifNoneMatch &&
57353
- (await moduleGraph.getModuleByUrl(url, false))?.transformResult
57361
+ (await server.moduleGraph.getModuleByUrl(url, false))?.transformResult
57354
57362
  ?.etag === ifNoneMatch) {
57355
- debugCache?.(`[304] ${prettifyUrl(url, root)}`);
57363
+ debugCache?.(`[304] ${prettifyUrl(url, server.config.root)}`);
57356
57364
  res.statusCode = 304;
57357
57365
  return res.end();
57358
57366
  }
@@ -57383,7 +57391,7 @@ function transformMiddleware(server) {
57383
57391
  res.end();
57384
57392
  }
57385
57393
  // This timeout is unexpected
57386
- logger.error(e.message);
57394
+ server.config.logger.error(e.message);
57387
57395
  return;
57388
57396
  }
57389
57397
  if (e?.code === ERR_OUTDATED_OPTIMIZED_DEP) {
@@ -57426,13 +57434,13 @@ function transformMiddleware(server) {
57426
57434
  };
57427
57435
  }
57428
57436
 
57429
- function createDevHtmlTransformFn(server) {
57430
- const [preHooks, normalHooks, postHooks] = resolveHtmlTransforms(server.config.plugins, server.config.logger);
57431
- return (url, html, originalUrl) => {
57437
+ function createDevHtmlTransformFn(config) {
57438
+ const [preHooks, normalHooks, postHooks] = resolveHtmlTransforms(config.plugins, config.logger);
57439
+ return (server, url, html, originalUrl) => {
57432
57440
  return applyHtmlTransforms(html, [
57433
- preImportMapHook(server.config),
57441
+ preImportMapHook(config),
57434
57442
  ...preHooks,
57435
- htmlEnvHook(server.config),
57443
+ htmlEnvHook(config),
57436
57444
  devHtmlHook,
57437
57445
  ...normalHooks,
57438
57446
  ...postHooks,
@@ -57459,39 +57467,42 @@ function shouldPreTransform(url, config) {
57459
57467
  const wordCharRE = /\w/;
57460
57468
  const isSrcSet = (attr) => attr.name === 'srcset' && attr.prefix === undefined;
57461
57469
  const processNodeUrl = (url, useSrcSetReplacer, config, htmlPath, originalUrl, server) => {
57462
- if (server?.moduleGraph) {
57463
- const mod = server.moduleGraph.urlToModuleMap.get(url);
57464
- if (mod && mod.lastHMRTimestamp > 0) {
57465
- url = injectQuery(url, `t=${mod.lastHMRTimestamp}`);
57466
- }
57467
- }
57468
- if ((url[0] === '/' && url[1] !== '/') ||
57469
- // #3230 if some request url (localhost:3000/a/b) return to fallback html, the relative assets
57470
- // path will add `/a/` prefix, it will caused 404.
57471
- //
57472
- // skip if url contains `:` as it implies a url protocol or Windows path that we don't want to replace.
57473
- //
57474
- // rewrite `./index.js` -> `localhost:5173/a/index.js`.
57475
- // rewrite `../index.js` -> `localhost:5173/index.js`.
57476
- // rewrite `relative/index.js` -> `localhost:5173/a/relative/index.js`.
57477
- ((url[0] === '.' || (wordCharRE.test(url[0]) && !url.includes(':'))) &&
57478
- originalUrl &&
57479
- originalUrl !== '/' &&
57480
- htmlPath === '/index.html')) {
57481
- // prefix with base (dev only, base is never relative)
57482
- const replacer = (url) => {
57470
+ // prefix with base (dev only, base is never relative)
57471
+ const replacer = (url) => {
57472
+ if (server?.moduleGraph) {
57473
+ const mod = server.moduleGraph.urlToModuleMap.get(url);
57474
+ if (mod && mod.lastHMRTimestamp > 0) {
57475
+ url = injectQuery(url, `t=${mod.lastHMRTimestamp}`);
57476
+ }
57477
+ }
57478
+ if ((url[0] === '/' && url[1] !== '/') ||
57479
+ // #3230 if some request url (localhost:3000/a/b) return to fallback html, the relative assets
57480
+ // path will add `/a/` prefix, it will caused 404.
57481
+ //
57482
+ // skip if url contains `:` as it implies a url protocol or Windows path that we don't want to replace.
57483
+ //
57484
+ // rewrite `./index.js` -> `localhost:5173/a/index.js`.
57485
+ // rewrite `../index.js` -> `localhost:5173/index.js`.
57486
+ // rewrite `relative/index.js` -> `localhost:5173/a/relative/index.js`.
57487
+ ((url[0] === '.' || (wordCharRE.test(url[0]) && !url.includes(':'))) &&
57488
+ originalUrl &&
57489
+ originalUrl !== '/' &&
57490
+ htmlPath === '/index.html')) {
57483
57491
  const devBase = config.base;
57484
57492
  const fullUrl = path$o.posix.join(devBase, url);
57485
57493
  if (server && shouldPreTransform(url, config)) {
57486
57494
  preTransformRequest(server, fullUrl, devBase);
57487
57495
  }
57488
57496
  return fullUrl;
57489
- };
57490
- const processedUrl = useSrcSetReplacer
57491
- ? processSrcSetSync(url, ({ url }) => replacer(url))
57492
- : replacer(url);
57493
- return processedUrl;
57494
- }
57497
+ }
57498
+ else {
57499
+ return url;
57500
+ }
57501
+ };
57502
+ const processedUrl = useSrcSetReplacer
57503
+ ? processSrcSetSync(url, ({ url }) => replacer(url))
57504
+ : replacer(url);
57505
+ return processedUrl;
57495
57506
  };
57496
57507
  const devHtmlHook = async (html, { path: htmlPath, filename, server, originalUrl }) => {
57497
57508
  const { config, moduleGraph, watcher } = server;
@@ -57552,7 +57563,7 @@ const devHtmlHook = async (html, { path: htmlPath, filename, server, originalUrl
57552
57563
  const { src, sourceCodeLocation, isModule } = getScriptInfo(node);
57553
57564
  if (src) {
57554
57565
  const processedUrl = processNodeUrl(src.value, isSrcSet(src), config, htmlPath, originalUrl, server);
57555
- if (processedUrl) {
57566
+ if (processedUrl !== src.value) {
57556
57567
  overwriteAttrValue(s, sourceCodeLocation, processedUrl);
57557
57568
  }
57558
57569
  }
@@ -57563,7 +57574,7 @@ const devHtmlHook = async (html, { path: htmlPath, filename, server, originalUrl
57563
57574
  const scriptNode = node.childNodes[node.childNodes.length - 1];
57564
57575
  for (const { url, start, end, } of extractImportExpressionFromClassicScript(scriptNode)) {
57565
57576
  const processedUrl = processNodeUrl(url, false, config, htmlPath, originalUrl);
57566
- if (processedUrl) {
57577
+ if (processedUrl !== url) {
57567
57578
  s.update(start, end, processedUrl);
57568
57579
  }
57569
57580
  }
@@ -57593,7 +57604,7 @@ const devHtmlHook = async (html, { path: htmlPath, filename, server, originalUrl
57593
57604
  const attrKey = getAttrKey(p);
57594
57605
  if (p.value && assetAttrs.includes(attrKey)) {
57595
57606
  const processedUrl = processNodeUrl(p.value, isSrcSet(p), config, htmlPath, originalUrl);
57596
- if (processedUrl) {
57607
+ if (processedUrl !== p.value) {
57597
57608
  overwriteAttrValue(s, node.sourceCodeLocation.attrs[attrKey], processedUrl);
57598
57609
  }
57599
57610
  }
@@ -57814,7 +57825,11 @@ class ModuleGraph {
57814
57825
  });
57815
57826
  }
57816
57827
  }
57817
- invalidateModule(mod, seen = new Set(), timestamp = Date.now(), isHmr = false, hmrBoundaries = [], softInvalidate = false) {
57828
+ invalidateModule(mod, seen = new Set(), timestamp = Date.now(), isHmr = false,
57829
+ /** @internal */
57830
+ hmrBoundaries = [],
57831
+ /** @internal */
57832
+ softInvalidate = false) {
57818
57833
  const prevInvalidationState = mod.invalidationState;
57819
57834
  const prevSsrInvalidationState = mod.ssrInvalidationState;
57820
57835
  // Handle soft invalidation before the `seen` check, as consecutive soft/hard invalidations can
@@ -57885,7 +57900,9 @@ class ModuleGraph {
57885
57900
  * @param staticImportedUrls Subset of `importedModules` where they're statically imported in code.
57886
57901
  * This is only used for soft invalidations so `undefined` is fine but may cause more runtime processing.
57887
57902
  */
57888
- async updateModuleInfo(mod, importedModules, importedBindings, acceptedModules, acceptedExports, isSelfAccepting, ssr, staticImportedUrls) {
57903
+ async updateModuleInfo(mod, importedModules, importedBindings, acceptedModules, acceptedExports, isSelfAccepting, ssr,
57904
+ /** @internal */
57905
+ staticImportedUrls) {
57889
57906
  mod.isSelfAccepting = isSelfAccepting;
57890
57907
  const prevImports = ssr ? mod.ssrImportedModules : mod.clientImportedModules;
57891
57908
  let noLongerImported;
@@ -58331,7 +58348,8 @@ async function _createServer(inlineConfig = {}, options) {
58331
58348
  const container = await createPluginContainer(config, moduleGraph, watcher);
58332
58349
  const closeHttpServer = createServerCloseFn(httpServer);
58333
58350
  let exitProcess;
58334
- const server = {
58351
+ const devHtmlTransformFn = createDevHtmlTransformFn(config);
58352
+ let server = {
58335
58353
  config,
58336
58354
  middlewares,
58337
58355
  httpServer,
@@ -58360,7 +58378,9 @@ async function _createServer(inlineConfig = {}, options) {
58360
58378
  });
58361
58379
  });
58362
58380
  },
58363
- transformIndexHtml: null,
58381
+ transformIndexHtml(url, html, originalUrl) {
58382
+ return devHtmlTransformFn(server, url, html, originalUrl);
58383
+ },
58364
58384
  async ssrLoadModule(url, opts) {
58365
58385
  if (isDepsOptimizerEnabled(config, true)) {
58366
58386
  await initDevSsrDepsOptimizer(config, server);
@@ -58449,6 +58469,9 @@ async function _createServer(inlineConfig = {}, options) {
58449
58469
  }
58450
58470
  server.resolvedUrls = null;
58451
58471
  },
58472
+ [ASYNC_DISPOSE]() {
58473
+ return this.close();
58474
+ },
58452
58475
  printUrls() {
58453
58476
  if (server.resolvedUrls) {
58454
58477
  printServerUrls(server.resolvedUrls, serverConfig.host, config.logger.info);
@@ -58473,6 +58496,11 @@ async function _createServer(inlineConfig = {}, options) {
58473
58496
  }
58474
58497
  return server._restartPromise;
58475
58498
  },
58499
+ _setInternalServer(_server) {
58500
+ // Rebind internal the server variable so functions reference the user
58501
+ // server instance after a restart
58502
+ server = _server;
58503
+ },
58476
58504
  _restartPromise: null,
58477
58505
  _importGlobMap: new Map(),
58478
58506
  _forceOptimizeOnRestart: false,
@@ -58480,7 +58508,6 @@ async function _createServer(inlineConfig = {}, options) {
58480
58508
  _fsDenyGlob: picomatch$4(config.server.fs.deny, { matchBase: true }),
58481
58509
  _shortcutsOptions: undefined,
58482
58510
  };
58483
- server.transformIndexHtml = createDevHtmlTransformFn(server);
58484
58511
  if (!middlewareMode) {
58485
58512
  exitProcess = async () => {
58486
58513
  try {
@@ -58561,7 +58588,7 @@ async function _createServer(inlineConfig = {}, options) {
58561
58588
  }
58562
58589
  // base
58563
58590
  if (config.base !== '/') {
58564
- middlewares.use(baseMiddleware(server));
58591
+ middlewares.use(baseMiddleware(config.rawBase, middlewareMode));
58565
58592
  }
58566
58593
  // open in editor support
58567
58594
  middlewares.use('/__open-in-editor', launchEditorMiddleware$1());
@@ -58755,6 +58782,8 @@ async function restartServer(server) {
58755
58782
  await server.close();
58756
58783
  // Assign new server props to existing server instance
58757
58784
  Object.assign(server, newServer);
58785
+ // Rebind internal server variable so functions reference the user server
58786
+ newServer._setInternalServer(server);
58758
58787
  const { logger, server: { port, middlewareMode }, } = server.config;
58759
58788
  if (!middlewareMode) {
58760
58789
  await server.listen(port, true);
@@ -61306,14 +61335,7 @@ function createPluginHookUtils(plugins) {
61306
61335
  }
61307
61336
  function getSortedPluginHooks(hookName) {
61308
61337
  const plugins = getSortedPlugins(hookName);
61309
- return plugins
61310
- .map((p) => {
61311
- const hook = p[hookName];
61312
- return typeof hook === 'object' && 'handler' in hook
61313
- ? hook.handler
61314
- : hook;
61315
- })
61316
- .filter(Boolean);
61338
+ return plugins.map((p) => getHookHandler(p[hookName])).filter(Boolean);
61317
61339
  }
61318
61340
  return {
61319
61341
  getSortedPlugins,
@@ -61342,6 +61364,9 @@ function getSortedPluginsByHook(hookName, plugins) {
61342
61364
  }
61343
61365
  return [...pre, ...normal, ...post];
61344
61366
  }
61367
+ function getHookHandler(hook) {
61368
+ return (typeof hook === 'object' ? hook.handler : hook);
61369
+ }
61345
61370
 
61346
61371
  /**
61347
61372
  * This file is refactored into TypeScript based on
@@ -61421,9 +61446,7 @@ async function createPluginContainer(config, moduleGraph, watcher) {
61421
61446
  const hook = plugin[hookName];
61422
61447
  if (!hook)
61423
61448
  continue;
61424
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
61425
- // @ts-ignore hook is not a primitive
61426
- const handler = 'handler' in hook ? hook.handler : hook;
61449
+ const handler = getHookHandler(hook);
61427
61450
  if (hook.sequential) {
61428
61451
  await Promise.all(parallelPromises);
61429
61452
  parallelPromises.length = 0;
@@ -61781,9 +61804,7 @@ async function createPluginContainer(config, moduleGraph, watcher) {
61781
61804
  continue;
61782
61805
  ctx._activePlugin = plugin;
61783
61806
  const pluginResolveStart = debugPluginResolve ? performance.now() : 0;
61784
- const handler = 'handler' in plugin.resolveId
61785
- ? plugin.resolveId.handler
61786
- : plugin.resolveId;
61807
+ const handler = getHookHandler(plugin.resolveId);
61787
61808
  const result = await handleHookPromise(handler.call(ctx, rawId, importer, {
61788
61809
  attributes: options?.attributes ?? {},
61789
61810
  custom: options?.custom,
@@ -61830,7 +61851,7 @@ async function createPluginContainer(config, moduleGraph, watcher) {
61830
61851
  if (!plugin.load)
61831
61852
  continue;
61832
61853
  ctx._activePlugin = plugin;
61833
- const handler = 'handler' in plugin.load ? plugin.load.handler : plugin.load;
61854
+ const handler = getHookHandler(plugin.load);
61834
61855
  const result = await handleHookPromise(handler.call(ctx, id, { ssr }));
61835
61856
  if (result != null) {
61836
61857
  if (isObject$1(result)) {
@@ -61856,9 +61877,7 @@ async function createPluginContainer(config, moduleGraph, watcher) {
61856
61877
  ctx._activeCode = code;
61857
61878
  const start = debugPluginTransform ? performance.now() : 0;
61858
61879
  let result;
61859
- const handler = 'handler' in plugin.transform
61860
- ? plugin.transform.handler
61861
- : plugin.transform;
61880
+ const handler = getHookHandler(plugin.transform);
61862
61881
  try {
61863
61882
  result = await handleHookPromise(handler.call(ctx, code, id, { ssr }));
61864
61883
  }
@@ -61903,6 +61922,9 @@ async function createPluginContainer(config, moduleGraph, watcher) {
61903
61922
  await hookParallel('buildEnd', () => ctx, () => []);
61904
61923
  await hookParallel('closeBundle', () => ctx, () => []);
61905
61924
  },
61925
+ [ASYNC_DISPOSE]() {
61926
+ return this.close();
61927
+ },
61906
61928
  };
61907
61929
  return container;
61908
61930
  }
@@ -62616,6 +62638,9 @@ async function createDepsOptimizer(config, server) {
62616
62638
  resetRegisteredIds,
62617
62639
  ensureFirstRun,
62618
62640
  close,
62641
+ [ASYNC_DISPOSE]() {
62642
+ return this.close();
62643
+ },
62619
62644
  options: getDepOptimizationConfig(config, ssr),
62620
62645
  };
62621
62646
  depsOptimizerMap.set(config, depsOptimizer);
@@ -63150,6 +63175,7 @@ async function createDevSsrDepsOptimizer(config) {
63150
63175
  resetRegisteredIds: () => { },
63151
63176
  ensureFirstRun: () => { },
63152
63177
  close: async () => { },
63178
+ [ASYNC_DISPOSE]: async () => { },
63153
63179
  options: config.ssr.optimizeDeps,
63154
63180
  };
63155
63181
  devSsrDepsOptimizerMap.set(config, depsOptimizer);
@@ -65127,7 +65153,7 @@ function injectSsrFlagToHooks(plugin) {
65127
65153
  function wrapSsrResolveId(hook) {
65128
65154
  if (!hook)
65129
65155
  return;
65130
- const fn = 'handler' in hook ? hook.handler : hook;
65156
+ const fn = getHookHandler(hook);
65131
65157
  const handler = function (id, importer, options) {
65132
65158
  return fn.call(this, id, importer, injectSsrFlag(options));
65133
65159
  };
@@ -65144,7 +65170,7 @@ function wrapSsrResolveId(hook) {
65144
65170
  function wrapSsrLoad(hook) {
65145
65171
  if (!hook)
65146
65172
  return;
65147
- const fn = 'handler' in hook ? hook.handler : hook;
65173
+ const fn = getHookHandler(hook);
65148
65174
  const handler = function (id, ...args) {
65149
65175
  // @ts-expect-error: Receiving options param to be future-proof if Rollup adds it
65150
65176
  return fn.call(this, id, injectSsrFlag(args[0]));
@@ -65162,7 +65188,7 @@ function wrapSsrLoad(hook) {
65162
65188
  function wrapSsrTransform(hook) {
65163
65189
  if (!hook)
65164
65190
  return;
65165
- const fn = 'handler' in hook ? hook.handler : hook;
65191
+ const fn = getHookHandler(hook);
65166
65192
  const handler = function (code, importer, ...args) {
65167
65193
  // @ts-expect-error: Receiving options param to be future-proof if Rollup adds it
65168
65194
  return fn.call(this, code, importer, injectSsrFlag(args[0]));
@@ -65485,7 +65511,10 @@ async function preview(inlineConfig = {}) {
65485
65511
  app.use(proxyMiddleware(httpServer, proxy, config));
65486
65512
  }
65487
65513
  app.use(compression());
65488
- const previewBase = config.base === './' || config.base === '' ? '/' : config.base;
65514
+ // base
65515
+ if (config.base !== '/') {
65516
+ app.use(baseMiddleware(config.rawBase, false));
65517
+ }
65489
65518
  // static assets
65490
65519
  const headers = config.preview.headers;
65491
65520
  const viteAssetMiddleware = (...args) => sirv(distDir, {
@@ -65504,23 +65533,22 @@ async function preview(inlineConfig = {}) {
65504
65533
  return shouldServeFile(filePath, distDir);
65505
65534
  },
65506
65535
  })(...args);
65507
- app.use(previewBase, viteAssetMiddleware);
65536
+ app.use(viteAssetMiddleware);
65508
65537
  // html fallback
65509
65538
  if (config.appType === 'spa' || config.appType === 'mpa') {
65510
- app.use(previewBase, htmlFallbackMiddleware(distDir, config.appType === 'spa', previewBase !== '/'));
65539
+ app.use(htmlFallbackMiddleware(distDir, config.appType === 'spa'));
65511
65540
  }
65512
65541
  // apply post server hooks from plugins
65513
65542
  postHooks.forEach((fn) => fn && fn());
65514
65543
  if (config.appType === 'spa' || config.appType === 'mpa') {
65515
65544
  // transform index.html
65516
- app.use(previewBase, indexHtmlMiddleware(distDir, server));
65545
+ app.use(indexHtmlMiddleware(distDir, server));
65517
65546
  // handle 404s
65518
- app.use(previewBase, notFoundMiddleware());
65547
+ app.use(notFoundMiddleware());
65519
65548
  }
65520
65549
  const hostname = await resolveHostname(options.host);
65521
65550
  const port = options.port ?? DEFAULT_PREVIEW_PORT;
65522
- const protocol = options.https ? 'https' : 'http';
65523
- const serverPort = await httpServerStart(httpServer, {
65551
+ await httpServerStart(httpServer, {
65524
65552
  port,
65525
65553
  strictPort: options.strictPort,
65526
65554
  host: hostname.host,
@@ -65528,10 +65556,11 @@ async function preview(inlineConfig = {}) {
65528
65556
  });
65529
65557
  server.resolvedUrls = await resolveServerUrls(httpServer, config.preview, config);
65530
65558
  if (options.open) {
65531
- const path = typeof options.open === 'string' ? options.open : previewBase;
65532
- openBrowser(path.startsWith('http')
65533
- ? path
65534
- : new URL(path, `${protocol}://${hostname.name}:${serverPort}`).href, true, logger);
65559
+ const url = server.resolvedUrls?.local[0] ?? server.resolvedUrls?.network[0];
65560
+ if (url) {
65561
+ const path = typeof options.open === 'string' ? new URL(options.open, url).href : url;
65562
+ openBrowser(path, true, logger);
65563
+ }
65535
65564
  }
65536
65565
  return server;
65537
65566
  }
@@ -65565,7 +65594,7 @@ const promisifiedRealpath = promisify$4(fs$l.realpath);
65565
65594
  function defineConfig(config) {
65566
65595
  return config;
65567
65596
  }
65568
- async function resolveConfig(inlineConfig, command, defaultMode = 'development', defaultNodeEnv = 'development') {
65597
+ async function resolveConfig(inlineConfig, command, defaultMode = 'development', defaultNodeEnv = 'development', isPreview = false) {
65569
65598
  let config = inlineConfig;
65570
65599
  let configFileDependencies = [];
65571
65600
  let mode = inlineConfig.mode || defaultMode;
@@ -65579,7 +65608,8 @@ async function resolveConfig(inlineConfig, command, defaultMode = 'development',
65579
65608
  const configEnv = {
65580
65609
  mode,
65581
65610
  command,
65582
- ssrBuild: !!config.build?.ssr,
65611
+ isSsrBuild: !!config.build?.ssr,
65612
+ isPreview,
65583
65613
  };
65584
65614
  let { configFile } = config;
65585
65615
  if (configFile !== false) {
@@ -66157,7 +66187,7 @@ async function runConfigHook(config, plugins, configEnv) {
66157
66187
  let conf = config;
66158
66188
  for (const p of getSortedPluginsByHook('config', plugins)) {
66159
66189
  const hook = p.config;
66160
- const handler = hook && 'handler' in hook ? hook.handler : hook;
66190
+ const handler = getHookHandler(hook);
66161
66191
  if (handler) {
66162
66192
  const res = await handler(conf, configEnv);
66163
66193
  if (res) {