@nx/eslint
Version:
145 lines (144 loc) • 7.56 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertToFlatConfigGenerator = convertToFlatConfigGenerator;
const devkit_1 = require("@nx/devkit");
const eslint_file_1 = require("../utils/eslint-file");
const path_1 = require("path");
const versions_1 = require("../../utils/versions");
const json_converter_1 = require("./converters/json-converter");
async function convertToFlatConfigGenerator(tree, options) {
const eslintFile = (0, eslint_file_1.findEslintFile)(tree);
if (!eslintFile) {
throw new Error('Could not find root eslint file');
}
if (eslintFile.endsWith('.js')) {
throw new Error('Only json and yaml eslint config files are supported for conversion');
}
options.eslintConfigFormat ??= 'mjs';
const eslintIgnoreFiles = new Set(['.eslintignore']);
// convert root eslint config to eslint.config.cjs or eslint.base.config.mjs based on eslintConfigFormat
convertRootToFlatConfig(tree, eslintFile, options.eslintConfigFormat);
// convert project eslint files to eslint.config.cjs
const projects = (0, devkit_1.getProjects)(tree);
for (const [project, projectConfig] of projects) {
convertProjectToFlatConfig(tree, project, projectConfig, (0, devkit_1.readNxJson)(tree), eslintIgnoreFiles, options.eslintConfigFormat);
}
// delete all .eslintignore files
for (const ignoreFile of eslintIgnoreFiles) {
tree.delete(ignoreFile);
}
// replace references in nx.json
updateNxJsonConfig(tree, options.eslintConfigFormat);
// install missing packages
if (!options.skipFormat) {
await (0, devkit_1.formatFiles)(tree);
}
return () => (0, devkit_1.installPackagesTask)(tree);
}
exports.default = convertToFlatConfigGenerator;
function convertRootToFlatConfig(tree, eslintFile, format) {
if (/\.base\.(js|json|yml|yaml)$/.test(eslintFile)) {
convertConfigToFlatConfig(tree, '', eslintFile, `eslint.base.config.${format}`, format);
}
convertConfigToFlatConfig(tree, '', eslintFile.replace('.base.', '.'), `eslint.config.${format}`, format);
}
function convertProjectToFlatConfig(tree, project, projectConfig, nxJson, eslintIgnoreFiles, format) {
const eslintFile = (0, eslint_file_1.findEslintFile)(tree, projectConfig.root);
if (eslintFile && !eslintFile.endsWith('.js')) {
if (projectConfig.targets) {
const eslintTargets = Object.keys(projectConfig.targets || {}).filter((t) => projectConfig.targets[t].executor === '@nx/eslint:lint' ||
projectConfig.targets[t].command?.includes('eslint'));
let ignorePath;
for (const target of eslintTargets) {
// remove any obsolete `eslintConfig` options pointing to the old config file
if (projectConfig.targets[target].options?.eslintConfig) {
delete projectConfig.targets[target].options.eslintConfig;
}
if (projectConfig.targets[target].options?.ignorePath) {
ignorePath = projectConfig.targets[target].options.ignorePath;
delete projectConfig.targets[target].options.ignorePath;
}
(0, devkit_1.updateProjectConfiguration)(tree, project, projectConfig);
}
const nxHasEsLintTargets = Object.keys(nxJson.targetDefaults || {}).some((t) => (t === '@nx/eslint:lint' ||
nxJson.targetDefaults[t].executor === '@nx/eslint:lint' ||
nxJson.targetDefaults[t].command?.includes('eslint')) &&
projectConfig.targets?.[t]);
const nxHasEsLintPlugin = (nxJson.plugins || []).some((p) => typeof p === 'string'
? p === '@nx/eslint/plugin'
: p.plugin === '@nx/eslint/plugin');
if (nxHasEsLintTargets || nxHasEsLintPlugin || eslintTargets.length > 0) {
convertConfigToFlatConfig(tree, projectConfig.root, eslintFile, `eslint.config.${format}`, format, ignorePath);
eslintIgnoreFiles.add(`${projectConfig.root}/.eslintignore`);
if (ignorePath) {
eslintIgnoreFiles.add(ignorePath);
}
}
}
}
}
// update names of eslint files in nx.json
// and remove eslintignore
function updateNxJsonConfig(tree, format) {
if (tree.exists('nx.json')) {
(0, devkit_1.updateJson)(tree, 'nx.json', (json) => {
if (json.targetDefaults?.lint?.inputs) {
const inputSet = new Set(json.targetDefaults.lint.inputs);
inputSet.add(`{workspaceRoot}/eslint.config.${format}`);
json.targetDefaults.lint.inputs = Array.from(inputSet);
}
if (json.targetDefaults?.['@nx/eslint:lint']?.inputs) {
const inputSet = new Set(json.targetDefaults['@nx/eslint:lint'].inputs);
inputSet.add(`{workspaceRoot}/eslint.config.${format}`);
json.targetDefaults['@nx/eslint:lint'].inputs = Array.from(inputSet);
}
if (json.namedInputs?.production) {
const inputSet = new Set(json.namedInputs.production);
inputSet.add(`!{projectRoot}/eslint.config.${format}`);
json.namedInputs.production = Array.from(inputSet);
}
return json;
});
}
}
function convertConfigToFlatConfig(tree, root, source, target, format, ignorePath) {
const ignorePaths = ignorePath
? [ignorePath, `${root}/.eslintignore`]
: [`${root}/.eslintignore`];
if (source.endsWith('.json')) {
const config = (0, devkit_1.readJson)(tree, `${root}/${source}`);
const conversionResult = (0, json_converter_1.convertEslintJsonToFlatConfig)(tree, root, config, ignorePaths, format);
return processConvertedConfig(tree, root, source, target, conversionResult);
}
if (source.endsWith('.yaml') || source.endsWith('.yml')) {
const originalContent = tree.read(`${root}/${source}`, 'utf-8');
const { load } = require('@zkochan/js-yaml');
const config = load(originalContent, {
json: true,
filename: source,
});
const conversionResult = (0, json_converter_1.convertEslintJsonToFlatConfig)(tree, root, config, ignorePaths, format);
return processConvertedConfig(tree, root, source, target, conversionResult);
}
}
function processConvertedConfig(tree, root, source, target, { content, addESLintRC, addESLintJS, }) {
// remove original config file
tree.delete((0, path_1.join)(root, source));
// save new
tree.write((0, path_1.join)(root, target), content);
// These dependencies are required for flat configs that are generated by subsequent app/lib generators.
const devDependencies = {
eslint: versions_1.eslint9__eslintVersion,
'eslint-config-prettier': versions_1.eslintConfigPrettierVersion,
'typescript-eslint': versions_1.eslint9__typescriptESLintVersion,
};
// add missing packages
if (addESLintRC) {
devDependencies['@eslint/eslintrc'] = versions_1.eslintrcVersion;
}
if (addESLintJS) {
devDependencies['@eslint/js'] = versions_1.eslintVersion;
}
(0, devkit_1.addDependenciesToPackageJson)(tree, {}, devDependencies);
(0, devkit_1.removeDependenciesFromPackageJson)(tree, ['@typescript-eslint/eslint-plugin', '@typescript-eslint/parser'], ['@typescript-eslint/eslint-plugin', '@typescript-eslint/parser']);
}
;