版博士V2.0程序
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

997 wiersze
30 KiB

  1. import { dirname, resolve, join } from 'node:path';
  2. import fs from 'fs-extra';
  3. import _debug from 'debug';
  4. import { green, dim, bold } from 'kolorist';
  5. import sirv from 'sirv';
  6. import { createFilter } from '@rollup/pluginutils';
  7. import { fileURLToPath } from 'node:url';
  8. const DEFAULT_TIMEOUT = 6e4;
  9. const defaultSerialize = (i) => i;
  10. const defaultDeserialize = defaultSerialize;
  11. function createBirpc(functions, options) {
  12. const {
  13. post,
  14. on,
  15. eventNames = [],
  16. serialize = defaultSerialize,
  17. deserialize = defaultDeserialize,
  18. timeout = DEFAULT_TIMEOUT
  19. } = options;
  20. const rpcPromiseMap = /* @__PURE__ */ new Map();
  21. let _promise;
  22. const rpc = new Proxy({}, {
  23. get(_, method) {
  24. const sendEvent = (...args) => {
  25. post(serialize({ m: method, a: args, t: "q" }));
  26. };
  27. if (eventNames.includes(method)) {
  28. sendEvent.asEvent = sendEvent;
  29. return sendEvent;
  30. }
  31. const sendCall = async (...args) => {
  32. await _promise;
  33. return new Promise((resolve, reject) => {
  34. const id = nanoid();
  35. rpcPromiseMap.set(id, { resolve, reject });
  36. post(serialize({ m: method, a: args, i: id, t: "q" }));
  37. if (timeout >= 0) {
  38. setTimeout(() => {
  39. reject(new Error(`[birpc] timeout on calling "${method}"`));
  40. rpcPromiseMap.delete(id);
  41. }, timeout);
  42. }
  43. });
  44. };
  45. sendCall.asEvent = sendEvent;
  46. return sendCall;
  47. }
  48. });
  49. _promise = on(async (data, ...extra) => {
  50. const msg = deserialize(data);
  51. if (msg.t === "q") {
  52. const { m: method, a: args } = msg;
  53. let result, error;
  54. try {
  55. result = await functions[method].apply(rpc, args);
  56. } catch (e) {
  57. error = e;
  58. }
  59. if (msg.i)
  60. post(serialize({ t: "s", i: msg.i, r: result, e: error }), ...extra);
  61. } else {
  62. const { i: ack, r: result, e: error } = msg;
  63. const promise = rpcPromiseMap.get(ack);
  64. if (promise) {
  65. if (error)
  66. promise.reject(error);
  67. else
  68. promise.resolve(result);
  69. }
  70. rpcPromiseMap.delete(ack);
  71. }
  72. });
  73. return rpc;
  74. }
  75. const cacheMap = /* @__PURE__ */ new WeakMap();
  76. function cachedMap(items, fn) {
  77. return items.map((i) => {
  78. let r = cacheMap.get(i);
  79. if (!r) {
  80. r = fn(i);
  81. cacheMap.set(i, r);
  82. }
  83. return r;
  84. });
  85. }
  86. function createBirpcGroup(functions, channels, options = {}) {
  87. const getChannels = () => typeof channels === "function" ? channels() : channels;
  88. const getClients = (channels2 = getChannels()) => cachedMap(channels2, (s) => createBirpc(functions, { ...options, ...s }));
  89. const broadcastProxy = new Proxy({}, {
  90. get(_, method) {
  91. const client = getClients();
  92. const functions2 = client.map((c) => c[method]);
  93. const sendCall = (...args) => {
  94. return Promise.all(functions2.map((i) => i(...args)));
  95. };
  96. sendCall.asEvent = (...args) => {
  97. functions2.map((i) => i.asEvent(...args));
  98. };
  99. return sendCall;
  100. }
  101. });
  102. function updateChannels(fn) {
  103. const channels2 = getChannels();
  104. fn?.(channels2);
  105. return getClients(channels2);
  106. }
  107. getClients();
  108. return {
  109. get clients() {
  110. return getClients();
  111. },
  112. updateChannels,
  113. broadcast: broadcastProxy,
  114. /**
  115. * @deprecated use `broadcast`
  116. */
  117. boardcast: broadcastProxy
  118. };
  119. }
  120. const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
  121. function nanoid(size = 21) {
  122. let id = "";
  123. let i = size;
  124. while (i--)
  125. id += urlAlphabet[Math.random() * 64 | 0];
  126. return id;
  127. }
  128. function createRPCServer(name, ws, functions) {
  129. const event = `${name}:rpc`;
  130. const group = createBirpcGroup(
  131. functions,
  132. () => cachedMap(
  133. Array.from(ws?.clients || []),
  134. (socket) => {
  135. return {
  136. on: (fn) => {
  137. ws.on(event, (data, source) => {
  138. if (socket === source)
  139. fn(data);
  140. });
  141. },
  142. post: (data) => {
  143. socket.send(event, data);
  144. }
  145. };
  146. }
  147. )
  148. );
  149. ws.on("connection", () => {
  150. group.updateChannels();
  151. });
  152. return group.broadcast;
  153. }
  154. const defaults = {
  155. ignoreUnknown: false,
  156. respectType: false,
  157. respectFunctionNames: false,
  158. respectFunctionProperties: false,
  159. unorderedObjects: true,
  160. unorderedArrays: false,
  161. unorderedSets: false
  162. };
  163. function objectHash(object, options = {}) {
  164. options = { ...defaults, ...options };
  165. const hasher = createHasher(options);
  166. hasher.dispatch(object);
  167. return hasher.toString();
  168. }
  169. function createHasher(options) {
  170. const buff = [];
  171. let context = [];
  172. const write = (str) => {
  173. buff.push(str);
  174. };
  175. return {
  176. toString() {
  177. return buff.join("");
  178. },
  179. getContext() {
  180. return context;
  181. },
  182. dispatch(value) {
  183. if (options.replacer) {
  184. value = options.replacer(value);
  185. }
  186. const type = value === null ? "null" : typeof value;
  187. return this["_" + type](value);
  188. },
  189. _object(object) {
  190. const pattern = /\[object (.*)]/i;
  191. const objString = Object.prototype.toString.call(object);
  192. const _objType = pattern.exec(objString);
  193. const objType = _objType ? _objType[1].toLowerCase() : "unknown:[" + objString.toLowerCase() + "]";
  194. let objectNumber = null;
  195. if ((objectNumber = context.indexOf(object)) >= 0) {
  196. return this.dispatch("[CIRCULAR:" + objectNumber + "]");
  197. } else {
  198. context.push(object);
  199. }
  200. if (typeof Buffer !== "undefined" && Buffer.isBuffer && Buffer.isBuffer(object)) {
  201. write("buffer:");
  202. return write(object.toString("utf8"));
  203. }
  204. if (objType !== "object" && objType !== "function" && objType !== "asyncfunction") {
  205. if (this["_" + objType]) {
  206. this["_" + objType](object);
  207. } else if (options.ignoreUnknown) {
  208. return write("[" + objType + "]");
  209. } else {
  210. throw new Error('Unknown object type "' + objType + '"');
  211. }
  212. } else {
  213. let keys = Object.keys(object);
  214. if (options.unorderedObjects) {
  215. keys = keys.sort();
  216. }
  217. if (options.respectType !== false && !isNativeFunction(object)) {
  218. keys.splice(0, 0, "prototype", "__proto__", "letructor");
  219. }
  220. if (options.excludeKeys) {
  221. keys = keys.filter(function(key) {
  222. return !options.excludeKeys(key);
  223. });
  224. }
  225. write("object:" + keys.length + ":");
  226. for (const key of keys) {
  227. this.dispatch(key);
  228. write(":");
  229. if (!options.excludeValues) {
  230. this.dispatch(object[key]);
  231. }
  232. write(",");
  233. }
  234. }
  235. },
  236. _array(arr, unordered) {
  237. unordered = typeof unordered !== "undefined" ? unordered : options.unorderedArrays !== false;
  238. write("array:" + arr.length + ":");
  239. if (!unordered || arr.length <= 1) {
  240. for (const entry of arr) {
  241. this.dispatch(entry);
  242. }
  243. return;
  244. }
  245. const contextAdditions = [];
  246. const entries = arr.map((entry) => {
  247. const hasher = createHasher(options);
  248. hasher.dispatch(entry);
  249. contextAdditions.push(hasher.getContext());
  250. return hasher.toString();
  251. });
  252. context = [...context, ...contextAdditions];
  253. entries.sort();
  254. return this._array(entries, false);
  255. },
  256. _date(date) {
  257. return write("date:" + date.toJSON());
  258. },
  259. _symbol(sym) {
  260. return write("symbol:" + sym.toString());
  261. },
  262. _error(err) {
  263. return write("error:" + err.toString());
  264. },
  265. _boolean(bool) {
  266. return write("bool:" + bool.toString());
  267. },
  268. _string(string) {
  269. write("string:" + string.length + ":");
  270. write(string.toString());
  271. },
  272. _function(fn) {
  273. write("fn:");
  274. if (isNativeFunction(fn)) {
  275. this.dispatch("[native]");
  276. } else {
  277. this.dispatch(fn.toString());
  278. }
  279. if (options.respectFunctionNames !== false) {
  280. this.dispatch("function-name:" + String(fn.name));
  281. }
  282. if (options.respectFunctionProperties) {
  283. this._object(fn);
  284. }
  285. },
  286. _number(number) {
  287. return write("number:" + number.toString());
  288. },
  289. _xml(xml) {
  290. return write("xml:" + xml.toString());
  291. },
  292. _null() {
  293. return write("Null");
  294. },
  295. _undefined() {
  296. return write("Undefined");
  297. },
  298. _regexp(regex) {
  299. return write("regex:" + regex.toString());
  300. },
  301. _uint8array(arr) {
  302. write("uint8array:");
  303. return this.dispatch(Array.prototype.slice.call(arr));
  304. },
  305. _uint8clampedarray(arr) {
  306. write("uint8clampedarray:");
  307. return this.dispatch(Array.prototype.slice.call(arr));
  308. },
  309. _int8array(arr) {
  310. write("int8array:");
  311. return this.dispatch(Array.prototype.slice.call(arr));
  312. },
  313. _uint16array(arr) {
  314. write("uint16array:");
  315. return this.dispatch(Array.prototype.slice.call(arr));
  316. },
  317. _int16array(arr) {
  318. write("int16array:");
  319. return this.dispatch(Array.prototype.slice.call(arr));
  320. },
  321. _uint32array(arr) {
  322. write("uint32array:");
  323. return this.dispatch(Array.prototype.slice.call(arr));
  324. },
  325. _int32array(arr) {
  326. write("int32array:");
  327. return this.dispatch(Array.prototype.slice.call(arr));
  328. },
  329. _float32array(arr) {
  330. write("float32array:");
  331. return this.dispatch(Array.prototype.slice.call(arr));
  332. },
  333. _float64array(arr) {
  334. write("float64array:");
  335. return this.dispatch(Array.prototype.slice.call(arr));
  336. },
  337. _arraybuffer(arr) {
  338. write("arraybuffer:");
  339. return this.dispatch(new Uint8Array(arr));
  340. },
  341. _url(url) {
  342. return write("url:" + url.toString());
  343. },
  344. _map(map) {
  345. write("map:");
  346. const arr = [...map];
  347. return this._array(arr, options.unorderedSets !== false);
  348. },
  349. _set(set) {
  350. write("set:");
  351. const arr = [...set];
  352. return this._array(arr, options.unorderedSets !== false);
  353. },
  354. _file(file) {
  355. write("file:");
  356. return this.dispatch([file.name, file.size, file.type, file.lastModfied]);
  357. },
  358. _blob() {
  359. if (options.ignoreUnknown) {
  360. return write("[blob]");
  361. }
  362. throw new Error('Hashing Blob objects is currently not supported\nUse "options.replacer" or "options.ignoreUnknown"\n');
  363. },
  364. _domwindow() {
  365. return write("domwindow");
  366. },
  367. _bigint(number) {
  368. return write("bigint:" + number.toString());
  369. },
  370. _process() {
  371. return write("process");
  372. },
  373. _timer() {
  374. return write("timer");
  375. },
  376. _pipe() {
  377. return write("pipe");
  378. },
  379. _tcp() {
  380. return write("tcp");
  381. },
  382. _udp() {
  383. return write("udp");
  384. },
  385. _tty() {
  386. return write("tty");
  387. },
  388. _statwatcher() {
  389. return write("statwatcher");
  390. },
  391. _securecontext() {
  392. return write("securecontext");
  393. },
  394. _connection() {
  395. return write("connection");
  396. },
  397. _zlib() {
  398. return write("zlib");
  399. },
  400. _context() {
  401. return write("context");
  402. },
  403. _nodescript() {
  404. return write("nodescript");
  405. },
  406. _httpparser() {
  407. return write("httpparser");
  408. },
  409. _dataview() {
  410. return write("dataview");
  411. },
  412. _signal() {
  413. return write("signal");
  414. },
  415. _fsevent() {
  416. return write("fsevent");
  417. },
  418. _tlswrap() {
  419. return write("tlswrap");
  420. }
  421. };
  422. }
  423. function isNativeFunction(f) {
  424. if (typeof f !== "function") {
  425. return false;
  426. }
  427. const exp = /^function\s+\w*\s*\(\s*\)\s*{\s+\[native code]\s+}$/i;
  428. return exp.exec(Function.prototype.toString.call(f)) != null;
  429. }
  430. class WordArray {
  431. constructor(words, sigBytes) {
  432. words = this.words = words || [];
  433. this.sigBytes = sigBytes !== void 0 ? sigBytes : words.length * 4;
  434. }
  435. toString(encoder) {
  436. return (encoder || Hex).stringify(this);
  437. }
  438. concat(wordArray) {
  439. this.clamp();
  440. if (this.sigBytes % 4) {
  441. for (let i = 0; i < wordArray.sigBytes; i++) {
  442. const thatByte = wordArray.words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
  443. this.words[this.sigBytes + i >>> 2] |= thatByte << 24 - (this.sigBytes + i) % 4 * 8;
  444. }
  445. } else {
  446. for (let j = 0; j < wordArray.sigBytes; j += 4) {
  447. this.words[this.sigBytes + j >>> 2] = wordArray.words[j >>> 2];
  448. }
  449. }
  450. this.sigBytes += wordArray.sigBytes;
  451. return this;
  452. }
  453. clamp() {
  454. this.words[this.sigBytes >>> 2] &= 4294967295 << 32 - this.sigBytes % 4 * 8;
  455. this.words.length = Math.ceil(this.sigBytes / 4);
  456. }
  457. clone() {
  458. return new WordArray([...this.words]);
  459. }
  460. }
  461. const Hex = {
  462. stringify(wordArray) {
  463. const hexChars = [];
  464. for (let i = 0; i < wordArray.sigBytes; i++) {
  465. const bite = wordArray.words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
  466. hexChars.push(
  467. (bite >>> 4).toString(16),
  468. (bite & 15).toString(16)
  469. );
  470. }
  471. return hexChars.join("");
  472. }
  473. };
  474. const Base64 = {
  475. stringify(wordArray) {
  476. const keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  477. const base64Chars = [];
  478. for (let i = 0; i < wordArray.sigBytes; i += 3) {
  479. const byte1 = wordArray.words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
  480. const byte2 = wordArray.words[i + 1 >>> 2] >>> 24 - (i + 1) % 4 * 8 & 255;
  481. const byte3 = wordArray.words[i + 2 >>> 2] >>> 24 - (i + 2) % 4 * 8 & 255;
  482. const triplet = byte1 << 16 | byte2 << 8 | byte3;
  483. for (let j = 0; j < 4 && i * 8 + j * 6 < wordArray.sigBytes * 8; j++) {
  484. base64Chars.push(keyStr.charAt(triplet >>> 6 * (3 - j) & 63));
  485. }
  486. }
  487. return base64Chars.join("");
  488. }
  489. };
  490. const Latin1 = {
  491. parse(latin1Str) {
  492. const latin1StrLength = latin1Str.length;
  493. const words = [];
  494. for (let i = 0; i < latin1StrLength; i++) {
  495. words[i >>> 2] |= (latin1Str.charCodeAt(i) & 255) << 24 - i % 4 * 8;
  496. }
  497. return new WordArray(words, latin1StrLength);
  498. }
  499. };
  500. const Utf8 = {
  501. parse(utf8Str) {
  502. return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
  503. }
  504. };
  505. class BufferedBlockAlgorithm {
  506. constructor() {
  507. this._minBufferSize = 0;
  508. this.blockSize = 512 / 32;
  509. this.reset();
  510. }
  511. reset() {
  512. this._data = new WordArray();
  513. this._nDataBytes = 0;
  514. }
  515. _append(data) {
  516. if (typeof data === "string") {
  517. data = Utf8.parse(data);
  518. }
  519. this._data.concat(data);
  520. this._nDataBytes += data.sigBytes;
  521. }
  522. _doProcessBlock(_dataWords, _offset) {
  523. }
  524. _process(doFlush) {
  525. let processedWords;
  526. let nBlocksReady = this._data.sigBytes / (this.blockSize * 4);
  527. if (doFlush) {
  528. nBlocksReady = Math.ceil(nBlocksReady);
  529. } else {
  530. nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
  531. }
  532. const nWordsReady = nBlocksReady * this.blockSize;
  533. const nBytesReady = Math.min(nWordsReady * 4, this._data.sigBytes);
  534. if (nWordsReady) {
  535. for (let offset = 0; offset < nWordsReady; offset += this.blockSize) {
  536. this._doProcessBlock(this._data.words, offset);
  537. }
  538. processedWords = this._data.words.splice(0, nWordsReady);
  539. this._data.sigBytes -= nBytesReady;
  540. }
  541. return new WordArray(processedWords, nBytesReady);
  542. }
  543. }
  544. class Hasher extends BufferedBlockAlgorithm {
  545. update(messageUpdate) {
  546. this._append(messageUpdate);
  547. this._process();
  548. return this;
  549. }
  550. finalize(messageUpdate) {
  551. if (messageUpdate) {
  552. this._append(messageUpdate);
  553. }
  554. }
  555. }
  556. const H = [1779033703, -1150833019, 1013904242, -1521486534, 1359893119, -1694144372, 528734635, 1541459225];
  557. const K = [1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987, 1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, -1866530822, -1538233109, -1090935817, -965641998];
  558. const W = [];
  559. class SHA256 extends Hasher {
  560. constructor() {
  561. super();
  562. this.reset();
  563. }
  564. reset() {
  565. super.reset();
  566. this._hash = new WordArray([...H]);
  567. }
  568. _doProcessBlock(M, offset) {
  569. const H2 = this._hash.words;
  570. let a = H2[0];
  571. let b = H2[1];
  572. let c = H2[2];
  573. let d = H2[3];
  574. let e = H2[4];
  575. let f = H2[5];
  576. let g = H2[6];
  577. let h = H2[7];
  578. for (let i = 0; i < 64; i++) {
  579. if (i < 16) {
  580. W[i] = M[offset + i] | 0;
  581. } else {
  582. const gamma0x = W[i - 15];
  583. const gamma0 = (gamma0x << 25 | gamma0x >>> 7) ^ (gamma0x << 14 | gamma0x >>> 18) ^ gamma0x >>> 3;
  584. const gamma1x = W[i - 2];
  585. const gamma1 = (gamma1x << 15 | gamma1x >>> 17) ^ (gamma1x << 13 | gamma1x >>> 19) ^ gamma1x >>> 10;
  586. W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];
  587. }
  588. const ch = e & f ^ ~e & g;
  589. const maj = a & b ^ a & c ^ b & c;
  590. const sigma0 = (a << 30 | a >>> 2) ^ (a << 19 | a >>> 13) ^ (a << 10 | a >>> 22);
  591. const sigma1 = (e << 26 | e >>> 6) ^ (e << 21 | e >>> 11) ^ (e << 7 | e >>> 25);
  592. const t1 = h + sigma1 + ch + K[i] + W[i];
  593. const t2 = sigma0 + maj;
  594. h = g;
  595. g = f;
  596. f = e;
  597. e = d + t1 | 0;
  598. d = c;
  599. c = b;
  600. b = a;
  601. a = t1 + t2 | 0;
  602. }
  603. H2[0] = H2[0] + a | 0;
  604. H2[1] = H2[1] + b | 0;
  605. H2[2] = H2[2] + c | 0;
  606. H2[3] = H2[3] + d | 0;
  607. H2[4] = H2[4] + e | 0;
  608. H2[5] = H2[5] + f | 0;
  609. H2[6] = H2[6] + g | 0;
  610. H2[7] = H2[7] + h | 0;
  611. }
  612. finalize(messageUpdate) {
  613. super.finalize(messageUpdate);
  614. const nBitsTotal = this._nDataBytes * 8;
  615. const nBitsLeft = this._data.sigBytes * 8;
  616. this._data.words[nBitsLeft >>> 5] |= 128 << 24 - nBitsLeft % 32;
  617. this._data.words[(nBitsLeft + 64 >>> 9 << 4) + 14] = Math.floor(nBitsTotal / 4294967296);
  618. this._data.words[(nBitsLeft + 64 >>> 9 << 4) + 15] = nBitsTotal;
  619. this._data.sigBytes = this._data.words.length * 4;
  620. this._process();
  621. return this._hash;
  622. }
  623. }
  624. function sha256base64(message) {
  625. return new SHA256().finalize(message).toString(Base64);
  626. }
  627. function hash(object, options = {}) {
  628. const hashed = typeof object === "string" ? object : objectHash(object, options);
  629. return sha256base64(hashed).slice(0, 10);
  630. }
  631. const DIR_DIST = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url));
  632. const DIR_CLIENT = resolve(DIR_DIST, "../dist/client");
  633. const debug = _debug("vite-plugin-inspect");
  634. const NAME = "vite-plugin-inspect";
  635. const dummyLoadPluginName = "__load__";
  636. function PluginInspect(options = {}) {
  637. const {
  638. dev = true,
  639. build = false,
  640. outputDir = ".vite-inspect"
  641. } = options;
  642. if (!dev && !build) {
  643. return {
  644. name: NAME
  645. };
  646. }
  647. const filter = createFilter(options.include, options.exclude);
  648. let config;
  649. const transformMap = {};
  650. const transformMapSSR = {};
  651. const idMap = {};
  652. const idMapSSR = {};
  653. function hijackHook(plugin2, name, wrapper) {
  654. if (!plugin2[name])
  655. return;
  656. debug(`hijack plugin "${name}"`, plugin2.name);
  657. let order = plugin2.order || plugin2.enforce || "normal";
  658. const hook = plugin2[name];
  659. if ("handler" in hook) {
  660. const oldFn = hook.handler;
  661. order += `-${hook.order || hook.enforce || "normal"}`;
  662. hook.handler = function(...args) {
  663. return wrapper(oldFn, this, args, order);
  664. };
  665. } else if ("transform" in hook) {
  666. const oldFn = hook.transform;
  667. order += `-${hook.order || hook.enforce || "normal"}`;
  668. hook.transform = function(...args) {
  669. return wrapper(oldFn, this, args, order);
  670. };
  671. } else {
  672. const oldFn = hook;
  673. plugin2[name] = function(...args) {
  674. return wrapper(oldFn, this, args, order);
  675. };
  676. }
  677. }
  678. function hijackPlugin(plugin2) {
  679. hijackHook(plugin2, "transform", async (fn, context, args, order) => {
  680. const code = args[0];
  681. const id = args[1];
  682. const ssr = args[2]?.ssr;
  683. const start = Date.now();
  684. const _result = await fn.apply(context, args);
  685. const end = Date.now();
  686. const result = typeof _result === "string" ? _result : _result?.code;
  687. const map = ssr ? transformMapSSR : transformMap;
  688. if (filter(id) && result != null) {
  689. if (!map[id])
  690. map[id] = [{ name: dummyLoadPluginName, result: code, start, end: start }];
  691. map[id].push({ name: plugin2.name, result, start, end, order });
  692. }
  693. return _result;
  694. });
  695. hijackHook(plugin2, "load", async (fn, context, args) => {
  696. const id = args[0];
  697. const ssr = args[1]?.ssr;
  698. const start = Date.now();
  699. const _result = await fn.apply(context, args);
  700. const end = Date.now();
  701. const result = typeof _result === "string" ? _result : _result?.code;
  702. const map = ssr ? transformMapSSR : transformMap;
  703. if (filter(id) && result != null)
  704. map[id] = [{ name: plugin2.name, result, start, end }];
  705. return _result;
  706. });
  707. hijackHook(plugin2, "resolveId", async (fn, context, args) => {
  708. const id = args[0];
  709. const ssr = args[2]?.ssr;
  710. const start = Date.now();
  711. const _result = await fn.apply(context, args);
  712. const end = Date.now();
  713. const result = typeof _result === "object" ? _result?.id : _result;
  714. const map = ssr ? idMapSSR : idMap;
  715. if (result && result !== id) {
  716. if (!map[id])
  717. map[id] = [];
  718. map[id].push({ name: plugin2.name, result, start, end });
  719. }
  720. return _result;
  721. });
  722. }
  723. function resolveId(id = "", ssr = false) {
  724. if (id.startsWith("./"))
  725. id = resolve(config.root, id).replace(/\\/g, "/");
  726. return resolveIdRec(id, ssr);
  727. }
  728. function resolveIdRec(id, ssr = false) {
  729. const map = ssr ? idMapSSR : idMap;
  730. return map[id]?.[0] ? resolveIdRec(map[id][0].result, ssr) : id;
  731. }
  732. function getPluginMetrics(ssr = false) {
  733. const map = {};
  734. const defaultMetricInfo = () => ({
  735. transform: { invokeCount: 0, totalTime: 0 },
  736. resolveId: { invokeCount: 0, totalTime: 0 }
  737. });
  738. config.plugins.forEach((i) => {
  739. map[i.name] = {
  740. ...defaultMetricInfo(),
  741. name: i.name,
  742. enforce: i.enforce
  743. };
  744. });
  745. Object.values(ssr ? transformMapSSR : transformMap).forEach((transformInfos) => {
  746. transformInfos.forEach(({ name, start, end }) => {
  747. if (name === dummyLoadPluginName)
  748. return;
  749. if (!map[name])
  750. map[name] = { ...defaultMetricInfo(), name };
  751. map[name].transform.totalTime += end - start;
  752. map[name].transform.invokeCount += 1;
  753. });
  754. });
  755. Object.values(ssr ? idMapSSR : idMap).forEach((resolveIdInfos) => {
  756. resolveIdInfos.forEach(({ name, start, end }) => {
  757. if (!map[name])
  758. map[name] = { ...defaultMetricInfo(), name };
  759. map[name].resolveId.totalTime += end - start;
  760. map[name].resolveId.invokeCount += 1;
  761. });
  762. });
  763. const metrics = Object.values(map).filter(Boolean).sort((a, b) => a.name.localeCompare(b.name));
  764. return metrics;
  765. }
  766. function configureServer(server) {
  767. const _invalidateModule = server.moduleGraph.invalidateModule;
  768. server.moduleGraph.invalidateModule = function(...args) {
  769. const mod = args[0];
  770. if (mod?.id) {
  771. delete transformMap[mod.id];
  772. delete transformMapSSR[mod.id];
  773. }
  774. return _invalidateModule.apply(this, args);
  775. };
  776. const base = (options.base ?? server.config.base) || "/";
  777. server.middlewares.use(`${base}__inspect`, sirv(DIR_CLIENT, {
  778. single: true,
  779. dev: true
  780. }));
  781. const rpcFunctions = {
  782. list,
  783. getIdInfo,
  784. getPluginMetrics,
  785. resolveId,
  786. clear: clearId
  787. };
  788. createRPCServer("vite-plugin-inspect", server.ws, rpcFunctions);
  789. async function getIdInfo(id, ssr = false, clear = false) {
  790. if (clear) {
  791. clearId(id, ssr);
  792. try {
  793. await server.transformRequest(id, { ssr });
  794. } catch {
  795. }
  796. }
  797. const resolvedId = resolveId(id, ssr);
  798. const map = ssr ? transformMapSSR : transformMap;
  799. return {
  800. resolvedId,
  801. transforms: map[resolvedId] || []
  802. };
  803. }
  804. function getModulesInfo(map) {
  805. return Object.keys(map).sort().map((id) => {
  806. const plugins = map[id]?.map((i) => i.name);
  807. const deps = Array.from(server.moduleGraph.getModuleById(id)?.importedModules || []).map((i) => i.id || "").filter(Boolean);
  808. return {
  809. id,
  810. plugins,
  811. deps,
  812. virtual: plugins[0] !== dummyLoadPluginName
  813. };
  814. });
  815. }
  816. function list() {
  817. return {
  818. root: config.root,
  819. modules: getModulesInfo(transformMap),
  820. ssrModules: getModulesInfo(transformMapSSR)
  821. };
  822. }
  823. function clearId(_id, ssr = false) {
  824. const id = resolveId(_id);
  825. if (id) {
  826. const mod = server.moduleGraph.getModuleById(id);
  827. if (mod)
  828. server.moduleGraph.invalidateModule(mod);
  829. const map = ssr ? transformMapSSR : transformMap;
  830. delete map[id];
  831. }
  832. }
  833. const _print = server.printUrls;
  834. server.printUrls = () => {
  835. const colorUrl = (url2) => green(url2.replace(/:(\d+)\//, (_, port) => `:${bold(port)}/`));
  836. let host = `${config.server.https ? "https" : "http"}://localhost:${config.server.port || "80"}`;
  837. const url = server.resolvedUrls?.local[0];
  838. if (url) {
  839. try {
  840. const u = new URL(url);
  841. host = `${u.protocol}//${u.host}`;
  842. } catch (error) {
  843. console.warn("Parse resolved url failed:", error);
  844. }
  845. }
  846. _print();
  847. console.log(` ${green("\u279C")} ${bold("Inspect")}: ${colorUrl(`${host}${base}__inspect/`)}`);
  848. };
  849. return rpcFunctions;
  850. }
  851. async function generateBuild() {
  852. const targetDir = join(config.root, outputDir);
  853. const reportsDir = join(targetDir, "reports");
  854. await fs.mkdir(targetDir, { recursive: true });
  855. await fs.copy(DIR_CLIENT, targetDir, { overwrite: true });
  856. await fs.writeFile(
  857. join(targetDir, "index.html"),
  858. (await fs.readFile(join(targetDir, "index.html"), "utf-8")).replace(
  859. 'data-vite-inspect-mode="DEV"',
  860. 'data-vite-inspect-mode="BUILD"'
  861. )
  862. );
  863. await fs.rm(reportsDir, {
  864. recursive: true,
  865. force: true
  866. });
  867. await fs.mkdir(reportsDir, { recursive: true });
  868. function getModulesInfo(map) {
  869. return Object.keys(map).sort().map((id) => {
  870. const plugins = map[id]?.map((i) => i.name);
  871. return {
  872. id,
  873. deps: [],
  874. plugins,
  875. virtual: plugins[0] !== dummyLoadPluginName && map[id][0].name !== "vite:load-fallback"
  876. };
  877. });
  878. }
  879. function list() {
  880. return {
  881. root: config.root,
  882. modules: getModulesInfo(transformMap),
  883. ssrModules: getModulesInfo(transformMapSSR)
  884. };
  885. }
  886. await fs.writeFile(
  887. join(reportsDir, "list.json"),
  888. JSON.stringify(list(), null, 2),
  889. "utf-8"
  890. );
  891. await fs.writeFile(
  892. join(reportsDir, "metrics.json"),
  893. JSON.stringify(getPluginMetrics(false), null, 2),
  894. "utf-8"
  895. );
  896. await fs.writeFile(
  897. join(reportsDir, "metrics-ssr.json"),
  898. JSON.stringify(getPluginMetrics(true), null, 2),
  899. "utf-8"
  900. );
  901. async function dumpModuleInfo(dir, map, ssr = false) {
  902. await fs.ensureDir(dir);
  903. return Promise.all(
  904. Object.entries(map).map(
  905. ([id, info]) => fs.writeJSON(
  906. join(dir, `${hash(id)}.json`),
  907. {
  908. resolvedId: resolveId(id, ssr),
  909. transforms: info
  910. }
  911. )
  912. )
  913. );
  914. }
  915. await dumpModuleInfo(join(reportsDir, "transform"), transformMap);
  916. await dumpModuleInfo(join(reportsDir, "transform-ssr"), transformMapSSR, true);
  917. return targetDir;
  918. }
  919. const plugin = {
  920. name: NAME,
  921. enforce: "pre",
  922. apply(_, { command }) {
  923. if (command === "serve" && dev)
  924. return true;
  925. if (command === "build" && build)
  926. return true;
  927. return false;
  928. },
  929. configResolved(_config) {
  930. config = _config;
  931. config.plugins.forEach(hijackPlugin);
  932. const _createResolver = config.createResolver;
  933. config.createResolver = function(...args) {
  934. const _resolver = _createResolver.apply(this, args);
  935. return async function(...args2) {
  936. const id = args2[0];
  937. const aliasOnly = args2[2];
  938. const ssr = args2[3];
  939. const start = Date.now();
  940. const result = await _resolver.apply(this, args2);
  941. const end = Date.now();
  942. const map = ssr ? idMapSSR : idMap;
  943. if (result && result !== id) {
  944. const pluginName = aliasOnly ? "alias" : "vite:resolve (+alias)";
  945. if (!map[id])
  946. map[id] = [];
  947. map[id].push({ name: pluginName, result, start, end });
  948. }
  949. return result;
  950. };
  951. };
  952. },
  953. configureServer(server) {
  954. const rpc = configureServer(server);
  955. plugin.api = {
  956. rpc
  957. };
  958. },
  959. load: {
  960. order: "pre",
  961. handler(id, { ssr } = {}) {
  962. const map = ssr ? transformMapSSR : transformMap;
  963. delete map[id];
  964. return null;
  965. }
  966. },
  967. handleHotUpdate({ modules, server }) {
  968. const ids = modules.map((module) => module.id);
  969. server.ws.send({
  970. type: "custom",
  971. event: "vite-plugin-inspect:update",
  972. data: { ids }
  973. });
  974. },
  975. async buildEnd() {
  976. if (!build)
  977. return;
  978. const dir = await generateBuild();
  979. console.log(green("Inspect report generated at"), dim(`${dir}`));
  980. }
  981. };
  982. return plugin;
  983. }
  984. PluginInspect.getViteInspectAPI = function(plugins) {
  985. return plugins.find((p) => p.name === NAME)?.api;
  986. };
  987. export { PluginInspect as default };