vite-plugin-eslint2
Version:
ESLint plugin for Vite.
274 lines (256 loc) • 9.02 kB
JavaScript
;
const pluginutils = require('@rollup/pluginutils');
const ESLINT_SEVERITY = {
ERROR: 2,
WARNING: 1
};
const PLUGIN_NAME = "vite:eslint2";
const COLOR_MAPPING = {
error: "red",
warning: "yellow",
plugin: "magenta"
};
function getDefaultExportFromCjs (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
var picocolors = {exports: {}};
var hasRequiredPicocolors;
function requirePicocolors () {
if (hasRequiredPicocolors) return picocolors.exports;
hasRequiredPicocolors = 1;
let p = process || {}, argv = p.argv || [], env = p.env || {};
let isColorSupported =
!(!!env.NO_COLOR || argv.includes("--no-color")) &&
(!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || ((p.stdout || {}).isTTY && env.TERM !== "dumb") || !!env.CI);
let formatter = (open, close, replace = open) =>
input => {
let string = "" + input, index = string.indexOf(close, open.length);
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close
};
let replaceClose = (string, close, replace, index) => {
let result = "", cursor = 0;
do {
result += string.substring(cursor, index) + replace;
cursor = index + close.length;
index = string.indexOf(close, cursor);
} while (~index)
return result + string.substring(cursor)
};
let createColors = (enabled = isColorSupported) => {
let f = enabled ? formatter : () => String;
return {
isColorSupported: enabled,
reset: f("\x1b[0m", "\x1b[0m"),
bold: f("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m"),
dim: f("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m"),
italic: f("\x1b[3m", "\x1b[23m"),
underline: f("\x1b[4m", "\x1b[24m"),
inverse: f("\x1b[7m", "\x1b[27m"),
hidden: f("\x1b[8m", "\x1b[28m"),
strikethrough: f("\x1b[9m", "\x1b[29m"),
black: f("\x1b[30m", "\x1b[39m"),
red: f("\x1b[31m", "\x1b[39m"),
green: f("\x1b[32m", "\x1b[39m"),
yellow: f("\x1b[33m", "\x1b[39m"),
blue: f("\x1b[34m", "\x1b[39m"),
magenta: f("\x1b[35m", "\x1b[39m"),
cyan: f("\x1b[36m", "\x1b[39m"),
white: f("\x1b[37m", "\x1b[39m"),
gray: f("\x1b[90m", "\x1b[39m"),
bgBlack: f("\x1b[40m", "\x1b[49m"),
bgRed: f("\x1b[41m", "\x1b[49m"),
bgGreen: f("\x1b[42m", "\x1b[49m"),
bgYellow: f("\x1b[43m", "\x1b[49m"),
bgBlue: f("\x1b[44m", "\x1b[49m"),
bgMagenta: f("\x1b[45m", "\x1b[49m"),
bgCyan: f("\x1b[46m", "\x1b[49m"),
bgWhite: f("\x1b[47m", "\x1b[49m"),
blackBright: f("\x1b[90m", "\x1b[39m"),
redBright: f("\x1b[91m", "\x1b[39m"),
greenBright: f("\x1b[92m", "\x1b[39m"),
yellowBright: f("\x1b[93m", "\x1b[39m"),
blueBright: f("\x1b[94m", "\x1b[39m"),
magentaBright: f("\x1b[95m", "\x1b[39m"),
cyanBright: f("\x1b[96m", "\x1b[39m"),
whiteBright: f("\x1b[97m", "\x1b[39m"),
bgBlackBright: f("\x1b[100m", "\x1b[49m"),
bgRedBright: f("\x1b[101m", "\x1b[49m"),
bgGreenBright: f("\x1b[102m", "\x1b[49m"),
bgYellowBright: f("\x1b[103m", "\x1b[49m"),
bgBlueBright: f("\x1b[104m", "\x1b[49m"),
bgMagentaBright: f("\x1b[105m", "\x1b[49m"),
bgCyanBright: f("\x1b[106m", "\x1b[49m"),
bgWhiteBright: f("\x1b[107m", "\x1b[49m"),
}
};
picocolors.exports = createColors();
picocolors.exports.createColors = createColors;
return picocolors.exports;
}
var picocolorsExports = /*@__PURE__*/ requirePicocolors();
const pico = /*@__PURE__*/getDefaultExportFromCjs(picocolorsExports);
function interopDefault(m) {
return m.default || m;
}
const getOptions = ({
test,
dev,
build,
cache,
include,
exclude,
eslintPath,
formatter,
lintInWorker,
lintOnStart,
lintDirtyOnly,
emitError,
emitErrorAsWarning,
emitWarning,
emitWarningAsError,
...eslintConstructorOptions
}) => ({
test: test ?? false,
dev: dev ?? true,
build: build ?? false,
cache: cache ?? true,
include: include ?? ["src/**/*.{js,jsx,ts,tsx,vue,svelte}"],
exclude: exclude ?? ["node_modules", "virtual:"],
eslintPath: eslintPath ?? "eslint",
formatter: formatter ?? "stylish",
lintInWorker: lintInWorker ?? false,
lintOnStart: lintOnStart ?? false,
lintDirtyOnly: lintDirtyOnly ?? true,
emitError: emitError ?? true,
emitErrorAsWarning: emitErrorAsWarning ?? false,
emitWarning: emitWarning ?? true,
emitWarningAsError: emitWarningAsError ?? false,
...eslintConstructorOptions
});
const getFilter = (options) => pluginutils.createFilter(options.include, options.exclude);
const getESLintConstructorOptions = (options) => ({
...Object.fromEntries(
Object.entries(options).filter(
([key]) => ![
"test",
"dev",
"build",
"include",
"exclude",
"eslintPath",
"formatter",
"lintInWorker",
"lintOnStart",
"lintDirtyOnly",
"emitError",
"emitErrorAsWarning",
"emitWarning",
"emitWarningAsError"
].includes(key)
)
),
errorOnUnmatchedPattern: false
});
const initializeESLint = async (options) => {
const { eslintPath, formatter } = options;
try {
const _module = await import(eslintPath);
const module = interopDefault(_module);
const ESLintClass = module.loadESLint ? await module.loadESLint() : module.ESLint || module.FlatESLint || module.LegacyESLint;
const eslintInstance = new ESLintClass(
getESLintConstructorOptions(options)
);
const loadedFormatter = await eslintInstance.loadFormatter(formatter);
const outputFixes = ESLintClass.outputFixes.bind(
ESLintClass
);
return {
eslintInstance,
formatter: loadedFormatter,
outputFixes
};
} catch (error) {
throw new Error(
`Failed to initialize ESLint. Have you installed and configured correctly? ${error}`
);
}
};
const isVirtualModule = (id) => id.startsWith("virtual:") || id[0] === "\0" || !id.includes("/");
const getFilePath = (id) => pluginutils.normalizePath(id).split("?")[0];
const shouldIgnoreModule = async (id, filter, eslintInstance) => {
if (isVirtualModule(id)) return true;
if (!filter(id)) return true;
const filePath = getFilePath(id);
if ([".vue", ".svelte"].some((extname) => filePath.endsWith(extname)) && id.includes("?") && id.includes("type=style")) {
return true;
}
if (eslintInstance) return await eslintInstance.isPathIgnored(filePath);
return false;
};
const removeESLintErrorResults = (results) => results.map((result) => {
const filteredMessages = result.messages.filter(
(message) => message.severity !== ESLINT_SEVERITY.ERROR
);
const filteredSuppressedMessages = result.suppressedMessages.filter(
(message) => message.severity !== ESLINT_SEVERITY.ERROR
);
return {
...result,
messages: filteredMessages,
suppressedMessages: filteredSuppressedMessages,
errorCount: 0,
fatalErrorCount: 0,
fixableErrorCount: 0
};
});
const removeESLintWarningResults = (results) => results.map((result) => {
const filteredMessages = result.messages.filter(
(message) => message.severity !== ESLINT_SEVERITY.WARNING
);
const filteredSuppressedMessages = result.suppressedMessages.filter(
(message) => message.severity !== ESLINT_SEVERITY.WARNING
);
return {
...result,
messages: filteredMessages,
suppressedMessages: filteredSuppressedMessages,
warningCount: 0,
fixableWarningCount: 0
};
});
const filterESLintLintResults = (results) => results.filter((result) => result.errorCount > 0 || result.warningCount > 0);
const colorize = (text, textType) => pico[COLOR_MAPPING[textType]](text);
const log = (text, textType, context) => {
console.log("");
if (context) {
if (textType === "error") context.error(text);
else if (textType === "warning") context.warn(text);
} else {
console.log(`${text} Plugin: ${colorize(PLUGIN_NAME, "plugin")}\r
`);
}
};
const lintFiles = async ({ files, eslintInstance, formatter, outputFixes, options }, context) => await eslintInstance.lintFiles(files).then(async (lintResults) => {
if (!lintResults || lintResults.length === 0) return;
if (options.fix) outputFixes(lintResults);
let results = [...lintResults];
if (!options.emitError) results = removeESLintErrorResults(results);
if (!options.emitWarning) results = removeESLintWarningResults(results);
results = filterESLintLintResults(results);
if (results.length === 0) return;
const formattedText = await formatter.format(results);
let formattedTextType;
if (results.some((result) => result.errorCount > 0)) {
formattedTextType = options.emitErrorAsWarning ? "warning" : "error";
} else {
formattedTextType = options.emitWarningAsError ? "error" : "warning";
}
return log(formattedText, formattedTextType, context);
});
exports.PLUGIN_NAME = PLUGIN_NAME;
exports.getFilePath = getFilePath;
exports.getFilter = getFilter;
exports.getOptions = getOptions;
exports.initializeESLint = initializeESLint;
exports.lintFiles = lintFiles;
exports.shouldIgnoreModule = shouldIgnoreModule;