vite-plugin-linter
Version:
Plugin for linting files with Vite
98 lines (95 loc) • 3.1 kB
JavaScript
import { fileURLToPath } from 'url';
import { resolveConfig } from 'vite';
import { workerData, parentPort, Worker } from 'worker_threads';
function createWorkerThreads(command, pluginName, linters) {
let workersByLinterName = {};
for (const linter of linters) {
const data = {
command,
linterName: linter.name,
pluginName,
workingDirectory: process.cwd()
};
workersByLinterName[linter.name] = new Worker(
fileURLToPath(import.meta.url),
{ workerData: data }
);
}
return workersByLinterName;
}
async function init(data) {
const config = await resolveConfig(
{ root: data.workingDirectory },
data.command
);
const plugin = config.plugins.find((p) => p.name === data.pluginName);
if (!plugin) {
throw new Error(`Could not find plugin ${data.pluginName}`);
}
const linter = plugin.getLinter(data.linterName);
if (!linter) {
throw new Error(`Could not find linter ${data.linterName}`);
}
parentPort.on("message", async (files) => {
switch (data.command) {
case "build":
const buildResult = await linter.lintBuild(files);
const buildMessage = {
files,
linterName: data.linterName,
result: { build: buildResult }
};
const functions = removeFunctionsFromObject(buildMessage);
parentPort.postMessage(buildMessage);
restoreFunctionsToObject(buildMessage, functions);
break;
case "serve":
linter.lintServe(files, (serveResult) => {
if (serveResult) {
const serveMessage = {
files,
linterName: data.linterName,
result: { serve: serveResult }
};
const functions2 = removeFunctionsFromObject(serveMessage);
parentPort.postMessage(serveMessage);
restoreFunctionsToObject(serveMessage, functions2);
}
});
break;
default:
throw new Error(`Uknown command ${data.command}`);
}
});
}
function removeFunctionsFromObject(object, maxDepth = 10) {
const record = object;
const functions = [];
for (const key of Object.keys(record)) {
if (typeof record[key] === "function") {
functions.push({ function: record[key], key, source: record });
delete record[key];
} else if (typeof record[key] === typeof object && record[key] !== null && maxDepth > 0) {
functions.push(
...removeFunctionsFromObject(record[key], maxDepth - 1)
);
}
}
return functions;
}
function restoreFunctionsToObject(object, functions, maxDepth = 10) {
const record = object;
const functionInfos = functions.filter((f) => f.source === record);
for (const functionInfo of functionInfos) {
record[functionInfo.key] = functionInfo.function;
}
for (const key of Object.keys(record)) {
if (typeof record[key] === typeof object && record[key] !== null && maxDepth > 0) {
restoreFunctionsToObject(record[key], functions, maxDepth - 1);
}
}
}
if (workerData) {
init(workerData);
}
export { createWorkerThreads };