fix(node): fix standalone linter setup (#15681)
This commit is contained in:
parent
e744f0429f
commit
4bf652d2e7
@ -443,68 +443,81 @@ describe('Linter', () => {
|
||||
beforeEach(() => newProject());
|
||||
afterEach(() => cleanupProject());
|
||||
|
||||
function verifySuccessfulStandaloneSetup(myapp: string) {
|
||||
expect(runCLI(`lint ${myapp}`, { silenceError: true })).toContain(
|
||||
'All files pass linting'
|
||||
);
|
||||
expect(runCLI(`lint e2e`, { silenceError: true })).toContain(
|
||||
'All files pass linting'
|
||||
);
|
||||
expect(() => checkFilesExist(`.eslintrc.base.json`)).toThrow();
|
||||
|
||||
const rootEslint = readJson('.eslintrc.json');
|
||||
const e2eEslint = readJson('e2e/.eslintrc.json');
|
||||
|
||||
// should directly refer to nx plugin
|
||||
expect(rootEslint.plugins).toEqual(['@nrwl/nx']);
|
||||
expect(e2eEslint.plugins).toEqual(['@nrwl/nx']);
|
||||
}
|
||||
|
||||
function verifySuccessfulMigratedSetup(myapp: string, mylib: string) {
|
||||
expect(runCLI(`lint ${myapp}`, { silenceError: true })).toContain(
|
||||
'All files pass linting'
|
||||
);
|
||||
expect(runCLI(`lint e2e`, { silenceError: true })).toContain(
|
||||
'All files pass linting'
|
||||
);
|
||||
expect(runCLI(`lint ${mylib}`, { silenceError: true })).toContain(
|
||||
'All files pass linting'
|
||||
);
|
||||
expect(() => checkFilesExist(`.eslintrc.base.json`)).not.toThrow();
|
||||
|
||||
const rootEslint = readJson('.eslintrc.base.json');
|
||||
const appEslint = readJson('.eslintrc.json');
|
||||
const e2eEslint = readJson('e2e/.eslintrc.json');
|
||||
const libEslint = readJson(`libs/${mylib}/.eslintrc.json`);
|
||||
|
||||
// should directly refer to nx plugin
|
||||
expect(rootEslint.plugins).toEqual(['@nrwl/nx']);
|
||||
expect(appEslint.plugins).toBeUndefined();
|
||||
expect(e2eEslint.plugins).toBeUndefined();
|
||||
expect(libEslint.plugins).toBeUndefined();
|
||||
|
||||
// should extend base
|
||||
expect(appEslint.extends.slice(-1)).toEqual(['./.eslintrc.base.json']);
|
||||
expect(e2eEslint.extends.slice(-1)).toEqual(['../.eslintrc.base.json']);
|
||||
expect(libEslint.extends.slice(-1)).toEqual([
|
||||
'../../.eslintrc.base.json',
|
||||
]);
|
||||
}
|
||||
|
||||
it('(React standalone) should set root project config to app and e2e app and migrate when another lib is added', () => {
|
||||
const myapp = uniq('myapp');
|
||||
const mylib = uniq('mylib');
|
||||
|
||||
runCLI(`generate @nrwl/react:app ${myapp} --rootProject=true`);
|
||||
verifySuccessfulStandaloneSetup(myapp);
|
||||
|
||||
let rootEslint = readJson('.eslintrc.json');
|
||||
let appEslint = readJson('.eslintrc.json');
|
||||
let e2eEslint = readJson('e2e/.eslintrc.json');
|
||||
expect(() => checkFilesExist(`.eslintrc.base.json`)).toThrow();
|
||||
|
||||
// should directly refer to nx plugin
|
||||
expect(rootEslint.plugins).toEqual(['@nrwl/nx']);
|
||||
expect(e2eEslint.plugins).toEqual(['@nrwl/nx']);
|
||||
// should only extend framework plugin
|
||||
expect(rootEslint.extends).toEqual(['plugin:@nrwl/nx/react']);
|
||||
expect(e2eEslint.extends).toEqual(['plugin:cypress/recommended']);
|
||||
// should have plugin extends
|
||||
expect(rootEslint.overrides[0].extends).toEqual([
|
||||
'plugin:@nrwl/nx/typescript',
|
||||
]);
|
||||
expect(rootEslint.overrides[1].extends).toEqual([
|
||||
'plugin:@nrwl/nx/javascript',
|
||||
]);
|
||||
expect(e2eEslint.overrides[0].extends).toEqual([
|
||||
'plugin:@nrwl/nx/typescript',
|
||||
]);
|
||||
expect(e2eEslint.overrides[1].extends).toEqual([
|
||||
'plugin:@nrwl/nx/javascript',
|
||||
]);
|
||||
expect(appEslint.overrides[0].extends).toBeDefined();
|
||||
expect(appEslint.overrides[1].extends).toBeDefined();
|
||||
expect(e2eEslint.overrides[0].extends).toBeDefined();
|
||||
expect(e2eEslint.overrides[1].extends).toBeDefined();
|
||||
|
||||
runCLI(`generate @nrwl/react:lib ${mylib} --unitTestRunner=jest`);
|
||||
// should add new tslint
|
||||
expect(() => checkFilesExist(`.eslintrc.base.json`)).not.toThrow();
|
||||
const appEslint = readJson(`.eslintrc.json`);
|
||||
rootEslint = readJson('.eslintrc.base.json');
|
||||
runCLI(`generate @nrwl/workspace:lib ${mylib} --unitTestRunner=jest`);
|
||||
verifySuccessfulMigratedSetup(myapp, mylib);
|
||||
|
||||
appEslint = readJson(`.eslintrc.json`);
|
||||
e2eEslint = readJson('e2e/.eslintrc.json');
|
||||
const libEslint = readJson(`libs/${mylib}/.eslintrc.json`);
|
||||
|
||||
// should directly refer to nx plugin only in the root
|
||||
expect(rootEslint.plugins).toEqual(['@nrwl/nx']);
|
||||
expect(appEslint.plugins).toBeUndefined();
|
||||
expect(e2eEslint.plugins).toBeUndefined();
|
||||
// should extend framework plugin and root config
|
||||
expect(appEslint.extends).toEqual([
|
||||
'plugin:@nrwl/nx/react',
|
||||
'./.eslintrc.base.json',
|
||||
]);
|
||||
expect(e2eEslint.extends).toEqual([
|
||||
'plugin:cypress/recommended',
|
||||
'../.eslintrc.base.json',
|
||||
]);
|
||||
expect(libEslint.extends).toEqual([
|
||||
'plugin:@nrwl/nx/react',
|
||||
'../../.eslintrc.base.json',
|
||||
]);
|
||||
// should have no plugin extends
|
||||
expect(appEslint.overrides[0].extends).toBeUndefined();
|
||||
expect(appEslint.overrides[1].extends).toBeUndefined();
|
||||
expect(e2eEslint.overrides[0].extends).toBeUndefined();
|
||||
expect(e2eEslint.overrides[1].extends).toBeUndefined();
|
||||
expect(libEslint.overrides[1].extends).toBeUndefined();
|
||||
expect(libEslint.overrides[1].extends).toBeUndefined();
|
||||
});
|
||||
|
||||
it('(Angular standalone) should set root project config to app and e2e app and migrate when another lib is added', () => {
|
||||
@ -514,57 +527,23 @@ describe('Linter', () => {
|
||||
runCLI(
|
||||
`generate @nrwl/angular:app ${myapp} --rootProject=true --no-interactive`
|
||||
);
|
||||
verifySuccessfulStandaloneSetup(myapp);
|
||||
|
||||
let rootEslint = readJson('.eslintrc.json');
|
||||
let appEslint = readJson('.eslintrc.json');
|
||||
let e2eEslint = readJson('e2e/.eslintrc.json');
|
||||
expect(() => checkFilesExist(`.eslintrc.base.json`)).toThrow();
|
||||
|
||||
// should directly refer to nx plugin
|
||||
expect(rootEslint.plugins).toEqual(['@nrwl/nx']);
|
||||
expect(e2eEslint.plugins).toEqual(['@nrwl/nx']);
|
||||
// should only extend framework plugin
|
||||
expect(e2eEslint.extends).toEqual(['plugin:cypress/recommended']);
|
||||
// should have plugin extends
|
||||
expect(rootEslint.overrides[0].files).toEqual(['*.ts']);
|
||||
expect(rootEslint.overrides[0].extends).toEqual([
|
||||
'plugin:@nrwl/nx/typescript',
|
||||
'plugin:@nrwl/nx/angular',
|
||||
'plugin:@angular-eslint/template/process-inline-templates',
|
||||
]);
|
||||
expect(Object.keys(rootEslint.overrides[0].rules)).toEqual([
|
||||
'@angular-eslint/directive-selector',
|
||||
'@angular-eslint/component-selector',
|
||||
]);
|
||||
expect(rootEslint.overrides[1].files).toEqual(['*.html']);
|
||||
expect(rootEslint.overrides[1].extends).toEqual([
|
||||
'plugin:@nrwl/nx/angular-template',
|
||||
]);
|
||||
expect(e2eEslint.overrides[0].extends).toEqual([
|
||||
'plugin:@nrwl/nx/typescript',
|
||||
]);
|
||||
expect(e2eEslint.overrides[1].extends).toEqual([
|
||||
'plugin:@nrwl/nx/javascript',
|
||||
]);
|
||||
expect(appEslint.overrides[0].extends).toBeDefined();
|
||||
expect(appEslint.overrides[1].extends).toBeDefined();
|
||||
expect(e2eEslint.overrides[0].extends).toBeDefined();
|
||||
expect(e2eEslint.overrides[1].extends).toBeDefined();
|
||||
|
||||
runCLI(`generate @nrwl/angular:lib ${mylib} --no-interactive`);
|
||||
// should add new tslint
|
||||
expect(() => checkFilesExist(`.eslintrc.base.json`)).not.toThrow();
|
||||
const appEslint = readJson(`.eslintrc.json`);
|
||||
rootEslint = readJson('.eslintrc.base.json');
|
||||
runCLI(`generate @nrwl/workspace:lib ${mylib} --no-interactive`);
|
||||
verifySuccessfulMigratedSetup(myapp, mylib);
|
||||
|
||||
appEslint = readJson(`.eslintrc.json`);
|
||||
e2eEslint = readJson('e2e/.eslintrc.json');
|
||||
const libEslint = readJson(`libs/${mylib}/.eslintrc.json`);
|
||||
|
||||
// should directly refer to nx plugin only in the root
|
||||
expect(rootEslint.plugins).toEqual(['@nrwl/nx']);
|
||||
expect(appEslint.plugins).toBeUndefined();
|
||||
expect(e2eEslint.plugins).toBeUndefined();
|
||||
// should extend framework plugin and root config
|
||||
expect(appEslint.extends).toEqual(['./.eslintrc.base.json']);
|
||||
expect(e2eEslint.extends).toEqual([
|
||||
'plugin:cypress/recommended',
|
||||
'../.eslintrc.base.json',
|
||||
]);
|
||||
expect(libEslint.extends).toEqual(['../../.eslintrc.base.json']);
|
||||
// should have no plugin extends
|
||||
expect(appEslint.overrides[0].extends).toEqual([
|
||||
'plugin:@nrwl/nx/angular',
|
||||
@ -572,10 +551,37 @@ describe('Linter', () => {
|
||||
]);
|
||||
expect(e2eEslint.overrides[0].extends).toBeUndefined();
|
||||
expect(e2eEslint.overrides[1].extends).toBeUndefined();
|
||||
expect(libEslint.overrides[0].extends).toEqual([
|
||||
'plugin:@nrwl/nx/angular',
|
||||
'plugin:@angular-eslint/template/process-inline-templates',
|
||||
]);
|
||||
});
|
||||
|
||||
it('(Node standalone) should set root project config to app and e2e app and migrate when another lib is added', () => {
|
||||
const myapp = uniq('myapp');
|
||||
const mylib = uniq('mylib');
|
||||
|
||||
runCLI(
|
||||
`generate @nrwl/node:app ${myapp} --rootProject=true --no-interactive`
|
||||
);
|
||||
verifySuccessfulStandaloneSetup(myapp);
|
||||
|
||||
let appEslint = readJson('.eslintrc.json');
|
||||
let e2eEslint = readJson('e2e/.eslintrc.json');
|
||||
|
||||
// should have plugin extends
|
||||
expect(appEslint.overrides[0].extends).toBeDefined();
|
||||
expect(appEslint.overrides[1].extends).toBeDefined();
|
||||
expect(e2eEslint.overrides[0].extends).toBeDefined();
|
||||
expect(e2eEslint.overrides[1].extends).toBeDefined();
|
||||
|
||||
runCLI(`generate @nrwl/workspace:lib ${mylib} --no-interactive`);
|
||||
verifySuccessfulMigratedSetup(myapp, mylib);
|
||||
|
||||
appEslint = readJson(`.eslintrc.json`);
|
||||
e2eEslint = readJson('e2e/.eslintrc.json');
|
||||
|
||||
// should have no plugin extends
|
||||
expect(appEslint.overrides[0].extends).toBeUndefined();
|
||||
expect(appEslint.overrides[1].extends).toBeUndefined();
|
||||
expect(e2eEslint.overrides[0].extends).toBeUndefined();
|
||||
expect(e2eEslint.overrides[1].extends).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -45,6 +45,7 @@ import { e2eProjectGenerator } from '../e2e-project/e2e-project';
|
||||
import { setupDockerGenerator } from '../setup-docker/setup-docker';
|
||||
|
||||
import { Schema } from './schema';
|
||||
import { mapLintPattern } from '@nrwl/linter/src/generators/lint-project/lint-project';
|
||||
|
||||
export interface NormalizedSchema extends Schema {
|
||||
appProjectRoot: string;
|
||||
@ -273,7 +274,11 @@ export async function addLintingToApplication(
|
||||
joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
|
||||
],
|
||||
eslintFilePatterns: [
|
||||
`${options.appProjectRoot}/**/*.${options.js ? 'js' : 'ts'}`,
|
||||
mapLintPattern(
|
||||
options.appProjectRoot,
|
||||
options.js ? 'js' : 'ts',
|
||||
options.rootProject
|
||||
),
|
||||
],
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
skipFormat: true,
|
||||
@ -382,11 +387,8 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
|
||||
|
||||
updateTsConfigOptions(tree, options);
|
||||
|
||||
if (options.linter !== Linter.None) {
|
||||
const lintTask = await addLintingToApplication(tree, {
|
||||
...options,
|
||||
skipFormat: true,
|
||||
});
|
||||
if (options.linter === Linter.EsLint) {
|
||||
const lintTask = await addLintingToApplication(tree, options);
|
||||
tasks.push(lintTask);
|
||||
}
|
||||
|
||||
|
||||
@ -14,11 +14,17 @@ import {
|
||||
readProjectConfiguration,
|
||||
runTasksInSerial,
|
||||
Tree,
|
||||
updateJson,
|
||||
} from '@nrwl/devkit';
|
||||
import { Linter, lintProjectGenerator } from '@nrwl/linter';
|
||||
|
||||
import { Schema } from './schema';
|
||||
import { axiosVersion } from '../../utils/versions';
|
||||
import { join } from 'path';
|
||||
import {
|
||||
globalJavaScriptOverrides,
|
||||
globalTypeScriptOverrides,
|
||||
} from '@nrwl/linter/src/generators/init/global-eslint-config';
|
||||
|
||||
export async function e2eProjectGenerator(host: Tree, _options: Schema) {
|
||||
const tasks: GeneratorCallback[] = [];
|
||||
@ -90,7 +96,7 @@ export async function e2eProjectGenerator(host: Tree, _options: Schema) {
|
||||
);
|
||||
tasks.push(installTask);
|
||||
|
||||
if (options.linter === 'eslint') {
|
||||
if (options.linter === Linter.EsLint) {
|
||||
const linterTask = await lintProjectGenerator(host, {
|
||||
project: options.e2eProjectName,
|
||||
linter: Linter.EsLint,
|
||||
@ -104,6 +110,33 @@ export async function e2eProjectGenerator(host: Tree, _options: Schema) {
|
||||
rootProject: options.rootProject,
|
||||
});
|
||||
tasks.push(linterTask);
|
||||
|
||||
updateJson(host, join(options.e2eProjectRoot, '.eslintrc.json'), (json) => {
|
||||
if (options.rootProject) {
|
||||
json.plugins = ['@nrwl/nx'];
|
||||
json.extends = [];
|
||||
}
|
||||
json.overrides = [
|
||||
...(options.rootProject
|
||||
? [globalTypeScriptOverrides, globalJavaScriptOverrides]
|
||||
: []),
|
||||
/**
|
||||
* In order to ensure maximum efficiency when typescript-eslint generates TypeScript Programs
|
||||
* behind the scenes during lint runs, we need to make sure the project is configured to use its
|
||||
* own specific tsconfigs, and not fall back to the ones in the root of the workspace.
|
||||
*/
|
||||
{
|
||||
files: ['*.ts', '*.tsx', '*.js', '*.jsx'],
|
||||
/**
|
||||
* Having an empty rules object present makes it more obvious to the user where they would
|
||||
* extend things from if they needed to
|
||||
*/
|
||||
rules: {},
|
||||
},
|
||||
];
|
||||
|
||||
return json;
|
||||
});
|
||||
}
|
||||
|
||||
if (options.formatFile) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user