vite 2.8.6 → 2.9.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.

Potentially problematic release.


This version of vite might be problematic. Click here for more details.

@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var build = require('./chunks/dep-9c153816.js');
5
+ var index = require('./chunks/dep-7a52803b.js');
6
6
  require('fs');
7
7
  require('path');
8
8
  require('tty');
@@ -21,31 +21,137 @@ require('zlib');
21
21
  require('crypto');
22
22
  require('tls');
23
23
  require('assert');
24
+ require('esbuild');
24
25
  require('buffer');
25
26
  require('querystring');
26
- require('esbuild');
27
27
  require('child_process');
28
28
  require('worker_threads');
29
29
  require('readline');
30
30
 
31
+ // Use splitVendorChunkPlugin() to get the same manualChunks strategy as Vite 2.7
32
+ // We don't recommend using this strategy as a general solution moving forward
33
+ // splitVendorChunk is a simple index/vendor strategy that was used in Vite
34
+ // until v2.8. It is exposed to let people continue to use it in case it was
35
+ // working well for their setups.
36
+ // The cache needs to be reset on buildStart for watch mode to work correctly
37
+ // Don't use this manualChunks strategy for ssr, lib mode, and 'umd' or 'iife'
38
+ class SplitVendorChunkCache {
39
+ constructor() {
40
+ this.cache = new Map();
41
+ }
42
+ reset() {
43
+ this.cache = new Map();
44
+ }
45
+ }
46
+ function splitVendorChunk(options = {}) {
47
+ var _a;
48
+ const cache = (_a = options.cache) !== null && _a !== void 0 ? _a : new SplitVendorChunkCache();
49
+ return (id, { getModuleInfo }) => {
50
+ if (id.includes('node_modules') &&
51
+ !index.isCSSRequest(id) &&
52
+ staticImportedByEntry(id, getModuleInfo, cache.cache)) {
53
+ return 'vendor';
54
+ }
55
+ };
56
+ }
57
+ function staticImportedByEntry(id, getModuleInfo, cache, importStack = []) {
58
+ if (cache.has(id)) {
59
+ return cache.get(id);
60
+ }
61
+ if (importStack.includes(id)) {
62
+ // circular deps!
63
+ cache.set(id, false);
64
+ return false;
65
+ }
66
+ const mod = getModuleInfo(id);
67
+ if (!mod) {
68
+ cache.set(id, false);
69
+ return false;
70
+ }
71
+ if (mod.isEntry) {
72
+ cache.set(id, true);
73
+ return true;
74
+ }
75
+ const someImporterIs = mod.importers.some((importer) => staticImportedByEntry(importer, getModuleInfo, cache, importStack.concat(id)));
76
+ cache.set(id, someImporterIs);
77
+ return someImporterIs;
78
+ }
79
+ function splitVendorChunkPlugin() {
80
+ const caches = [];
81
+ function createSplitVendorChunk(output, config) {
82
+ var _a;
83
+ const cache = new SplitVendorChunkCache();
84
+ caches.push(cache);
85
+ const build = (_a = config.build) !== null && _a !== void 0 ? _a : {};
86
+ const format = output === null || output === void 0 ? void 0 : output.format;
87
+ if (!build.ssr && !build.lib && format !== 'umd' && format !== 'iife') {
88
+ return splitVendorChunk({ cache });
89
+ }
90
+ }
91
+ return {
92
+ name: 'vite:split-vendor-chunk',
93
+ config(config) {
94
+ var _a, _b;
95
+ let outputs = (_b = (_a = config === null || config === void 0 ? void 0 : config.build) === null || _a === void 0 ? void 0 : _a.rollupOptions) === null || _b === void 0 ? void 0 : _b.output;
96
+ if (outputs) {
97
+ outputs = Array.isArray(outputs) ? outputs : [outputs];
98
+ for (const output of outputs) {
99
+ const viteManualChunks = createSplitVendorChunk(output, config);
100
+ if (viteManualChunks) {
101
+ if (output.manualChunks) {
102
+ if (typeof output.manualChunks === 'function') {
103
+ const userManualChunks = output.manualChunks;
104
+ output.manualChunks = (id, api) => {
105
+ var _a;
106
+ return (_a = userManualChunks(id, api)) !== null && _a !== void 0 ? _a : viteManualChunks(id, api);
107
+ };
108
+ }
109
+ // else, leave the object form of manualChunks untouched, as
110
+ // we can't safely replicate rollup handling.
111
+ }
112
+ else {
113
+ output.manualChunks = viteManualChunks;
114
+ }
115
+ }
116
+ }
117
+ }
118
+ else {
119
+ return {
120
+ build: {
121
+ rollupOptions: {
122
+ output: {
123
+ manualChunks: createSplitVendorChunk({}, config)
124
+ }
125
+ }
126
+ }
127
+ };
128
+ }
129
+ },
130
+ buildStart() {
131
+ caches.forEach((cache) => cache.reset());
132
+ }
133
+ };
134
+ }
31
135
 
32
-
33
- exports.build = build.build;
34
- exports.createLogger = build.createLogger;
35
- exports.createServer = build.createServer;
36
- exports.defineConfig = build.defineConfig;
37
- exports.loadConfigFromFile = build.loadConfigFromFile;
38
- exports.loadEnv = build.loadEnv;
39
- exports.mergeConfig = build.mergeConfig;
40
- exports.normalizePath = build.normalizePath;
41
- exports.optimizeDeps = build.optimizeDeps;
42
- exports.preview = build.preview;
43
- exports.printHttpServerUrls = build.printHttpServerUrls;
44
- exports.resolveConfig = build.resolveConfig;
45
- exports.resolveEnvPrefix = build.resolveEnvPrefix;
46
- exports.resolvePackageData = build.resolvePackageData;
47
- exports.resolvePackageEntry = build.resolvePackageEntry;
48
- exports.searchForWorkspaceRoot = build.searchForWorkspaceRoot;
49
- exports.send = build.send;
50
- exports.sortUserPlugins = build.sortUserPlugins;
51
- exports.transformWithEsbuild = build.transformWithEsbuild;
136
+ exports.build = index.build;
137
+ exports.createLogger = index.createLogger;
138
+ exports.createServer = index.createServer;
139
+ exports.defineConfig = index.defineConfig;
140
+ exports.formatPostcssSourceMap = index.formatPostcssSourceMap;
141
+ exports.loadConfigFromFile = index.loadConfigFromFile;
142
+ exports.loadEnv = index.loadEnv;
143
+ exports.mergeConfig = index.mergeConfig;
144
+ exports.normalizePath = index.normalizePath;
145
+ exports.optimizeDeps = index.optimizeDeps;
146
+ exports.preview = index.preview;
147
+ exports.printHttpServerUrls = index.printHttpServerUrls;
148
+ exports.resolveConfig = index.resolveConfig;
149
+ exports.resolveEnvPrefix = index.resolveEnvPrefix;
150
+ exports.resolvePackageData = index.resolvePackageData;
151
+ exports.resolvePackageEntry = index.resolvePackageEntry;
152
+ exports.searchForWorkspaceRoot = index.searchForWorkspaceRoot;
153
+ exports.send = index.send;
154
+ exports.sortUserPlugins = index.sortUserPlugins;
155
+ exports.transformWithEsbuild = index.transformWithEsbuild;
156
+ exports.splitVendorChunk = splitVendorChunk;
157
+ exports.splitVendorChunkPlugin = splitVendorChunkPlugin;
@@ -10201,7 +10201,7 @@ function is_some_comments(comment) {
10201
10201
  // multiline comment
10202
10202
  return (
10203
10203
  (comment.type === "comment2" || comment.type === "comment1")
10204
- && /@preserve|@lic|@cc_on|^\**!/i.test(comment.value)
10204
+ && /@preserve|@copyright|@lic|@cc_on|^\**!/i.test(comment.value)
10205
10205
  );
10206
10206
  }
10207
10207
 
@@ -10314,8 +10314,8 @@ function OutputStream(options) {
10314
10314
  var OUTPUT = new Rope();
10315
10315
  let printed_comments = new Set();
10316
10316
 
10317
- var to_utf8 = options.ascii_only ? function(str, identifier) {
10318
- if (options.ecma >= 2015 && !options.safari10) {
10317
+ var to_utf8 = options.ascii_only ? function(str, identifier = false, regexp = false) {
10318
+ if (options.ecma >= 2015 && !options.safari10 && !regexp) {
10319
10319
  str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) {
10320
10320
  var code = get_full_char_code(ch, 0).toString(16);
10321
10321
  return "\\u{" + code + "}";
@@ -11127,7 +11127,8 @@ function OutputStream(options) {
11127
11127
  var p = output.parent();
11128
11128
  if (this.args.length === 0
11129
11129
  && (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]()
11130
- || p instanceof AST_Call && p.expression === this)) // (new foo)(bar)
11130
+ || p instanceof AST_Call && p.expression === this
11131
+ || p instanceof AST_PrefixedTemplateString && p.prefix === this)) // (new foo)(bar)
11131
11132
  return true;
11132
11133
  });
11133
11134
 
@@ -12242,7 +12243,7 @@ function OutputStream(options) {
12242
12243
  flags = flags ? sort_regexp_flags(flags) : "";
12243
12244
  source = source.replace(r_slash_script, slash_script_replace);
12244
12245
 
12245
- output.print(output.to_utf8(`/${source}/${flags}`));
12246
+ output.print(output.to_utf8(`/${source}/${flags}`, false, true));
12246
12247
 
12247
12248
  const parent = output.parent();
12248
12249
  if (
@@ -12666,6 +12667,11 @@ const MASK_EXPORT_WANT_MANGLE = 1 << 1;
12666
12667
 
12667
12668
  let function_defs = null;
12668
12669
  let unmangleable_names = null;
12670
+ /**
12671
+ * When defined, there is a function declaration somewhere that's inside of a block.
12672
+ * See https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html#sec-block-level-function-declarations-web-legacy-compatibility-semantics
12673
+ */
12674
+ let scopes_with_block_defuns = null;
12669
12675
 
12670
12676
  class SymbolDef {
12671
12677
  constructor(scope, orig, init) {
@@ -13216,6 +13222,15 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
13216
13222
  });
13217
13223
 
13218
13224
  function next_mangled(scope, options) {
13225
+ let defun_scope;
13226
+ if (
13227
+ scopes_with_block_defuns
13228
+ && (defun_scope = scope.get_defun_scope())
13229
+ && scopes_with_block_defuns.has(defun_scope)
13230
+ ) {
13231
+ scope = defun_scope;
13232
+ }
13233
+
13219
13234
  var ext = scope.enclosed;
13220
13235
  var nth_identifier = options.nth_identifier;
13221
13236
  out: while (true) {
@@ -13350,6 +13365,13 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
13350
13365
  lname = save_nesting;
13351
13366
  return true; // don't descend again in TreeWalker
13352
13367
  }
13368
+ if (
13369
+ node instanceof AST_Defun
13370
+ && !(tw.parent() instanceof AST_Scope)
13371
+ ) {
13372
+ scopes_with_block_defuns = scopes_with_block_defuns || new Set();
13373
+ scopes_with_block_defuns.add(node.parent_scope.get_defun_scope());
13374
+ }
13353
13375
  if (node instanceof AST_Scope) {
13354
13376
  node.variables.forEach(collect);
13355
13377
  return;
@@ -13398,6 +13420,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
13398
13420
 
13399
13421
  function_defs = null;
13400
13422
  unmangleable_names = null;
13423
+ scopes_with_block_defuns = null;
13401
13424
 
13402
13425
  function collect(symbol) {
13403
13426
  if (symbol.export & MASK_EXPORT_DONT_MANGLE) {
@@ -30781,7 +30804,54 @@ function cache_to_json(cache) {
30781
30804
  };
30782
30805
  }
30783
30806
 
30784
- async function minify(files, options) {
30807
+ function log_input(files, options, fs, debug_folder) {
30808
+ if (!(fs && fs.writeFileSync && fs.mkdirSync)) {
30809
+ return;
30810
+ }
30811
+
30812
+ try {
30813
+ fs.mkdirSync(debug_folder);
30814
+ } catch (e) {
30815
+ if (e.code !== "EEXIST") throw e;
30816
+ }
30817
+
30818
+ const log_path = `${debug_folder}/terser-debug-${(Math.random() * 9999999) | 0}.log`;
30819
+
30820
+ options = options || {};
30821
+
30822
+ const options_str = JSON.stringify(options, (_key, thing) => {
30823
+ if (typeof thing === "function") return "[Function " + thing.toString() + "]";
30824
+ if (thing instanceof RegExp) return "[RegExp " + thing.toString() + "]";
30825
+ return thing;
30826
+ }, 4);
30827
+
30828
+ const files_str = (file) => {
30829
+ if (typeof file === "object" && options.parse && options.parse.spidermonkey) {
30830
+ return JSON.stringify(file, null, 2);
30831
+ } else if (typeof file === "object") {
30832
+ return Object.keys(file)
30833
+ .map((key) => key + ": " + files_str(file[key]))
30834
+ .join("\n\n");
30835
+ } else if (typeof file === "string") {
30836
+ return "```\n" + file + "\n```";
30837
+ } else {
30838
+ return file; // What do?
30839
+ }
30840
+ };
30841
+
30842
+ fs.writeFileSync(log_path, "Options: \n" + options_str + "\n\nInput files:\n\n" + files_str(files) + "\n");
30843
+ }
30844
+
30845
+ async function minify(files, options, _fs_module) {
30846
+ if (
30847
+ _fs_module
30848
+ && typeof process === "object"
30849
+ && process.env
30850
+ && typeof process.env.TERSER_DEBUG_DIR === "string"
30851
+ ) {
30852
+ log_input(files, options, _fs_module, process.env.TERSER_DEBUG_DIR);
30853
+ }
30854
+
30785
30855
  options = defaults(options, {
30786
30856
  compress: {},
30787
30857
  ecma: undefined,
@@ -30804,6 +30874,7 @@ async function minify(files, options) {
30804
30874
  warnings: false,
30805
30875
  wrap: false,
30806
30876
  }, true);
30877
+
30807
30878
  var timings = options.timings && {
30808
30879
  start: Date.now()
30809
30880
  };
@@ -31205,7 +31276,7 @@ async function run_cli({ program, packageJson, fs, path }) {
31205
31276
 
31206
31277
  let result;
31207
31278
  try {
31208
- result = await minify(files, options);
31279
+ result = await minify(files, options, fs);
31209
31280
  } catch (ex) {
31210
31281
  if (ex.name == "SyntaxError") {
31211
31282
  print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
@@ -31268,14 +31339,18 @@ async function run_cli({ program, packageJson, fs, path }) {
31268
31339
  }, 2));
31269
31340
  } else if (program.output == "spidermonkey") {
31270
31341
  try {
31271
- const minified = await minify(result.code, {
31272
- compress: false,
31273
- mangle: false,
31274
- format: {
31275
- ast: true,
31276
- code: false
31277
- }
31278
- });
31342
+ const minified = await minify(
31343
+ result.code,
31344
+ {
31345
+ compress: false,
31346
+ mangle: false,
31347
+ format: {
31348
+ ast: true,
31349
+ code: false
31350
+ }
31351
+ },
31352
+ fs
31353
+ );
31279
31354
  console.log(JSON.stringify(minified.ast.to_mozilla_ast(), null, 2));
31280
31355
  } catch (ex) {
31281
31356
  fatal(ex);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite",
3
- "version": "2.8.6",
3
+ "version": "2.9.0-beta.10",
4
4
  "license": "MIT",
5
5
  "author": "Evan You",
6
6
  "description": "Native-ESM powered web dev build tool",
@@ -43,8 +43,8 @@
43
43
  },
44
44
  "//": "READ CONTRIBUTING.md to understand what to put under deps vs. devDeps!",
45
45
  "dependencies": {
46
- "esbuild": "^0.14.14",
47
- "postcss": "^8.4.6",
46
+ "esbuild": "^0.14.27",
47
+ "postcss": "^8.4.12",
48
48
  "resolve": "^1.22.0",
49
49
  "rollup": "^2.59.0"
50
50
  },
@@ -52,16 +52,17 @@
52
52
  "fsevents": "~2.3.2"
53
53
  },
54
54
  "devDependencies": {
55
- "@ampproject/remapping": "^2.1.0",
56
- "@babel/parser": "^7.17.0",
55
+ "@ampproject/remapping": "^2.1.2",
56
+ "@babel/parser": "^7.17.8",
57
57
  "@babel/types": "^7.17.0",
58
+ "@jridgewell/trace-mapping": "^0.3.4",
58
59
  "@rollup/plugin-alias": "^3.1.9",
59
- "@rollup/plugin-commonjs": "^21.0.1",
60
+ "@rollup/plugin-commonjs": "^21.0.3",
60
61
  "@rollup/plugin-dynamic-import-vars": "^1.4.2",
61
62
  "@rollup/plugin-json": "^4.1.0",
62
63
  "@rollup/plugin-node-resolve": "13.1.3",
63
- "@rollup/plugin-typescript": "^8.3.0",
64
- "@rollup/pluginutils": "^4.1.2",
64
+ "@rollup/plugin-typescript": "^8.3.1",
65
+ "@rollup/pluginutils": "^4.2.0",
65
66
  "@types/convert-source-map": "^1.5.2",
66
67
  "@types/cross-spawn": "^6.0.2",
67
68
  "@types/debug": "^4.1.7",
@@ -70,50 +71,49 @@
70
71
  "@types/less": "^3.0.3",
71
72
  "@types/micromatch": "^4.0.2",
72
73
  "@types/mime": "^2.0.3",
73
- "@types/node": "^16.11.22",
74
+ "@types/node": "^16.11.26",
74
75
  "@types/resolve": "^1.20.1",
75
76
  "@types/sass": "~1.43.1",
76
77
  "@types/stylus": "^0.48.36",
77
- "@types/ws": "^8.2.2",
78
- "@vue/compiler-dom": "^3.2.30",
78
+ "@types/ws": "^8.5.3",
79
+ "@vue/compiler-dom": "^3.2.31",
79
80
  "acorn": "^8.7.0",
80
81
  "cac": "6.7.9",
81
82
  "chokidar": "^3.5.3",
82
- "compression": "^1.7.4",
83
83
  "connect": "^3.7.0",
84
84
  "connect-history-api-fallback": "^1.6.0",
85
85
  "convert-source-map": "^1.8.0",
86
86
  "cors": "^2.8.5",
87
87
  "cross-spawn": "^7.0.3",
88
- "debug": "^4.3.3",
88
+ "debug": "^4.3.4",
89
89
  "dotenv": "^14.3.2",
90
90
  "dotenv-expand": "^5.1.0",
91
- "es-module-lexer": "^0.9.3",
91
+ "es-module-lexer": "^0.10.4",
92
92
  "estree-walker": "^2.0.2",
93
93
  "etag": "^1.8.1",
94
94
  "fast-glob": "^3.2.11",
95
95
  "http-proxy": "^1.18.1",
96
- "json5": "^2.2.0",
96
+ "json5": "^2.2.1",
97
97
  "launch-editor-middleware": "^2.3.0",
98
- "magic-string": "^0.25.7",
99
- "micromatch": "^4.0.4",
98
+ "magic-string": "^0.26.1",
99
+ "micromatch": "^4.0.5",
100
100
  "mrmime": "^1.0.0",
101
- "node-forge": "^1.2.1",
101
+ "node-forge": "^1.3.0",
102
102
  "okie": "^1.0.1",
103
103
  "open": "^8.4.0",
104
104
  "periscopic": "^2.0.3",
105
105
  "picocolors": "^1.0.0",
106
- "postcss-import": "^14.0.2",
107
- "postcss-load-config": "^3.1.1",
108
- "postcss-modules": "^4.3.0",
106
+ "postcss-import": "^14.1.0",
107
+ "postcss-load-config": "^3.1.3",
108
+ "postcss-modules": "^4.3.1",
109
109
  "resolve.exports": "^1.1.0",
110
110
  "rollup-plugin-license": "^2.6.1",
111
111
  "sirv": "^2.0.2",
112
112
  "source-map-js": "^1.0.2",
113
113
  "source-map-support": "^0.5.21",
114
114
  "strip-ansi": "^6.0.1",
115
- "terser": "^5.10.0",
116
- "tsconfck": "1.1.2",
115
+ "terser": "^5.12.1",
116
+ "tsconfck": "^1.2.1",
117
117
  "tslib": "^2.3.1",
118
118
  "types": "link:./types",
119
119
  "ws": "^8.5.0"
@@ -1,12 +1,6 @@
1
- import type {
2
- ErrorPayload,
3
- FullReloadPayload,
4
- HMRPayload,
5
- PrunePayload,
6
- Update,
7
- UpdatePayload
8
- } from 'types/hmrPayload'
9
- import type { CustomEventName } from 'types/customEvent'
1
+ import type { ErrorPayload, HMRPayload, Update } from 'types/hmrPayload'
2
+ import type { ViteHotContext } from 'types/hot'
3
+ import type { InferCustomEventPayload } from 'types/customEvent'
10
4
  import { ErrorOverlay, overlayId } from './overlay'
11
5
  // eslint-disable-next-line node/no-missing-import
12
6
  import '@vite/env'
@@ -15,7 +9,7 @@ import '@vite/env'
15
9
  declare const __BASE__: string
16
10
  declare const __HMR_PROTOCOL__: string
17
11
  declare const __HMR_HOSTNAME__: string
18
- declare const __HMR_PORT__: string
12
+ declare const __HMR_PORT__: string | false
19
13
  declare const __HMR_TIMEOUT__: number
20
14
  declare const __HMR_ENABLE_OVERLAY__: boolean
21
15
 
@@ -24,9 +18,13 @@ console.log('[vite] connecting...')
24
18
  // use server configuration, then fallback to inference
25
19
  const socketProtocol =
26
20
  __HMR_PROTOCOL__ || (location.protocol === 'https:' ? 'wss' : 'ws')
27
- const socketHost = `${__HMR_HOSTNAME__ || location.hostname}:${__HMR_PORT__}`
21
+ const socketHost = __HMR_PORT__
22
+ ? `${__HMR_HOSTNAME__ || location.hostname}:${__HMR_PORT__}`
23
+ : `${__HMR_HOSTNAME__ || location.hostname}`
24
+
28
25
  const socket = new WebSocket(`${socketProtocol}://${socketHost}`, 'vite-hmr')
29
26
  const base = __BASE__ || '/'
27
+ const messageBuffer: string[] = []
30
28
 
31
29
  function warnFailedFetch(err: Error, path: string | string[]) {
32
30
  if (!err.message.match('fetch')) {
@@ -56,9 +54,10 @@ async function handleMessage(payload: HMRPayload) {
56
54
  switch (payload.type) {
57
55
  case 'connected':
58
56
  console.log(`[vite] connected.`)
57
+ sendMessageBuffer()
59
58
  // proxy(nginx, docker) hmr ws maybe caused timeout,
60
59
  // so send ping package let ws keep alive.
61
- setInterval(() => socket.send('ping'), __HMR_TIMEOUT__)
60
+ setInterval(() => socket.send('{"type":"ping"}'), __HMR_TIMEOUT__)
62
61
  break
63
62
  case 'update':
64
63
  notifyListeners('vite:beforeUpdate', payload)
@@ -98,7 +97,7 @@ async function handleMessage(payload: HMRPayload) {
98
97
  })
99
98
  break
100
99
  case 'custom': {
101
- notifyListeners(payload.event as CustomEventName<any>, payload.data)
100
+ notifyListeners(payload.event, payload.data)
102
101
  break
103
102
  }
104
103
  case 'full-reload':
@@ -151,19 +150,9 @@ async function handleMessage(payload: HMRPayload) {
151
150
  }
152
151
  }
153
152
 
154
- function notifyListeners(
155
- event: 'vite:beforeUpdate',
156
- payload: UpdatePayload
157
- ): void
158
- function notifyListeners(event: 'vite:beforePrune', payload: PrunePayload): void
159
- function notifyListeners(
160
- event: 'vite:beforeFullReload',
161
- payload: FullReloadPayload
162
- ): void
163
- function notifyListeners(event: 'vite:error', payload: ErrorPayload): void
164
153
  function notifyListeners<T extends string>(
165
- event: CustomEventName<T>,
166
- data: any
154
+ event: T,
155
+ data: InferCustomEventPayload<T>
167
156
  ): void
168
157
  function notifyListeners(event: string, data: any): void {
169
158
  const cbs = customListenersMap.get(event)
@@ -214,9 +203,14 @@ async function waitForSuccessfulPing(ms = 1000) {
214
203
  // eslint-disable-next-line no-constant-condition
215
204
  while (true) {
216
205
  try {
217
- await fetch(`${base}__vite_ping`)
218
- break
206
+ const pingResponse = await fetch(`${base}__vite_ping`)
207
+
208
+ // success - 2xx status code
209
+ if (pingResponse.ok) break
210
+ // failure - non-2xx status code
211
+ else throw new Error()
219
212
  } catch (e) {
213
+ // wait ms before attempting to ping again
220
214
  await new Promise((resolve) => setTimeout(resolve, ms))
221
215
  }
222
216
  }
@@ -353,6 +347,13 @@ async function fetchUpdate({ path, acceptedPath, timestamp }: Update) {
353
347
  }
354
348
  }
355
349
 
350
+ function sendMessageBuffer() {
351
+ if (socket.readyState === 1) {
352
+ messageBuffer.forEach((msg) => socket.send(msg))
353
+ messageBuffer.length = 0
354
+ }
355
+ }
356
+
356
357
  interface HotModule {
357
358
  id: string
358
359
  callbacks: HotCallback[]
@@ -374,9 +375,7 @@ const ctxToListenersMap = new Map<
374
375
  Map<string, ((data: any) => void)[]>
375
376
  >()
376
377
 
377
- // Just infer the return type for now
378
- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
379
- export const createHotContext = (ownerPath: string) => {
378
+ export function createHotContext(ownerPath: string): ViteHotContext {
380
379
  if (!dataMap.has(ownerPath)) {
381
380
  dataMap.set(ownerPath, {})
382
381
  }
@@ -417,12 +416,12 @@ export const createHotContext = (ownerPath: string) => {
417
416
  hotModulesMap.set(ownerPath, mod)
418
417
  }
419
418
 
420
- const hot = {
419
+ const hot: ViteHotContext = {
421
420
  get data() {
422
421
  return dataMap.get(ownerPath)
423
422
  },
424
423
 
425
- accept(deps: any, callback?: any) {
424
+ accept(deps?: any, callback?: any) {
426
425
  if (typeof deps === 'function' || !deps) {
427
426
  // self-accept: hot.accept(() => {})
428
427
  acceptDeps([ownerPath], ([mod]) => deps && deps(mod))
@@ -443,10 +442,11 @@ export const createHotContext = (ownerPath: string) => {
443
442
  )
444
443
  },
445
444
 
446
- dispose(cb: (data: any) => void) {
445
+ dispose(cb) {
447
446
  disposeMap.set(ownerPath, cb)
448
447
  },
449
448
 
449
+ // @ts-expect-error untyped
450
450
  prune(cb: (data: any) => void) {
451
451
  pruneMap.set(ownerPath, cb)
452
452
  },
@@ -462,7 +462,7 @@ export const createHotContext = (ownerPath: string) => {
462
462
  },
463
463
 
464
464
  // custom events
465
- on: (event: string, cb: (data: any) => void) => {
465
+ on(event, cb) {
466
466
  const addToMap = (map: Map<string, any[]>) => {
467
467
  const existing = map.get(event) || []
468
468
  existing.push(cb)
@@ -470,6 +470,11 @@ export const createHotContext = (ownerPath: string) => {
470
470
  }
471
471
  addToMap(customListenersMap)
472
472
  addToMap(newListeners)
473
+ },
474
+
475
+ send(event, data) {
476
+ messageBuffer.push(JSON.stringify({ type: 'custom', event, data }))
477
+ sendMessageBuffer()
473
478
  }
474
479
  }
475
480
 
@@ -1,5 +1,16 @@
1
- // See https://stackoverflow.com/a/63549561.
2
- export type CustomEventName<T extends string> = (T extends `vite:${T}`
3
- ? never
4
- : T) &
5
- (`vite:${T}` extends T ? never : T)
1
+ import type {
2
+ ErrorPayload,
3
+ FullReloadPayload,
4
+ PrunePayload,
5
+ UpdatePayload
6
+ } from './hmrPayload'
7
+
8
+ export interface CustomEventMap {
9
+ 'vite:beforeUpdate': UpdatePayload
10
+ 'vite:beforePrune': PrunePayload
11
+ 'vite:beforeFullReload': FullReloadPayload
12
+ 'vite:error': ErrorPayload
13
+ }
14
+
15
+ export type InferCustomEventPayload<T extends string> =
16
+ T extends keyof CustomEventMap ? CustomEventMap[T] : any
package/types/hot.d.ts ADDED
@@ -0,0 +1,25 @@
1
+ import type { InferCustomEventPayload } from './customEvent'
2
+
3
+ export interface ViteHotContext {
4
+ readonly data: any
5
+
6
+ accept(): void
7
+ accept(cb: (mod: any) => void): void
8
+ accept(dep: string, cb: (mod: any) => void): void
9
+ accept(deps: readonly string[], cb: (mods: any[]) => void): void
10
+
11
+ /**
12
+ * @deprecated
13
+ */
14
+ acceptDeps(): never
15
+
16
+ dispose(cb: (data: any) => void): void
17
+ decline(): void
18
+ invalidate(): void
19
+
20
+ on<T extends string>(
21
+ event: T,
22
+ cb: (payload: InferCustomEventPayload<T>) => void
23
+ ): void
24
+ send<T extends string>(event: T, data?: InferCustomEventPayload<T>): void
25
+ }