speed-measure-vite-plugin
Version:
Measures your vite plugin transform speed
154 lines (149 loc) • 4.9 kB
JavaScript
;
var decorateVitePlugin = require('decorate-vite-plugin');
var node_perf_hooks = require('node:perf_hooks');
function log(text) {
return console.log(`${text}`);
}
function colorGreen(s) {
return `\x1B[32m${s}\x1B[0m`;
}
function colorPrimary(s) {
return `\x1B[38;2;124;102;255m${s}\x1B[0m`;
}
function speedMeasureWrap(plugins, {
hooks = ["transform"],
sort = (a, b) => b - a,
maxGapTimeOnce = 1e3,
maxTransformTimeOnce
} = {}) {
let statsMap = /* @__PURE__ */ new Map();
let lastTransformRunAt = null;
let interval = null;
const gapTimeOnce = maxGapTimeOnce || maxTransformTimeOnce;
function checkProcessDone() {
if (lastTransformRunAt && lastTransformRunAt < node_perf_hooks.performance.now() - gapTimeOnce) {
printResults(statsMap, sort);
statsMap = /* @__PURE__ */ new Map();
}
}
function printResults(statsMap2, sort2) {
if (statsMap2.size === 0) {
return;
}
log(colorPrimary("[SMVP]"));
const pluginTotals = /* @__PURE__ */ new Map();
let allPluginsTotal = 0;
statsMap2.forEach((hookStats, pluginName) => {
let pluginTotal = 0;
hookStats.forEach((stats) => {
pluginTotal += stats.total;
});
pluginTotals.set(pluginName, pluginTotal);
allPluginsTotal += pluginTotal;
});
const pluginEntries = Array.from(pluginTotals.entries());
if (typeof sort2 === "function") {
pluginEntries.sort((a, b) => sort2(a[1], b[1]));
}
pluginEntries.forEach(([pluginName, pluginTotal], index) => {
if (index > 0) {
log("");
}
log(`${pluginName}: ${colorGreen(`${pluginTotal / 1e3}s`)}`);
const hookStats = statsMap2.get(pluginName);
if (!hookStats || hookStats.size === 0) return;
let maxHookNameLength = 0;
hookStats.forEach((_, hookName) => {
maxHookNameLength = Math.max(maxHookNameLength, hookName.length);
});
const table = [];
hookStats.forEach((stats, hookName) => {
const { total, parallel } = stats;
table.push({
hookName,
total,
parallel,
totalS: `${total / 1e3}s`,
parallelS: `${parallel / 1e3}s`
});
});
if (typeof sort2 === "function") {
table.sort((a, b) => sort2(a.total, b.total));
}
table.forEach(({ hookName, totalS, parallelS }) => {
const paddedHookName = hookName.padEnd(maxHookNameLength, " ");
log(` ${paddedHookName} Total: ${colorGreen(totalS)} Parallel: ${colorGreen(parallelS)}`);
});
});
log(colorPrimary(`All plugins total time: ${allPluginsTotal / 1e3}s`));
}
const createHookDecorator = (hookName) => {
return (originalHook, plugin) => {
if (typeof originalHook !== "function") {
return originalHook;
}
const name = plugin.name || `unnamed_${Math.random().toString(36).substring(2, 15)}`;
return function decoratedHook(...args) {
if (!interval) {
interval = setInterval(checkProcessDone, 1e3);
}
let pluginStats = statsMap.get(name);
if (!pluginStats) {
pluginStats = /* @__PURE__ */ new Map();
statsMap.set(name, pluginStats);
}
let hookStats = pluginStats.get(hookName);
if (!hookStats) {
hookStats = {
total: 0,
parallel: 0,
runAt: 0,
runCount: 0
};
pluginStats.set(hookName, hookStats);
}
hookStats.runCount++;
const startAt = node_perf_hooks.performance.now();
if (hookName === "transform") {
lastTransformRunAt = startAt;
}
if (hookStats.runAt === 0) {
hookStats.runAt = startAt;
}
const res = originalHook.apply(this, args);
function writeTime() {
if (!hookStats) return;
const endAt = node_perf_hooks.performance.now();
hookStats.total += endAt - startAt;
hookStats.runCount--;
if (hookStats.runCount === 0) {
hookStats.parallel += endAt - hookStats.runAt;
hookStats.runAt = 0;
}
}
if (res instanceof Promise) {
res.then(writeTime);
} else {
writeTime();
}
return res;
};
};
};
let wrappedPlugins = plugins;
hooks.forEach((hookName) => {
wrappedPlugins = decorateVitePlugin.decorateVitePluginOption(wrappedPlugins, hookName, createHookDecorator(hookName));
});
const closeBundlePlugin = {
name: "smvp:closeBundleWatcher",
closeBundle: () => {
printResults(statsMap, sort);
if (interval) {
clearInterval(interval);
interval = null;
}
}
};
return Array.isArray(wrappedPlugins) ? [...wrappedPlugins, closeBundlePlugin] : [wrappedPlugins, closeBundlePlugin];
}
module.exports = speedMeasureWrap;