vite 6.0.0-beta.1 → 6.0.0-beta.10

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.
package/README.md CHANGED
@@ -11,10 +11,10 @@
11
11
 
12
12
  Vite (French word for "fast", pronounced `/vit/`) is a new breed of frontend build tool that significantly improves the frontend development experience. It consists of two major parts:
13
13
 
14
- - A dev server that serves your source files over [native ES modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules), with [rich built-in features](https://vitejs.dev/guide/features.html) and astonishingly fast [Hot Module Replacement (HMR)](https://vitejs.dev/guide/features.html#hot-module-replacement).
14
+ - A dev server that serves your source files over [native ES modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules), with [rich built-in features](https://vite.dev/guide/features.html) and astonishingly fast [Hot Module Replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement).
15
15
 
16
- - A [build command](https://vitejs.dev/guide/build.html) that bundles your code with [Rollup](https://rollupjs.org), pre-configured to output highly optimized static assets for production.
16
+ - A [build command](https://vite.dev/guide/build.html) that bundles your code with [Rollup](https://rollupjs.org), pre-configured to output highly optimized static assets for production.
17
17
 
18
- In addition, Vite is highly extensible via its [Plugin API](https://vitejs.dev/guide/api-plugin.html) and [JavaScript API](https://vitejs.dev/guide/api-javascript.html) with full typing support.
18
+ In addition, Vite is highly extensible via its [Plugin API](https://vite.dev/guide/api-plugin.html) and [JavaScript API](https://vite.dev/guide/api-javascript.html) with full typing support.
19
19
 
20
- [Read the Docs to Learn More](https://vitejs.dev).
20
+ [Read the Docs to Learn More](https://vite.dev).
package/bin/vite.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { performance } from 'node:perf_hooks'
3
+ import module from 'node:module'
3
4
 
4
5
  if (!import.meta.url.includes('node_modules')) {
5
6
  try {
@@ -41,6 +42,10 @@ if (debugIndex > 0) {
41
42
  }
42
43
 
43
44
  function start() {
45
+ try {
46
+ // eslint-disable-next-line n/no-unsupported-features/node-builtins -- it is supported in Node 22.8.0+ and only called if it exists
47
+ module.enableCompileCache?.()
48
+ } catch {}
44
49
  return import('../dist/node/cli.js')
45
50
  }
46
51
 
package/client.d.ts CHANGED
@@ -247,6 +247,16 @@ declare module '*?inline' {
247
247
  export default src
248
248
  }
249
249
 
250
+ declare module '*?no-inline' {
251
+ const src: string
252
+ export default src
253
+ }
254
+
255
+ declare module '*?url&inline' {
256
+ const src: string
257
+ export default src
258
+ }
259
+
250
260
  declare interface VitePreloadErrorEvent extends Event {
251
261
  payload: Error
252
262
  }
@@ -94,9 +94,7 @@ class HMRContext {
94
94
  removeFromMap(this.newListeners);
95
95
  }
96
96
  send(event, data) {
97
- this.hmrClient.messenger.send(
98
- JSON.stringify({ type: "custom", event, data })
99
- );
97
+ this.hmrClient.send({ type: "custom", event, data });
100
98
  }
101
99
  acceptDeps(deps, callback = () => {
102
100
  }) {
@@ -111,25 +109,10 @@ class HMRContext {
111
109
  this.hmrClient.hotModulesMap.set(this.ownerPath, mod);
112
110
  }
113
111
  }
114
- class HMRMessenger {
115
- constructor(connection) {
116
- this.connection = connection;
117
- this.queue = [];
118
- }
119
- send(message) {
120
- this.queue.push(message);
121
- this.flush();
122
- }
123
- flush() {
124
- if (this.connection.isReady()) {
125
- this.queue.forEach((msg) => this.connection.send(msg));
126
- this.queue = [];
127
- }
128
- }
129
- }
130
112
  class HMRClient {
131
- constructor(logger, connection, importUpdatedModule) {
113
+ constructor(logger, transport, importUpdatedModule) {
132
114
  this.logger = logger;
115
+ this.transport = transport;
133
116
  this.importUpdatedModule = importUpdatedModule;
134
117
  this.hotModulesMap = /* @__PURE__ */ new Map();
135
118
  this.disposeMap = /* @__PURE__ */ new Map();
@@ -139,7 +122,6 @@ class HMRClient {
139
122
  this.ctxToListenersMap = /* @__PURE__ */ new Map();
140
123
  this.updateQueue = [];
141
124
  this.pendingUpdateQueue = false;
142
- this.messenger = new HMRMessenger(connection);
143
125
  }
144
126
  async notifyListeners(event, data) {
145
127
  const cbs = this.customListenersMap.get(event);
@@ -147,6 +129,9 @@ class HMRClient {
147
129
  await Promise.allSettled(cbs.map((cb) => cb(data)));
148
130
  }
149
131
  }
132
+ send(payload) {
133
+ this.transport.send(payload);
134
+ }
150
135
  clear() {
151
136
  this.hotModulesMap.clear();
152
137
  this.disposeMap.clear();
@@ -157,7 +142,7 @@ class HMRClient {
157
142
  }
158
143
  // After an HMR update, some modules are no longer imported on the page
159
144
  // but they may have left behind side effects that need to be cleaned up
160
- // (.e.g style injections)
145
+ // (e.g. style injections)
161
146
  async prunePaths(paths) {
162
147
  await Promise.all(
163
148
  paths.map((path) => {
@@ -228,6 +213,255 @@ class HMRClient {
228
213
  }
229
214
  }
230
215
 
216
+ let urlAlphabet =
217
+ 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
218
+ let nanoid = (size = 21) => {
219
+ let id = '';
220
+ let i = size;
221
+ while (i--) {
222
+ id += urlAlphabet[(Math.random() * 64) | 0];
223
+ }
224
+ return id
225
+ };
226
+
227
+ typeof process !== "undefined" && process.platform === "win32";
228
+ function promiseWithResolvers() {
229
+ let resolve;
230
+ let reject;
231
+ const promise = new Promise((_resolve, _reject) => {
232
+ resolve = _resolve;
233
+ reject = _reject;
234
+ });
235
+ return { promise, resolve, reject };
236
+ }
237
+
238
+ function reviveInvokeError(e) {
239
+ return Object.assign(new Error(e.message || "Unknown invoke error"), e);
240
+ }
241
+ const createInvokeableTransport = (transport) => {
242
+ if (transport.invoke) {
243
+ return {
244
+ ...transport,
245
+ async invoke(name, data) {
246
+ const result = await transport.invoke({
247
+ type: "custom",
248
+ event: "vite:invoke",
249
+ data: {
250
+ id: "send",
251
+ name,
252
+ data
253
+ }
254
+ });
255
+ if ("e" in result) {
256
+ throw reviveInvokeError(result.e);
257
+ }
258
+ return result.r;
259
+ }
260
+ };
261
+ }
262
+ if (!transport.send || !transport.connect) {
263
+ throw new Error(
264
+ "transport must implement send and connect when invoke is not implemented"
265
+ );
266
+ }
267
+ const rpcPromises = /* @__PURE__ */ new Map();
268
+ return {
269
+ ...transport,
270
+ connect({ onMessage, onDisconnection }) {
271
+ return transport.connect({
272
+ onMessage(payload) {
273
+ if (payload.type === "custom" && payload.event === "vite:invoke") {
274
+ const data = payload.data;
275
+ if (data.id.startsWith("response:")) {
276
+ const invokeId = data.id.slice("response:".length);
277
+ const promise = rpcPromises.get(invokeId);
278
+ if (!promise) return;
279
+ if (promise.timeoutId) clearTimeout(promise.timeoutId);
280
+ rpcPromises.delete(invokeId);
281
+ const { e, r } = data.data;
282
+ if (e) {
283
+ promise.reject(reviveInvokeError(e));
284
+ } else {
285
+ promise.resolve(r);
286
+ }
287
+ return;
288
+ }
289
+ }
290
+ onMessage(payload);
291
+ },
292
+ onDisconnection
293
+ });
294
+ },
295
+ disconnect() {
296
+ rpcPromises.forEach((promise) => {
297
+ promise.reject(
298
+ new Error(
299
+ `transport was disconnected, cannot call ${JSON.stringify(promise.name)}`
300
+ )
301
+ );
302
+ });
303
+ rpcPromises.clear();
304
+ return transport.disconnect?.();
305
+ },
306
+ send(data) {
307
+ return transport.send(data);
308
+ },
309
+ async invoke(name, data) {
310
+ const promiseId = nanoid();
311
+ const wrappedData = {
312
+ type: "custom",
313
+ event: "vite:invoke",
314
+ data: {
315
+ name,
316
+ id: `send:${promiseId}`,
317
+ data
318
+ }
319
+ };
320
+ const sendPromise = transport.send(wrappedData);
321
+ const { promise, resolve, reject } = promiseWithResolvers();
322
+ const timeout = transport.timeout ?? 6e4;
323
+ let timeoutId;
324
+ if (timeout > 0) {
325
+ timeoutId = setTimeout(() => {
326
+ rpcPromises.delete(promiseId);
327
+ reject(
328
+ new Error(
329
+ `transport invoke timed out after ${timeout}ms (data: ${JSON.stringify(wrappedData)})`
330
+ )
331
+ );
332
+ }, timeout);
333
+ timeoutId?.unref?.();
334
+ }
335
+ rpcPromises.set(promiseId, { resolve, reject, name, timeoutId });
336
+ if (sendPromise) {
337
+ sendPromise.catch((err) => {
338
+ clearTimeout(timeoutId);
339
+ rpcPromises.delete(promiseId);
340
+ reject(err);
341
+ });
342
+ }
343
+ return await promise;
344
+ }
345
+ };
346
+ };
347
+ const normalizeModuleRunnerTransport = (transport) => {
348
+ const invokeableTransport = createInvokeableTransport(transport);
349
+ let isConnected = !invokeableTransport.connect;
350
+ let connectingPromise;
351
+ return {
352
+ ...transport,
353
+ ...invokeableTransport.connect ? {
354
+ async connect(onMessage) {
355
+ if (isConnected) return;
356
+ if (connectingPromise) {
357
+ await connectingPromise;
358
+ return;
359
+ }
360
+ const maybePromise = invokeableTransport.connect({
361
+ onMessage: onMessage ?? (() => {
362
+ }),
363
+ onDisconnection() {
364
+ isConnected = false;
365
+ }
366
+ });
367
+ if (maybePromise) {
368
+ connectingPromise = maybePromise;
369
+ await connectingPromise;
370
+ connectingPromise = void 0;
371
+ }
372
+ isConnected = true;
373
+ }
374
+ } : {},
375
+ ...invokeableTransport.disconnect ? {
376
+ async disconnect() {
377
+ if (!isConnected) return;
378
+ if (connectingPromise) {
379
+ await connectingPromise;
380
+ }
381
+ isConnected = false;
382
+ await invokeableTransport.disconnect();
383
+ }
384
+ } : {},
385
+ async send(data) {
386
+ if (!invokeableTransport.send) return;
387
+ if (!isConnected) {
388
+ if (connectingPromise) {
389
+ await connectingPromise;
390
+ } else {
391
+ throw new Error("send was called before connect");
392
+ }
393
+ }
394
+ await invokeableTransport.send(data);
395
+ },
396
+ async invoke(name, data) {
397
+ if (!isConnected) {
398
+ if (connectingPromise) {
399
+ await connectingPromise;
400
+ } else {
401
+ throw new Error("invoke was called before connect");
402
+ }
403
+ }
404
+ return invokeableTransport.invoke(name, data);
405
+ }
406
+ };
407
+ };
408
+ const createWebSocketModuleRunnerTransport = (options) => {
409
+ const pingInterval = options.pingInterval ?? 3e4;
410
+ let ws;
411
+ let pingIntervalId;
412
+ return {
413
+ async connect({ onMessage, onDisconnection }) {
414
+ const socket = options.createConnection();
415
+ socket.addEventListener("message", async ({ data }) => {
416
+ onMessage(JSON.parse(data));
417
+ });
418
+ let isOpened = socket.readyState === socket.OPEN;
419
+ if (!isOpened) {
420
+ await new Promise((resolve, reject) => {
421
+ socket.addEventListener(
422
+ "open",
423
+ () => {
424
+ isOpened = true;
425
+ resolve();
426
+ },
427
+ { once: true }
428
+ );
429
+ socket.addEventListener("close", async () => {
430
+ if (!isOpened) {
431
+ reject(new Error("WebSocket closed without opened."));
432
+ return;
433
+ }
434
+ onMessage({
435
+ type: "custom",
436
+ event: "vite:ws:disconnect",
437
+ data: { webSocket: socket }
438
+ });
439
+ onDisconnection();
440
+ });
441
+ });
442
+ }
443
+ onMessage({
444
+ type: "custom",
445
+ event: "vite:ws:connect",
446
+ data: { webSocket: socket }
447
+ });
448
+ ws = socket;
449
+ pingIntervalId = setInterval(() => {
450
+ if (socket.readyState === socket.OPEN) {
451
+ socket.send(JSON.stringify({ type: "ping" }));
452
+ }
453
+ }, pingInterval);
454
+ },
455
+ disconnect() {
456
+ clearInterval(pingIntervalId);
457
+ ws?.close();
458
+ },
459
+ send(data) {
460
+ ws.send(JSON.stringify(data));
461
+ }
462
+ };
463
+ };
464
+
231
465
  const hmrConfigName = __HMR_CONFIG_NAME__;
232
466
  const base$1 = __BASE__ || "/";
233
467
  function h(e, attrs = {}, ...children) {
@@ -503,68 +737,67 @@ const hmrPort = __HMR_PORT__;
503
737
  const socketHost = `${__HMR_HOSTNAME__ || importMetaUrl.hostname}:${hmrPort || importMetaUrl.port}${__HMR_BASE__}`;
504
738
  const directSocketHost = __HMR_DIRECT_TARGET__;
505
739
  const base = __BASE__ || "/";
506
- let socket;
507
- try {
508
- let fallback;
509
- if (!hmrPort) {
510
- fallback = () => {
511
- socket = setupWebSocket(socketProtocol, directSocketHost, () => {
512
- const currentScriptHostURL = new URL(import.meta.url);
513
- const currentScriptHost = currentScriptHostURL.host + currentScriptHostURL.pathname.replace(/@vite\/client$/, "");
514
- console.error(
515
- `[vite] failed to connect to websocket.
740
+ const hmrTimeout = __HMR_TIMEOUT__;
741
+ const transport = normalizeModuleRunnerTransport(
742
+ (() => {
743
+ let wsTransport = createWebSocketModuleRunnerTransport({
744
+ createConnection: () => new WebSocket(`${socketProtocol}://${socketHost}`, "vite-hmr"),
745
+ pingInterval: hmrTimeout
746
+ });
747
+ return {
748
+ async connect(handlers) {
749
+ try {
750
+ await wsTransport.connect(handlers);
751
+ } catch (e) {
752
+ if (!hmrPort) {
753
+ wsTransport = createWebSocketModuleRunnerTransport({
754
+ createConnection: () => new WebSocket(
755
+ `${socketProtocol}://${directSocketHost}`,
756
+ "vite-hmr"
757
+ ),
758
+ pingInterval: hmrTimeout
759
+ });
760
+ try {
761
+ await wsTransport.connect(handlers);
762
+ console.info(
763
+ "[vite] Direct websocket connection fallback. Check out https://vite.dev/config/server-options.html#server-hmr to remove the previous connection error."
764
+ );
765
+ } catch (e2) {
766
+ if (e2 instanceof Error && e2.message.includes("WebSocket closed without opened.")) {
767
+ const currentScriptHostURL = new URL(import.meta.url);
768
+ const currentScriptHost = currentScriptHostURL.host + currentScriptHostURL.pathname.replace(/@vite\/client$/, "");
769
+ console.error(
770
+ `[vite] failed to connect to websocket.
516
771
  your current setup:
517
772
  (browser) ${currentScriptHost} <--[HTTP]--> ${serverHost} (server)
518
773
  (browser) ${socketHost} <--[WebSocket (failing)]--> ${directSocketHost} (server)
519
- Check out your Vite / network configuration and https://vitejs.dev/config/server-options.html#server-hmr .`
520
- );
521
- });
522
- socket.addEventListener(
523
- "open",
524
- () => {
525
- console.info(
526
- "[vite] Direct websocket connection fallback. Check out https://vitejs.dev/config/server-options.html#server-hmr to remove the previous connection error."
527
- );
528
- },
529
- { once: true }
530
- );
774
+ Check out your Vite / network configuration and https://vite.dev/config/server-options.html#server-hmr .`
775
+ );
776
+ }
777
+ }
778
+ return;
779
+ }
780
+ console.error(`[vite] failed to connect to websocket (${e}). `);
781
+ throw e;
782
+ }
783
+ },
784
+ async disconnect() {
785
+ await wsTransport.disconnect();
786
+ },
787
+ send(data) {
788
+ wsTransport.send(data);
789
+ }
531
790
  };
532
- }
533
- socket = setupWebSocket(socketProtocol, socketHost, fallback);
534
- } catch (error) {
535
- console.error(`[vite] failed to connect to websocket (${error}). `);
536
- }
537
- function setupWebSocket(protocol, hostAndPath, onCloseWithoutOpen) {
538
- const socket2 = new WebSocket(`${protocol}://${hostAndPath}`, "vite-hmr");
539
- let isOpened = false;
540
- socket2.addEventListener(
541
- "open",
542
- () => {
543
- isOpened = true;
544
- notifyListeners("vite:ws:connect", { webSocket: socket2 });
545
- },
546
- { once: true }
547
- );
548
- socket2.addEventListener("message", async ({ data }) => {
549
- handleMessage(JSON.parse(data));
550
- });
551
- socket2.addEventListener("close", async ({ wasClean }) => {
552
- if (wasClean) return;
553
- if (!isOpened && onCloseWithoutOpen) {
554
- onCloseWithoutOpen();
555
- return;
556
- }
557
- notifyListeners("vite:ws:disconnect", { webSocket: socket2 });
558
- if (hasDocument) {
559
- console.log(`[vite] server connection lost. Polling for restart...`);
560
- await waitForSuccessfulPing(protocol, hostAndPath);
561
- location.reload();
562
- }
791
+ })()
792
+ );
793
+ let willUnload = false;
794
+ if (typeof window !== "undefined") {
795
+ window.addEventListener("beforeunload", () => {
796
+ willUnload = true;
563
797
  });
564
- return socket2;
565
798
  }
566
799
  function cleanUrl(pathname) {
567
- const url = new URL(pathname, "http://vitejs.dev");
800
+ const url = new URL(pathname, "http://vite.dev");
568
801
  url.searchParams.delete("direct");
569
802
  return url.pathname + url.search;
570
803
  }
@@ -588,10 +821,7 @@ const hmrClient = new HMRClient(
588
821
  error: (err) => console.error("[vite]", err),
589
822
  debug: (...msg) => console.debug("[vite]", ...msg)
590
823
  },
591
- {
592
- isReady: () => socket && socket.readyState === 1,
593
- send: (message) => socket.send(message)
594
- },
824
+ transport,
595
825
  async function importUpdatedModule({
596
826
  acceptedPath,
597
827
  timestamp,
@@ -614,16 +844,11 @@ const hmrClient = new HMRClient(
614
844
  return await importPromise;
615
845
  }
616
846
  );
847
+ transport.connect(handleMessage);
617
848
  async function handleMessage(payload) {
618
849
  switch (payload.type) {
619
850
  case "connected":
620
851
  console.debug(`[vite] connected.`);
621
- hmrClient.messenger.flush();
622
- setInterval(() => {
623
- if (socket.readyState === socket.OPEN) {
624
- socket.send('{"type":"ping"}');
625
- }
626
- }, __HMR_TIMEOUT__);
627
852
  break;
628
853
  case "update":
629
854
  notifyListeners("vite:beforeUpdate", payload);
@@ -673,6 +898,14 @@ async function handleMessage(payload) {
673
898
  break;
674
899
  case "custom": {
675
900
  notifyListeners(payload.event, payload.data);
901
+ if (payload.event === "vite:ws:disconnect") {
902
+ if (hasDocument && !willUnload) {
903
+ console.log(`[vite] server connection lost. Polling for restart...`);
904
+ const socket = payload.data.webSocket;
905
+ await waitForSuccessfulPing(socket.url);
906
+ location.reload();
907
+ }
908
+ }
676
909
  break;
677
910
  }
678
911
  case "full-reload":
@@ -710,6 +943,8 @@ ${err.stack}`
710
943
  }
711
944
  break;
712
945
  }
946
+ case "ping":
947
+ break;
713
948
  default: {
714
949
  const check = payload;
715
950
  return check;
@@ -731,23 +966,27 @@ function clearErrorOverlay() {
731
966
  function hasErrorOverlay() {
732
967
  return document.querySelectorAll(overlayId).length;
733
968
  }
734
- async function waitForSuccessfulPing(socketProtocol2, hostAndPath, ms = 1e3) {
735
- const pingHostProtocol = socketProtocol2 === "wss" ? "https" : "http";
736
- const ping = async () => {
737
- try {
738
- await fetch(`${pingHostProtocol}://${hostAndPath}`, {
739
- mode: "no-cors",
740
- headers: {
741
- // Custom headers won't be included in a request with no-cors so (ab)use one of the
742
- // safelisted headers to identify the ping request
743
- Accept: "text/x-vite-ping"
744
- }
745
- });
746
- return true;
747
- } catch {
748
- }
749
- return false;
750
- };
969
+ async function waitForSuccessfulPing(socketUrl, ms = 1e3) {
970
+ async function ping() {
971
+ const socket = new WebSocket(socketUrl, "vite-ping");
972
+ return new Promise((resolve) => {
973
+ function onOpen() {
974
+ resolve(true);
975
+ close();
976
+ }
977
+ function onError() {
978
+ resolve(false);
979
+ close();
980
+ }
981
+ function close() {
982
+ socket.removeEventListener("open", onOpen);
983
+ socket.removeEventListener("error", onError);
984
+ socket.close();
985
+ }
986
+ socket.addEventListener("open", onOpen);
987
+ socket.addEventListener("error", onError);
988
+ });
989
+ }
751
990
  if (await ping()) {
752
991
  return;
753
992
  }
@@ -824,7 +1063,7 @@ function injectQuery(url, queryToInject) {
824
1063
  return url;
825
1064
  }
826
1065
  const pathname = url.replace(/[?#].*$/, "");
827
- const { search, hash } = new URL(url, "http://vitejs.dev");
1066
+ const { search, hash } = new URL(url, "http://vite.dev");
828
1067
  return `${pathname}?${queryToInject}${search ? `&` + search.slice(1) : ""}${hash || ""}`;
829
1068
  }
830
1069
 
@@ -1,11 +1,3 @@
1
- import { fileURLToPath as __cjs_fileURLToPath } from 'node:url';
2
- import { dirname as __cjs_dirname } from 'node:path';
3
- import { createRequire as __cjs_createRequire } from 'node:module';
4
-
5
- const __filename = __cjs_fileURLToPath(import.meta.url);
6
- const __dirname = __cjs_dirname(__filename);
7
- const require = __cjs_createRequire(import.meta.url);
8
- const __require = require;
9
1
  var openParentheses = "(".charCodeAt(0);
10
2
  var closeParentheses = ")".charCodeAt(0);
11
3
  var singleQuote = "'".charCodeAt(0);