vite-plugin-dts-build
Version:
A Vite plugin that runs TypeScript build process in a separate worker thread for better performance and efficient incremental builds
105 lines (104 loc) • 2.92 kB
JavaScript
import { Worker } from "node:worker_threads";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { performance } from "node:perf_hooks";
let _dirname, _filename;
let _workerName;
if (typeof import.meta !== "undefined") {
_filename = fileURLToPath(import.meta.url);
_dirname = dirname(_filename);
_workerName = "worker.js";
} else {
_dirname = __dirname;
_filename = __filename;
_workerName = "worker.cjs";
}
function createWorker(options) {
return new Worker(join(_dirname, _workerName), {
workerData: options
});
}
function waitBuildInWorker(worker, startTime) {
return new Promise((resolve, reject) => {
worker.once("message", (message) => {
printMessage(`Declaration files built in ${measureTime(startTime)}ms.`);
worker.removeAllListeners();
resolve(message);
});
worker.once("error", (err) => {
reject(err);
});
worker.once("exit", (code) => {
reject(new Error(`Worker stopped with exit code ${code}`));
});
});
}
function waitCopyInWorker(worker, afterBuild) {
return new Promise((resolve, reject) => {
worker?.once("error", (err) => {
reject(err);
});
worker?.on("exit", async () => {
printMessage("Copy files completed.");
Promise.resolve(afterBuild()).then(() => resolve());
});
});
}
function measureTime(startTime) {
const elapsed = performance.now() - startTime;
const duration = Math.round(elapsed);
return duration;
}
function printMessage(message) {
const cyan = "\x1B[36m";
const green = "\x1B[32m";
const reset = "\x1B[0m";
console.log(`${cyan}[vite-tsc-build] ${green}${message}${reset}`);
}
function noop() {
}
function dts(options = {}) {
const { afterBuild = noop, ...workerOptions } = options;
let workerInstance;
const runState = {
hasStartRun: false,
canWriteRun: false
};
return {
name: "vite-plugin-dts-build",
enforce: "pre",
apply: "build",
async buildStart() {
if (runState.hasStartRun) {
return;
}
runState.hasStartRun = true;
const startTime = performance.now();
printMessage("Starting TypeScript build...");
workerInstance = createWorker(workerOptions);
const result = await waitBuildInWorker(workerInstance, startTime);
if (result === "build-end") {
runState.canWriteRun = true;
}
},
async writeBundle() {
if (!runState.canWriteRun || workerInstance === void 0) {
return;
}
runState.canWriteRun = false;
printMessage("Starting Copy files...");
workerInstance?.postMessage("copy-start");
await waitCopyInWorker(workerInstance, afterBuild);
workerInstance = void 0;
},
watchChange(_id, change) {
if (change.event === "update") {
runState.hasStartRun = false;
runState.canWriteRun = false;
}
}
};
}
export {
dts
};