fix(linter): add jest to root .eslintrc if selected as unit test runner (#11555)
This commit is contained in:
parent
99a3563c8f
commit
187f5200c0
@ -12,6 +12,7 @@ export async function addLintingGenerator(
|
||||
): Promise<GeneratorCallback> {
|
||||
const installTask = lintInitGenerator(tree, {
|
||||
linter: Linter.EsLint,
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
skipPackageJson: options.skipPackageJson,
|
||||
});
|
||||
|
||||
|
||||
@ -5,4 +5,5 @@ export interface AddLintingGeneratorSchema {
|
||||
setParserOptionsProject?: boolean;
|
||||
skipFormat?: boolean;
|
||||
skipPackageJson?: boolean;
|
||||
unitTestRunner?: string;
|
||||
}
|
||||
|
||||
@ -48,6 +48,7 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) {
|
||||
eslintFilePatterns: [
|
||||
joinPathFragments(options.e2eProjectRoot, '**/*.ts'),
|
||||
],
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
skipFormat: true,
|
||||
setParserOptionsProject: options.setParserOptionsProject,
|
||||
skipPackageJson: options.skipPackageJson,
|
||||
|
||||
@ -14,5 +14,6 @@ export async function addLinting(host: Tree, options: NormalizedSchema) {
|
||||
prefix: options.prefix,
|
||||
setParserOptionsProject: options.setParserOptionsProject,
|
||||
skipPackageJson: options.skipPackageJson,
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
});
|
||||
}
|
||||
|
||||
@ -168,6 +168,7 @@ async function addLinting(host: Tree, options: NormalizedSchema) {
|
||||
projectName: options.name,
|
||||
projectRoot: options.projectRoot,
|
||||
prefix: options.prefix,
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
setParserOptionsProject: options.setParserOptionsProject,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -96,7 +96,7 @@ export async function migrateFromAngularCli(
|
||||
createRootKarmaConfig(tree);
|
||||
}
|
||||
if (workspaceCapabilities.eslint) {
|
||||
updateRootEsLintConfig(tree, eslintConfig);
|
||||
updateRootEsLintConfig(tree, eslintConfig, options.unitTestRunner);
|
||||
cleanupEsLintPackages(tree);
|
||||
}
|
||||
|
||||
|
||||
@ -310,6 +310,7 @@ export class E2eMigrator extends ProjectMigrator<SupportedTargets> {
|
||||
project: this.project.name,
|
||||
linter: Linter.EsLint,
|
||||
eslintFilePatterns: [`${this.project.newRoot}/**/*.{js,ts}`],
|
||||
unitTestRunner: this.options.unitTestRunner,
|
||||
tsConfigPaths: [
|
||||
joinPathFragments(this.project.newRoot, 'tsconfig.json'),
|
||||
],
|
||||
|
||||
@ -163,7 +163,8 @@ export function updatePackageJson(tree: Tree): void {
|
||||
|
||||
export function updateRootEsLintConfig(
|
||||
tree: Tree,
|
||||
existingEsLintConfig: any | undefined
|
||||
existingEsLintConfig: any | undefined,
|
||||
unitTestRunner?: string
|
||||
): void {
|
||||
if (tree.exists('.eslintrc.json')) {
|
||||
/**
|
||||
@ -175,7 +176,7 @@ export function updateRootEsLintConfig(
|
||||
tree.delete('.eslintrc.json');
|
||||
}
|
||||
|
||||
lintInitGenerator(tree, { linter: Linter.EsLint });
|
||||
lintInitGenerator(tree, { linter: Linter.EsLint, unitTestRunner });
|
||||
|
||||
if (!existingEsLintConfig) {
|
||||
// There was no eslint config in the root, so we keep the generated one as-is.
|
||||
|
||||
@ -155,6 +155,7 @@ export function addLint(
|
||||
tsConfigPaths: [
|
||||
joinPathFragments(options.projectRoot, 'tsconfig.lib.json'),
|
||||
],
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
eslintFilePatterns: [
|
||||
`${options.projectRoot}/**/*.${options.js ? 'js' : 'ts'}`,
|
||||
],
|
||||
|
||||
@ -16,9 +16,11 @@ import {
|
||||
|
||||
import { Linter } from '../utils/linter';
|
||||
import { containsEslint } from '../utils/eslint-file';
|
||||
import { ESLint } from 'eslint';
|
||||
|
||||
export interface LinterInitOptions {
|
||||
linter?: Linter;
|
||||
unitTestRunner?: string;
|
||||
skipPackageJson?: boolean;
|
||||
}
|
||||
|
||||
@ -86,7 +88,8 @@ const globalTsLintConfiguration = {
|
||||
},
|
||||
};
|
||||
|
||||
const globalEsLintConfiguration = {
|
||||
const getGlobalEsLintConfiguration = (unitTestRunner?: string) => {
|
||||
const config: ESLint.ConfigData = {
|
||||
root: true,
|
||||
ignorePatterns: ['**/*'],
|
||||
plugins: ['@nrwl/nx'],
|
||||
@ -146,6 +149,17 @@ const globalEsLintConfiguration = {
|
||||
rules: {},
|
||||
},
|
||||
],
|
||||
};
|
||||
if (unitTestRunner === 'jest') {
|
||||
config.overrides.push({
|
||||
files: ['*.spec.ts', '*.spec.tsx', '*.spec.js', '*.spec.jsx'],
|
||||
env: {
|
||||
jest: true,
|
||||
},
|
||||
rules: {},
|
||||
});
|
||||
}
|
||||
return config;
|
||||
};
|
||||
|
||||
function initTsLint(tree: Tree, options: LinterInitOptions): GeneratorCallback {
|
||||
@ -175,7 +189,11 @@ function initEsLint(tree: Tree, options: LinterInitOptions): GeneratorCallback {
|
||||
removeDependenciesFromPackageJson(tree, ['@nrwl/linter'], []);
|
||||
}
|
||||
|
||||
writeJson(tree, '.eslintrc.json', globalEsLintConfiguration);
|
||||
writeJson(
|
||||
tree,
|
||||
'.eslintrc.json',
|
||||
getGlobalEsLintConfiguration(options.unitTestRunner)
|
||||
);
|
||||
|
||||
if (tree.exists('.vscode/extensions.json')) {
|
||||
updateJson(tree, '.vscode/extensions.json', (json) => {
|
||||
|
||||
@ -20,6 +20,7 @@ interface LintProjectOptions {
|
||||
skipFormat: boolean;
|
||||
setParserOptionsProject?: boolean;
|
||||
skipPackageJson?: boolean;
|
||||
unitTestRunner?: string;
|
||||
}
|
||||
|
||||
function createTsLintConfiguration(
|
||||
@ -90,6 +91,7 @@ export async function lintProjectGenerator(
|
||||
) {
|
||||
const installTask = lintInitGenerator(tree, {
|
||||
linter: options.linter,
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
skipPackageJson: options.skipPackageJson,
|
||||
});
|
||||
const projectConfig = readProjectConfiguration(tree, options.project);
|
||||
|
||||
@ -20,6 +20,7 @@ export async function addLinting(
|
||||
tsConfigPaths: [
|
||||
joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
|
||||
],
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
eslintFilePatterns: [`${options.appProjectRoot}/**/*.{ts,tsx,js,jsx}`],
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -187,6 +187,7 @@ export async function addLintingToApplication(
|
||||
eslintFilePatterns: [
|
||||
`${options.appProjectRoot}/**/*.${options.js ? 'js' : 'ts'}`,
|
||||
],
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
skipFormat: true,
|
||||
setParserOptionsProject: options.setParserOptionsProject,
|
||||
});
|
||||
|
||||
@ -9,8 +9,8 @@ import {
|
||||
convertNxGenerator,
|
||||
Tree,
|
||||
formatFiles,
|
||||
joinPathFragments,
|
||||
GeneratorCallback,
|
||||
joinPathFragments,
|
||||
} from '@nrwl/devkit';
|
||||
import { normalizeOptions } from './lib/normalize-options';
|
||||
import initGenerator from '../init/init';
|
||||
@ -29,14 +29,14 @@ export async function reactNativeApplicationGenerator(
|
||||
addProject(host, options);
|
||||
|
||||
const initTask = await initGenerator(host, { ...options, skipFormat: true });
|
||||
const lintTask = await addLinting(
|
||||
host,
|
||||
options.projectName,
|
||||
options.appProjectRoot,
|
||||
[joinPathFragments(options.appProjectRoot, 'tsconfig.app.json')],
|
||||
options.linter,
|
||||
options.setParserOptionsProject
|
||||
);
|
||||
const lintTask = await addLinting(host, {
|
||||
...options,
|
||||
projectRoot: options.appProjectRoot,
|
||||
tsConfigPaths: [
|
||||
joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
|
||||
],
|
||||
});
|
||||
|
||||
const jestTask = await addJest(
|
||||
host,
|
||||
options.unitTestRunner,
|
||||
|
||||
@ -44,14 +44,13 @@ export async function reactNativeLibraryGenerator(
|
||||
e2eTestRunner: 'none',
|
||||
});
|
||||
|
||||
const lintTask = await addLinting(
|
||||
host,
|
||||
options.name,
|
||||
options.projectRoot,
|
||||
[joinPathFragments(options.projectRoot, 'tsconfig.lib.json')],
|
||||
options.linter,
|
||||
options.setParserOptionsProject
|
||||
);
|
||||
const lintTask = await addLinting(host, {
|
||||
...options,
|
||||
projectName: options.name,
|
||||
tsConfigPaths: [
|
||||
joinPathFragments(options.projectRoot, 'tsconfig.lib.json'),
|
||||
],
|
||||
});
|
||||
|
||||
if (!options.skipTsConfig) {
|
||||
updateBaseTsConfig(host, options);
|
||||
|
||||
@ -16,13 +16,12 @@ describe('Add Linting', () => {
|
||||
});
|
||||
|
||||
it('should add update `workspace.json` file properly when eslint is passed', () => {
|
||||
addLinting(
|
||||
tree,
|
||||
'my-lib',
|
||||
'libs/my-lib',
|
||||
['libs/my-lib/tsconfig.lib.json'],
|
||||
Linter.EsLint
|
||||
);
|
||||
addLinting(tree, {
|
||||
projectName: 'my-lib',
|
||||
linter: Linter.EsLint,
|
||||
tsConfigPaths: ['libs/my-lib/tsconfig.lib.json'],
|
||||
projectRoot: 'libs/my-lib',
|
||||
});
|
||||
const project = readProjectConfiguration(tree, 'my-lib');
|
||||
|
||||
expect(project.targets.lint).toBeDefined();
|
||||
@ -30,13 +29,12 @@ describe('Add Linting', () => {
|
||||
});
|
||||
|
||||
it('should add update `workspace.json` file properly when tslint is passed', () => {
|
||||
addLinting(
|
||||
tree,
|
||||
'my-lib',
|
||||
'libs/my-lib',
|
||||
['libs/my-lib/tsconfig.lib.json'],
|
||||
Linter.TsLint
|
||||
);
|
||||
addLinting(tree, {
|
||||
projectName: 'my-lib',
|
||||
linter: Linter.TsLint,
|
||||
tsConfigPaths: ['libs/my-lib/tsconfig.lib.json'],
|
||||
projectRoot: 'libs/my-lib',
|
||||
});
|
||||
const project = readProjectConfiguration(tree, 'my-lib');
|
||||
|
||||
expect(project.targets.lint).toBeDefined();
|
||||
@ -46,13 +44,12 @@ describe('Add Linting', () => {
|
||||
});
|
||||
|
||||
it('should not add lint target when "none" is passed', async () => {
|
||||
addLinting(
|
||||
tree,
|
||||
'my-lib',
|
||||
'libs/my-lib',
|
||||
['libs/my-lib/tsconfig.lib.json'],
|
||||
Linter.None
|
||||
);
|
||||
addLinting(tree, {
|
||||
projectName: 'my-lib',
|
||||
linter: Linter.None,
|
||||
tsConfigPaths: ['libs/my-lib/tsconfig.lib.json'],
|
||||
projectRoot: 'libs/my-lib',
|
||||
});
|
||||
const project = readProjectConfiguration(tree, 'my-lib');
|
||||
|
||||
expect(project.targets.lint).toBeUndefined();
|
||||
|
||||
@ -9,38 +9,39 @@ import {
|
||||
import { extraEslintDependencies, createReactEslintJson } from '@nrwl/react';
|
||||
import type { Linter as ESLintLinter } from 'eslint';
|
||||
|
||||
export async function addLinting(
|
||||
host: Tree,
|
||||
projectName: string,
|
||||
appProjectRoot: string,
|
||||
tsConfigPaths: string[],
|
||||
linter: Linter,
|
||||
setParserOptionsProject?: boolean
|
||||
) {
|
||||
if (linter === Linter.None) {
|
||||
interface NormalizedSchema {
|
||||
linter?: Linter;
|
||||
projectName: string;
|
||||
projectRoot: string;
|
||||
setParserOptionsProject?: boolean;
|
||||
tsConfigPaths: string[];
|
||||
}
|
||||
|
||||
export async function addLinting(host: Tree, options: NormalizedSchema) {
|
||||
if (options.linter === Linter.None) {
|
||||
return () => {};
|
||||
}
|
||||
|
||||
const lintTask = await lintProjectGenerator(host, {
|
||||
linter,
|
||||
project: projectName,
|
||||
tsConfigPaths,
|
||||
eslintFilePatterns: [`${appProjectRoot}/**/*.{ts,tsx,js,jsx}`],
|
||||
linter: options.linter,
|
||||
project: options.projectName,
|
||||
tsConfigPaths: options.tsConfigPaths,
|
||||
eslintFilePatterns: [`${options.projectRoot}/**/*.{ts,tsx,js,jsx}`],
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
if (linter === Linter.TsLint) {
|
||||
if (options.linter === Linter.TsLint) {
|
||||
return () => {};
|
||||
}
|
||||
|
||||
const reactEslintJson = createReactEslintJson(
|
||||
appProjectRoot,
|
||||
setParserOptionsProject
|
||||
options.projectRoot,
|
||||
options.setParserOptionsProject
|
||||
);
|
||||
|
||||
updateJson(
|
||||
host,
|
||||
joinPathFragments(appProjectRoot, '.eslintrc.json'),
|
||||
joinPathFragments(options.projectRoot, '.eslintrc.json'),
|
||||
(json: ESLintLinter.Config) => {
|
||||
json = reactEslintJson;
|
||||
json.ignorePatterns = ['!**/*', 'public', '.cache', 'node_modules'];
|
||||
|
||||
@ -35,6 +35,7 @@ async function addLinting(host: Tree, options: NormalizedSchema) {
|
||||
tsConfigPaths: [
|
||||
joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
|
||||
],
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
eslintFilePatterns: [`${options.appProjectRoot}/**/*.{ts,tsx,js,jsx}`],
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -147,6 +147,7 @@ async function addLinting(host: Tree, options: NormalizedSchema) {
|
||||
tsConfigPaths: [
|
||||
joinPathFragments(options.projectRoot, 'tsconfig.lib.json'),
|
||||
],
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
eslintFilePatterns: [`${options.projectRoot}/**/*.{ts,tsx,js,jsx}`],
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -206,6 +206,7 @@ export async function applicationGenerator(host: Tree, schema: Schema) {
|
||||
tsConfigPaths: [
|
||||
joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
|
||||
],
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
eslintFilePatterns: [`${options.appProjectRoot}/**/*.ts`],
|
||||
skipFormat: true,
|
||||
setParserOptionsProject: options.setParserOptionsProject,
|
||||
|
||||
@ -81,6 +81,7 @@ export function addLint(
|
||||
tsConfigPaths: [
|
||||
joinPathFragments(options.projectRoot, 'tsconfig.lib.json'),
|
||||
],
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
eslintFilePatterns: [
|
||||
`${options.projectRoot}/**/*.${options.js ? 'js' : 'ts'}`,
|
||||
],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user