From 2130bb6b17b067325970a60dda408aa4a22941a7 Mon Sep 17 00:00:00 2001 From: Alex Pshul Date: Mon, 7 Oct 2024 20:20:37 -0400 Subject: [PATCH] Added eslint flat config support to init generator --- .../func/src/generators/init/generator.ts | 47 ++++++++++++++++--- .../src/generators/init/tests/eslint.spec.ts | 30 +++++++++++- 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/packages/func/src/generators/init/generator.ts b/packages/func/src/generators/init/generator.ts index 1400197..bfcc835 100644 --- a/packages/func/src/generators/init/generator.ts +++ b/packages/func/src/generators/init/generator.ts @@ -204,9 +204,7 @@ const createRegisterPathsFile = (tree: Tree, { appRoot }: NormalizedOptions) => ); }; -const configureEslint = (tree: Tree, { appRoot, appNames: { name } }: NormalizedOptions) => { - if (!tree.exists('.eslintrc.json')) return; - +const setupEslintrc = (tree: Tree, appRoot: string) => { const relativePathToRoot = offsetFromRoot(appRoot); const projectJsonPath = `${appRoot}/tsconfig.*?.json`; @@ -234,13 +232,48 @@ const configureEslint = (tree: Tree, { appRoot, appNames: { name } }: Normalized }; tree.write(path.posix.join(appRoot, '.eslintrc.json'), JSON.stringify(projectEslintConfig, null, 2)); +}; + +const setupFlatEslintConfig = (tree: Tree, appRoot: string, fileName: string) => { + const relativePathToRoot = offsetFromRoot(appRoot); + const projectJsonPath = path.posix.normalize(`${fileName}/tsconfig.*?.json`); + + const configFileContent = ` + const baseConfig = require('${relativePathToRoot}eslint.config.js'); + + module.exports = [ + ...baseConfig, + { rules: {} }, + { + files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'], + // Override or add rules here + rules: {}, + languageOptions: { parserOptions: { project: [${path.posix.join(...projectJsonPath.split(path.sep))}], } }, + }, + { + files: ['**/*.ts', '**/*.tsx'], + // Override or add rules here + rules: {}, + }, + { + files: ['**/*.js', '**/*.jsx'], + // Override or add rules here + rules: {}, + }, + ]; + `; + + tree.write(path.posix.join(appRoot, 'eslint.config.js'), configFileContent); +}; + +const configureEslint = (tree: Tree, { appRoot, appNames: { name, fileName } }: NormalizedOptions) => { + if (tree.exists('.eslintrc.json')) setupEslintrc(tree, appRoot); + else if (tree.exists('eslint.config.js')) setupFlatEslintConfig(tree, appRoot, fileName); + else return; const projectConfig = readProjectConfiguration(tree, name); projectConfig.targets.lint = { - executor: '@nx/linter:eslint', - options: { - lintFilePatterns: [`apps/${name}/**/*.ts`], - }, + executor: '@nx/eslint:lint', outputs: ['{options.outputFile}'], }; diff --git a/packages/func/src/generators/init/tests/eslint.spec.ts b/packages/func/src/generators/init/tests/eslint.spec.ts index ce155b9..2a47eaf 100644 --- a/packages/func/src/generators/init/tests/eslint.spec.ts +++ b/packages/func/src/generators/init/tests/eslint.spec.ts @@ -26,18 +26,23 @@ describe('Init with no eslint', () => { it( 'No global config -> no app config', async () => { - await generator(appTree, { ...baseOptions, name: baseOptions.name + '1' }); + const name = baseOptions.name + '1'; + await generator(appTree, { ...baseOptions, name }); const eslintConfigExists = appTree.exists('apps/hello-world1/.eslintrc.json'); expect(eslintConfigExists).toBeFalsy(); + + const projectConfiguration = readProjectConfiguration(appTree, name); + expect(projectConfiguration).not.toHaveProperty('targets.lint'); }, TEST_TIMEOUT, ); it( - 'Global config exists -> app config generated', + 'Global old config exists -> app config generated', async () => { appTree.write('.eslintrc.json', JSON.stringify({})); + const name = baseOptions.name + '2'; await generator(appTree, { ...baseOptions, name }); @@ -46,6 +51,27 @@ describe('Init with no eslint', () => { const projectConfiguration = readProjectConfiguration(appTree, name); expect(projectConfiguration).toHaveProperty('targets.lint'); + + appTree.delete('.eslintrc.json'); + }, + TEST_TIMEOUT, + ); + + it( + 'Global flat config exists -> app config generated', + async () => { + appTree.write('eslint.config.js', ''); + + const name = baseOptions.name + '3'; + await generator(appTree, { ...baseOptions, name }); + + const eslintConfigExists = appTree.exists('apps/hello-world3/eslint.config.js'); + expect(eslintConfigExists).toBeTruthy(); + + const projectConfiguration = readProjectConfiguration(appTree, name); + expect(projectConfiguration).toHaveProperty('targets.lint'); + + appTree.delete('eslint.config.js'); }, TEST_TIMEOUT, );