nx/packages/vue/src/utils/add-linting.ts
Jack Hsu 769974b45a
feat(vue): init, app, component and lib generators (#19130)
Co-authored-by: Katerina Skroumpelou <sk.katherine@gmail.com>
2023-09-13 15:05:10 -04:00

150 lines
4.1 KiB
TypeScript

import { Tree } from 'nx/src/generators/tree';
import { Linter, lintProjectGenerator } from '@nx/linter';
import { joinPathFragments } from 'nx/src/utils/path';
import {
addDependenciesToPackageJson,
runTasksInSerial,
updateJson,
} from '@nx/devkit';
import { extraEslintDependencies } from './lint';
import {
addExtendsToLintConfig,
isEslintConfigSupported,
} from '@nx/linter/src/generators/utils/eslint-file';
export async function addLinting(
host: Tree,
options: {
linter: Linter;
name: string;
projectRoot: string;
unitTestRunner?: 'jest' | 'vitest' | 'none';
setParserOptionsProject?: boolean;
skipPackageJson?: boolean;
rootProject?: boolean;
},
projectType: 'lib' | 'app'
) {
if (options.linter === Linter.EsLint) {
const lintTask = await lintProjectGenerator(host, {
linter: options.linter,
project: options.name,
tsConfigPaths: [
joinPathFragments(options.projectRoot, `tsconfig.${projectType}.json`),
],
unitTestRunner: options.unitTestRunner,
eslintFilePatterns: [`${options.projectRoot}/**/*.{ts,tsx,js,jsx,vue}`],
skipFormat: true,
setParserOptionsProject: options.setParserOptionsProject,
rootProject: options.rootProject,
});
if (isEslintConfigSupported(host)) {
addExtendsToLintConfig(host, options.projectRoot, [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-typescript',
'@vue/eslint-config-prettier/skip-formatting',
]);
}
editEslintConfigFiles(host, options.projectRoot, options.rootProject);
let installTask = () => {};
if (!options.skipPackageJson) {
installTask = addDependenciesToPackageJson(
host,
extraEslintDependencies.dependencies,
extraEslintDependencies.devDependencies
);
}
return runTasksInSerial(lintTask, installTask);
} else {
return () => {};
}
}
function editEslintConfigFiles(
tree: Tree,
projectRoot: string,
rootProject?: boolean
) {
if (tree.exists(joinPathFragments(projectRoot, 'eslint.config.js'))) {
const fileName = joinPathFragments(projectRoot, 'eslint.config.js');
updateJson(tree, fileName, (json) => {
let updated = false;
for (let override of json.overrides) {
if (override.parserOptions) {
if (!override.files.includes('*.vue')) {
override.files.push('*.vue');
}
updated = true;
}
}
if (!updated) {
json.overrides = [
{
files: ['*.ts', '*.tsx', '*.js', '*.jsx', '*.vue'],
rules: {},
},
];
}
return json;
});
} else {
const fileName = joinPathFragments(projectRoot, '.eslintrc.json');
updateJson(tree, fileName, (json) => {
let updated = false;
for (let override of json.overrides) {
if (override.parserOptions) {
if (!override.files.includes('*.vue')) {
override.files.push('*.vue');
}
updated = true;
}
}
if (!updated) {
json.overrides = [
{
files: ['*.ts', '*.tsx', '*.js', '*.jsx', '*.vue'],
rules: {},
},
];
}
return json;
});
}
// Edit root config too
if (tree.exists('.eslintrc.base.json')) {
updateJson(tree, '.eslintrc.base.json', (json) => {
for (let override of json.overrides) {
if (
override.rules &&
'@nx/enforce-module-boundaries' in override.rules
) {
if (!override.files.includes('*.vue')) {
override.files.push('*.vue');
}
}
}
return json;
});
} else if (tree.exists('.eslintrc.json') && !rootProject) {
updateJson(tree, '.eslintrc.json', (json) => {
for (let override of json.overrides) {
if (
override.rules &&
'@nx/enforce-module-boundaries' in override.rules
) {
if (!override.files.includes('*.vue')) {
override.files.push('*.vue');
}
}
}
return json;
});
}
}