From cca3dab7a040e4c659cea4d79300480500e34e96 Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Mon, 8 Jul 2024 15:09:26 -0300 Subject: [PATCH] migrate react eslint to flat config --- .github/dependabot.yml | 5 +- generators/client/files-common.js | 1 + .../webpack/webpack.microfrontend.js.jhi.ejs | 2 +- generators/cypress/files.ts | 4 + .../eslint.config.js.jhi.cypress.ejs | 41 +++++++ .../__snapshots__/generator.spec.ts.snap | 60 ++++------ generators/react/files-react.js | 7 +- generators/react/generator.js | 42 +++++-- generators/react/resources/package.json | 5 +- generators/react/templates/.eslintrc.json.ejs | 109 ------------------ .../templates/eslint.config.js.jhi.react.ejs | 109 ++++++++++++++++++ generators/react/templates/jest.conf.js.ejs | 2 +- generators/react/templates/package.json.ejs | 7 +- .../templates/webpack/environment.js.ejs | 2 +- .../react/templates/webpack/utils.js.ejs | 2 +- .../templates/webpack/webpack.common.js.ejs | 10 +- .../templates/webpack/webpack.dev.js.ejs | 1 - .../webpack.microfrontend.js.jhi.react.ejs | 5 - .../webpack.microfrontend.js.jhi.vue.ejs | 6 - 19 files changed, 235 insertions(+), 185 deletions(-) create mode 100644 generators/cypress/templates/eslint.config.js.jhi.cypress.ejs delete mode 100644 generators/react/templates/.eslintrc.json.ejs create mode 100644 generators/react/templates/eslint.config.js.jhi.react.ejs diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 159cf6a2994f..6a033ebc710f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -150,9 +150,10 @@ updates: - dependency-name: '@module-federation/utilities' versions: ['*'] groups: - typescript-eslint: + eslint: patterns: - - '@typescript-eslint/*' + - '@eslint/*' + - 'eslint' fortawesome: patterns: - '@fortawesome/fontawesome-svg-core' diff --git a/generators/client/files-common.js b/generators/client/files-common.js index 99c012733d2f..c11c3840d31d 100644 --- a/generators/client/files-common.js +++ b/generators/client/files-common.js @@ -27,6 +27,7 @@ export const files = { templates: ['README.md.jhi.client', '.prettierignore.jhi.client'], }, clientRootTemplatesBlock({ + condition: ctx => !ctx.clientFrameworkReact, templates: ['.eslintignore'], }), clientRootTemplatesBlock({ diff --git a/generators/client/templates/webpack/webpack.microfrontend.js.jhi.ejs b/generators/client/templates/webpack/webpack.microfrontend.js.jhi.ejs index 1589b3f27bb2..409867e8adbe 100644 --- a/generators/client/templates/webpack/webpack.microfrontend.js.jhi.ejs +++ b/generators/client/templates/webpack/webpack.microfrontend.js.jhi.ejs @@ -42,7 +42,7 @@ const shareDependencies = ({ skipList = [] } = {}) => .map(([dependency, version]) => [dependency, { ...sharedDefaults, version, requiredVersion: version }]), ); -module.exports = ({ serve }) => { +module.exports = () => { return { optimization: { moduleIds: 'named', diff --git a/generators/cypress/files.ts b/generators/cypress/files.ts index 3bf3c4440143..efaa182ef783 100644 --- a/generators/cypress/files.ts +++ b/generators/cypress/files.ts @@ -35,6 +35,10 @@ export const cypressFiles: WriteFileSection Boolean(ctx.eslintConfigFile), + templates: [{ sourceFile: 'eslint.config.js.jhi.cypress', destinationFile: ctx => `${ctx.eslintConfigFile}.jhi.cypress` }], + }), ], clientTestFw: [ { diff --git a/generators/cypress/templates/eslint.config.js.jhi.cypress.ejs b/generators/cypress/templates/eslint.config.js.jhi.cypress.ejs new file mode 100644 index 000000000000..41c496ee2eb7 --- /dev/null +++ b/generators/cypress/templates/eslint.config.js.jhi.cypress.ejs @@ -0,0 +1,41 @@ +<%# + Copyright 2013-2024 the original author or authors from the JHipster project. + + This file is part of the JHipster project, see https://www.jhipster.tech/ + for more information. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +-%> +<&_ if (fragment.importsSection) { -&> +import cypress from 'eslint-plugin-cypress/flat'; +<&_ } -&> +<&_ if (fragment.configSection) { -&> + { + files: ['<%- this.relativeDir(clientRootDir, cypressDir) %>**/*.cy.ts'], + extends: [...tseslint.configs.recommendedTypeChecked, cypress.configs.recommended], + languageOptions: { + parserOptions: { + "project": ["./<%= this.relativeDir(clientRootDir, cypressDir) %>tsconfig.json"], + }, + }, + rules: { + '@typescript-eslint/no-explicit-any': 'warn', + '@typescript-eslint/no-unsafe-argument': 'warn', + '@typescript-eslint/no-unsafe-assignment': 'warn', + '@typescript-eslint/no-unsafe-call': 'warn', + '@typescript-eslint/no-unsafe-member-access': 'warn', + '@typescript-eslint/unbound-method': 'warn', + '@typescript-eslint/no-unused-vars': 'warn', + }, + }, +<&_ } -&> diff --git a/generators/react/__snapshots__/generator.spec.ts.snap b/generators/react/__snapshots__/generator.spec.ts.snap index 4b9063ae6195..a887e1339736 100644 --- a/generators/react/__snapshots__/generator.spec.ts.snap +++ b/generators/react/__snapshots__/generator.spec.ts.snap @@ -17,10 +17,7 @@ exports[`generator - react gateway-jwt-skipUserManagement(true)-withAdminUi(fals ".yo-rc.json": { "stateCleared": "modified", }, - "clientRoot/.eslintignore": { - "stateCleared": "modified", - }, - "clientRoot/.eslintrc.json": { + "clientRoot/eslint.config.mjs": { "stateCleared": "modified", }, "clientRoot/jest.conf.js": { @@ -419,6 +416,9 @@ exports[`generator - react gateway-jwt-skipUserManagement(true)-withAdminUi(fals "clientRoot/webpack/webpack.prod.js": { "stateCleared": "modified", }, + "package.json": { + "stateCleared": "modified", + }, } `; @@ -439,10 +439,7 @@ exports[`generator - react gateway-oauth2-withAdminUi(true)-skipJhipsterDependen ".yo-rc.json": { "stateCleared": "modified", }, - "clientRoot/.eslintignore": { - "stateCleared": "modified", - }, - "clientRoot/.eslintrc.json": { + "clientRoot/eslint.config.mjs": { "stateCleared": "modified", }, "clientRoot/jest.conf.js": { @@ -874,6 +871,9 @@ exports[`generator - react gateway-oauth2-withAdminUi(true)-skipJhipsterDependen "clientRoot/webpack/webpack.prod.js": { "stateCleared": "modified", }, + "package.json": { + "stateCleared": "modified", + }, } `; @@ -894,10 +894,7 @@ exports[`generator - react microservice-jwt-skipUserManagement(false)-withAdminU ".yo-rc.json": { "stateCleared": "modified", }, - "clientRoot/.eslintignore": { - "stateCleared": "modified", - }, - "clientRoot/.eslintrc.json": { + "clientRoot/eslint.config.mjs": { "stateCleared": "modified", }, "clientRoot/jest.conf.js": { @@ -1302,17 +1299,14 @@ exports[`generator - react microservice-jwt-skipUserManagement(false)-withAdminU "clientRoot/webpack/webpack.prod.js": { "stateCleared": "modified", }, + "package.json": { + "stateCleared": "modified", + }, } `; exports[`generator - react microservice-oauth2-withAdminUi(true)-skipJhipsterDependencies(true)-enableTranslation(true)--websocket(false) should match generated files snapshot 1`] = ` { - ".eslintignore": { - "stateCleared": "modified", - }, - ".eslintrc.json": { - "stateCleared": "modified", - }, ".jhipster/EntityWithCustomId.json": { "stateCleared": "modified", }, @@ -1328,6 +1322,9 @@ exports[`generator - react microservice-oauth2-withAdminUi(true)-skipJhipsterDep ".yo-rc.json": { "stateCleared": "modified", }, + "eslint.config.mjs": { + "stateCleared": "modified", + }, "jest.conf.js": { "stateCleared": "modified", }, @@ -1753,12 +1750,6 @@ exports[`generator - react microservice-oauth2-withAdminUi(true)-skipJhipsterDep exports[`generator - react monolith-jwt-skipUserManagement(false)-withAdminUi(true)-skipJhipsterDependencies(true)-enableTranslation(true)--websocket(true) should match generated files snapshot 1`] = ` { - ".eslintignore": { - "stateCleared": "modified", - }, - ".eslintrc.json": { - "stateCleared": "modified", - }, ".jhipster/EntityWithCustomId.json": { "stateCleared": "modified", }, @@ -1774,6 +1765,9 @@ exports[`generator - react monolith-jwt-skipUserManagement(false)-withAdminUi(tr ".yo-rc.json": { "stateCleared": "modified", }, + "eslint.config.mjs": { + "stateCleared": "modified", + }, "jest.conf.js": { "stateCleared": "modified", }, @@ -2268,12 +2262,6 @@ exports[`generator - react monolith-jwt-skipUserManagement(false)-withAdminUi(tr exports[`generator - react monolith-oauth2-withAdminUi(false)-skipJhipsterDependencies(false)-enableTranslation(false)-websocket(false) should match generated files snapshot 1`] = ` { - ".eslintignore": { - "stateCleared": "modified", - }, - ".eslintrc.json": { - "stateCleared": "modified", - }, ".jhipster/EntityWithCustomId.json": { "stateCleared": "modified", }, @@ -2289,6 +2277,9 @@ exports[`generator - react monolith-oauth2-withAdminUi(false)-skipJhipsterDepend ".yo-rc.json": { "stateCleared": "modified", }, + "eslint.config.mjs": { + "stateCleared": "modified", + }, "jest.conf.js": { "stateCleared": "modified", }, @@ -2693,12 +2684,6 @@ exports[`generator - react monolith-oauth2-withAdminUi(false)-skipJhipsterDepend exports[`generator - react monolith-session-skipUserManagement(true)-withAdminUi(false)-skipJhipsterDependencies(false)-enableTranslation(false)-websocket(true) should match generated files snapshot 1`] = ` { - ".eslintignore": { - "stateCleared": "modified", - }, - ".eslintrc.json": { - "stateCleared": "modified", - }, ".jhipster/EntityWithCustomId.json": { "stateCleared": "modified", }, @@ -2714,6 +2699,9 @@ exports[`generator - react monolith-session-skipUserManagement(true)-withAdminUi ".yo-rc.json": { "stateCleared": "modified", }, + "eslint.config.mjs": { + "stateCleared": "modified", + }, "jest.conf.js": { "stateCleared": "modified", }, diff --git a/generators/react/files-react.js b/generators/react/files-react.js index ee4adff43c7b..444137d95ecf 100644 --- a/generators/react/files-react.js +++ b/generators/react/files-react.js @@ -16,14 +16,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { asWriteFilesSection } from '../base-application/support/index.js'; import { clientApplicationTemplatesBlock, clientRootTemplatesBlock, clientSrcTemplatesBlock } from '../client/support/files.js'; -export const files = { +export const files = asWriteFilesSection({ common: [ clientRootTemplatesBlock({ templates: [ + { sourceFile: 'eslint.config.js.jhi.react', destinationFile: ctx => `${ctx.eslintConfigFile}.jhi.react` }, 'package.json', - '.eslintrc.json', 'tsconfig.json', 'tsconfig.test.json', 'jest.conf.js', @@ -304,7 +305,7 @@ export const files = { templates: ['shared/reducers/user-management.spec.ts'], }, ], -}; +}); export async function writeFiles({ application }) { if (!application.clientFrameworkReact) return; diff --git a/generators/react/generator.js b/generators/react/generator.js index 23bd56980e08..39da47d53076 100644 --- a/generators/react/generator.js +++ b/generators/react/generator.js @@ -29,6 +29,7 @@ import { generateEntityClientImports as formatEntityClientImports, generateTestEntityId as getTestEntityId, generateTestEntityPrimaryKey as getTestEntityPrimaryKey, + clientRootTemplatesBlock, } from '../client/support/index.js'; import { createNeedleCallback, upperFirstCamelCase } from '../base/support/index.js'; import { writeEntitiesFiles, postWriteEntitiesFiles, cleanupEntitiesFiles } from './entity-files-react.js'; @@ -40,10 +41,7 @@ import { isTranslatedReactFile, translateReactFilesTransform } from './support/i const { CommonDBTypes } = fieldTypes; const TYPE_BOOLEAN = CommonDBTypes.BOOLEAN; const { REACT } = clientFrameworkTypes; -/** - * @class - * @extends {BaseApplicationGenerator} - */ + export default class ReactGenerator extends BaseApplicationGenerator { async beforeQueue() { if (!this.fromBlueprint) { @@ -51,6 +49,7 @@ export default class ReactGenerator extends BaseApplicationGenerator { } if (!this.delegateToBlueprint) { + await this.dependsOnJHipster('jhipster:javascript:bootstrap'); await this.dependsOnJHipster(GENERATOR_CLIENT); await this.dependsOnJHipster(GENERATOR_LANGUAGES); } @@ -76,6 +75,12 @@ export default class ReactGenerator extends BaseApplicationGenerator { this.fetchFromInstalledJHipster(GENERATOR_REACT, 'resources', 'package.json'), ); }, + applicationDefauts({ applicationDefaults }) { + applicationDefaults({ + __override__: true, + typescriptEslint: true, + }); + }, }); } @@ -85,9 +90,14 @@ export default class ReactGenerator extends BaseApplicationGenerator { get preparing() { return this.asPreparingTaskGroup({ + applicationDefauts({ applicationDefaults }) { + applicationDefaults({ + __override__: true, + eslintConfigFile: app => `eslint.config.${app.packageJsonType === 'module' ? 'js' : 'mjs'}`, + webappEnumerationsDir: app => `${app.clientSrcDir}app/shared/model/enumerations/`, + }); + }, prepareForTemplates({ application, source }) { - application.webappEnumerationsDir = `${application.clientSrcDir}app/shared/model/enumerations/`; - source.addWebpackConfig = args => { const webpackPath = `${application.clientRootDir}webpack/webpack.common.js`; const ignoreNonExisting = this.sharedData.getControl().ignoreNeedlesError && 'Webpack configuration file not found'; @@ -142,10 +152,26 @@ export default class ReactGenerator extends BaseApplicationGenerator { } get writing() { - return { + return this.asWritingTaskGroup({ + cleanup({ control }) { + control.cleanupFiles({ + '8.6.1': ['.eslintrc.json', '.eslintignore'], + }); + }, cleanupOldFilesTask, + async writingEslintFile({ application }) { + await this.writeFiles({ + blocks: [ + clientRootTemplatesBlock({ + templates: [{ sourceFile: 'eslint.config.js.jhi', destinationFile: ctx => `${ctx.eslintConfigFile}.jhi` }], + }), + ], + context: application, + rootTemplatesPath: this.fetchFromInstalledJHipster('javascript/generators/eslint/templates'), + }); + }, writeFiles, - }; + }); } get [BaseApplicationGenerator.WRITING]() { diff --git a/generators/react/resources/package.json b/generators/react/resources/package.json index e5659741f151..b49d7b13b494 100644 --- a/generators/react/resources/package.json +++ b/generators/react/resources/package.json @@ -29,6 +29,7 @@ "webstomp-client": "1.2.6" }, "devDependencies": { + "@eslint/js": "8.57.0", "@module-federation/utilities": "3.0.3-0", "@testing-library/react": "16.0.0", "@types/jest": "29.5.12", @@ -39,8 +40,6 @@ "@types/react-redux": "7.1.33", "@types/redux": "3.6.31", "@types/webpack-env": "1.18.5", - "@typescript-eslint/eslint-plugin": "7.16.0", - "@typescript-eslint/parser": "7.16.0", "autoprefixer": "10.4.19", "browser-sync": "2.29.3", "browser-sync-webpack-plugin": "2.3.0", @@ -51,6 +50,7 @@ "css-minimizer-webpack-plugin": "7.0.0", "eslint": "8.57.0", "eslint-config-prettier": "9.1.0", + "eslint-plugin-prettier": "5.1.3", "eslint-plugin-react": "7.34.4", "eslint-webpack-plugin": "4.2.0", "folder-hash": "4.0.4", @@ -81,6 +81,7 @@ "ts-jest": "29.2.2", "ts-loader": "9.5.1", "typescript": "5.5.3", + "typescript-eslint": "7.16.0", "webpack": "5.93.0", "webpack-cli": "5.1.4", "webpack-dev-server": "5.0.4", diff --git a/generators/react/templates/.eslintrc.json.ejs b/generators/react/templates/.eslintrc.json.ejs deleted file mode 100644 index 7d69f8a866a0..000000000000 --- a/generators/react/templates/.eslintrc.json.ejs +++ /dev/null @@ -1,109 +0,0 @@ -<%# - Copyright 2013-2024 the original author or authors from the JHipster project. - - This file is part of the JHipster project, see https://www.jhipster.tech/ - for more information. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. --%> -{ - "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint"], - "extends": [ - "plugin:react/recommended", - "eslint:recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking", - "prettier", - "eslint-config-prettier" - ], - "parserOptions": { - "ecmaVersion": 2018, - "sourceType": "module", - "ecmaFeatures": { - "jsx": true - }, - "project": [ - "./tsconfig.json", -<%_ if (cypressTests) { _%> - "./<%= this.relativeDir(clientRootDir, clientTestDir) %>cypress/tsconfig.json", -<%_ } _%> - "./tsconfig.test.json" - ] - }, - "settings": { - "react": { - "version": "detect" - } - }, - "rules": { - "@typescript-eslint/member-ordering": [ - "error", - { - "default": [ - "static-field", - "instance-field", - "constructor", - "static-method", - "instance-method" - ] - } - ], - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/explicit-member-accessibility": "off", - "@typescript-eslint/explicit-function-return-type": "off", - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-unsafe-argument": "off", - "@typescript-eslint/no-unsafe-return": "off", - "@typescript-eslint/no-unsafe-member-access":"off", - "@typescript-eslint/no-unsafe-call": "off", - "@typescript-eslint/no-unsafe-assignment": "off", - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/restrict-template-expressions": "off", - "@typescript-eslint/restrict-plus-operands": "off", - "@typescript-eslint/no-floating-promises": "off", - "@typescript-eslint/ban-types": [ - "error", - { - "types": { - "Object": "Use {} instead." - } - } - ], - "@typescript-eslint/interface-name-prefix": "off", - "@typescript-eslint/no-empty-function": "off", - "@typescript-eslint/unbound-method": "off", - "@typescript-eslint/array-type": "off", - "@typescript-eslint/no-shadow": "error", - "spaced-comment": ["warn", "always"], - "guard-for-in": "error", - "no-labels": "error", - "no-caller": "error", - "no-bitwise": "error", - "no-console": ["error", { "allow": ["warn", "error"] }], - "no-new-wrappers": "error", - "no-eval": "error", - "no-new": "error", - "no-var": "error", - "radix": "error", - "eqeqeq": ["error", "always", { "null": "ignore" }], - "prefer-const": "error", - "object-shorthand": ["error", "always", { "avoidExplicitReturnArrows": true }], - "default-case": "error", - "complexity": ["error", 40], - "no-invalid-this": "off", - "react/prop-types": "off", - "react/display-name": "off" - } -} diff --git a/generators/react/templates/eslint.config.js.jhi.react.ejs b/generators/react/templates/eslint.config.js.jhi.react.ejs new file mode 100644 index 000000000000..37229fa6d7a4 --- /dev/null +++ b/generators/react/templates/eslint.config.js.jhi.react.ejs @@ -0,0 +1,109 @@ +<%# + Copyright 2013-2024 the original author or authors from the JHipster project. + + This file is part of the JHipster project, see https://www.jhipster.tech/ + for more information. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +-%> +<&_ if (fragment.importsSection) { -&> +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import react from 'eslint-plugin-react/configs/recommended.js'; +<&_ } -&> +<&_ if (fragment.configSection) { -&> + { ignores: ['<%- this.relativeDir(clientRootDir, clientDistDir) %>', '<%- temporaryDir %>'] }, + eslint.configs.recommended, + { + files: ['**/*.{js,cjs,mjs}'], + rules: { + 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + }, + }, + { + files: ['<%- this.relativeDir(clientRootDir, clientSrcDir) %>**/*.{ts,tsx}'], + extends: [...tseslint.configs.recommendedTypeChecked, react], + settings: { + react: { + version: 'detect', + }, + }, + languageOptions: { + globals: { + ...globals.browser, + }, + parserOptions: { + project: ['./tsconfig.json', './tsconfig.test.json'], + }, + }, + rules: { + '@typescript-eslint/member-ordering': [ + 'error', + { + default: ['static-field', 'instance-field', 'constructor', 'static-method', 'instance-method'], + }, + ], + '@typescript-eslint/no-unused-vars': 'off', + '@typescript-eslint/explicit-member-accessibility': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unsafe-argument': 'off', + '@typescript-eslint/no-unsafe-return': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/restrict-template-expressions': 'off', + '@typescript-eslint/restrict-plus-operands': 'off', + '@typescript-eslint/no-floating-promises': 'off', + '@typescript-eslint/ban-types': [ + 'error', + { + types: { + Object: 'Use {} instead.', + }, + }, + ], + '@typescript-eslint/interface-name-prefix': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/unbound-method': 'off', + '@typescript-eslint/array-type': 'off', + '@typescript-eslint/no-shadow': 'error', + 'spaced-comment': ['warn', 'always'], + 'guard-for-in': 'error', + 'no-labels': 'error', + 'no-caller': 'error', + 'no-bitwise': 'error', + 'no-console': ['error', { allow: ['warn', 'error'] }], + 'no-new-wrappers': 'error', + 'no-eval': 'error', + 'no-new': 'error', + 'no-var': 'error', + radix: 'error', + eqeqeq: ['error', 'always', { null: 'ignore' }], + 'prefer-const': 'error', + 'object-shorthand': ['error', 'always', { avoidExplicitReturnArrows: true }], + 'default-case': 'error', + complexity: ['error', 40], + 'no-invalid-this': 'off', + 'react/prop-types': 'off', + 'react/display-name': 'off', + }, + }, + { + files: ['<%- this.relativeDir(clientRootDir, clientSrcDir) %>**/*.spec.ts'], + rules: { + '@typescript-eslint/no-empty-function': 'off', + }, + }, +<&_ } -&> diff --git a/generators/react/templates/jest.conf.js.ejs b/generators/react/templates/jest.conf.js.ejs index b34130e90dbb..7f88be20c161 100644 --- a/generators/react/templates/jest.conf.js.ejs +++ b/generators/react/templates/jest.conf.js.ejs @@ -47,7 +47,7 @@ function mapTypescriptAliasToJestAlias(alias = {}) { return jestAliases; } Object.entries(tsconfig.compilerOptions.paths) - .filter(([key, value]) => { + .filter(([_key, value]) => { // use Typescript alias in Jest only if this has value if (value.length) { return true; diff --git a/generators/react/templates/package.json.ejs b/generators/react/templates/package.json.ejs index 2d3671671452..0a7691982536 100644 --- a/generators/react/templates/package.json.ejs +++ b/generators/react/templates/package.json.ejs @@ -26,6 +26,7 @@ "node_modules" ], "dependencies": { + "@eslint/js": null, "@fortawesome/fontawesome-svg-core": "<%= nodeDependencies['@fortawesome/fontawesome-svg-core'] %>", "@fortawesome/free-solid-svg-icons": "<%= nodeDependencies['@fortawesome/free-solid-svg-icons'] %>", "@fortawesome/react-fontawesome": "<%= nodeDependencies['@fortawesome/react-fontawesome'] %>", @@ -70,8 +71,6 @@ "@types/react-redux": "<%= nodeDependencies['@types/react-redux'] %>", "@types/redux": "<%= nodeDependencies['@types/redux'] %>", "@types/webpack-env": "<%= nodeDependencies['@types/webpack-env'] %>", - "@typescript-eslint/eslint-plugin": "<%= nodeDependencies['@typescript-eslint/eslint-plugin'] %>", - "@typescript-eslint/parser": "<%= nodeDependencies['@typescript-eslint/parser'] %>", "autoprefixer": "<%= nodeDependencies['autoprefixer'] %>", "browser-sync": "<%= nodeDependencies['browser-sync'] %>", "browser-sync-webpack-plugin": "<%= nodeDependencies['browser-sync-webpack-plugin'] %>", @@ -82,6 +81,7 @@ "css-minimizer-webpack-plugin": "<%= nodeDependencies['css-minimizer-webpack-plugin'] %>", "eslint": "<%= nodeDependencies['eslint'] %>", "eslint-config-prettier": "<%= nodeDependencies['eslint-config-prettier'] %>", + "eslint-plugin-prettier": "<%= nodeDependencies['eslint-plugin-prettier'] %>", "eslint-plugin-react": "<%= nodeDependencies['eslint-plugin-react'] %>", "eslint-webpack-plugin": "<%= nodeDependencies['eslint-webpack-plugin'] %>", "fork-ts-checker-webpack-plugin": "<%= nodeDependencies['fork-ts-checker-webpack-plugin'] %>", @@ -120,6 +120,7 @@ "cypress": "<%= nodeDependencies['cypress'] %>", <%_ } _%> "typescript": "<%= nodeDependencies['typescript'] %>", + "typescript-eslint": "<%= nodeDependencies['typescript-eslint'] %>", "webpack": "<%= nodeDependencies['webpack'] %>", "webpack-cli": "<%= nodeDependencies['webpack-cli'] %>", "webpack-dev-server": "<%= nodeDependencies['webpack-dev-server'] %>", @@ -136,7 +137,7 @@ "scripts": { "prettier:check": "prettier --check \"{,src/**/,webpack/,.blueprint/**/}*.{<%= prettierExtensions %>}\"", "prettier:format": "prettier --write \"{,src/**/,webpack/,.blueprint/**/}*.{<%= prettierExtensions %>}\"", - "lint": "eslint . --ext .js,.ts,.jsx,.tsx", + "lint": "eslint .", "lint:fix": "<%= clientPackageManager %> run lint -- --fix", "cleanup": "rimraf <%= this.relativeDir(clientRootDir, temporaryDir) %>", "clean-www": "rimraf <%= this.relativeDir(clientRootDir, clientDistDir) %>", diff --git a/generators/react/templates/webpack/environment.js.ejs b/generators/react/templates/webpack/environment.js.ejs index d792b70c2f18..6573e4518af3 100644 --- a/generators/react/templates/webpack/environment.js.ejs +++ b/generators/react/templates/webpack/environment.js.ejs @@ -25,7 +25,7 @@ module.exports = { VERSION: packageJson.version, <%_ } else { _%> // APP_VERSION is passed as an environment variable from the Gradle / Maven build tasks. - VERSION: process.env.hasOwnProperty('APP_VERSION') ? process.env.APP_VERSION : 'DEV', + VERSION: process.env.APP_VERSION || 'DEV', <%_ } _%> // The root URL for API calls, ending with a '/' - for example: `"https://www.jhipster.tech:8081/myservice/"`. // If this URL is left empty (""), then it will be relative to the current context. diff --git a/generators/react/templates/webpack/utils.js.ejs b/generators/react/templates/webpack/utils.js.ejs index 45511688f1f6..a361f7da853f 100644 --- a/generators/react/templates/webpack/utils.js.ejs +++ b/generators/react/templates/webpack/utils.js.ejs @@ -38,7 +38,7 @@ function mapTypescriptAliasToWebpackAlias(alias = {}) { return webpackAliases; } Object.entries(tsconfig.compilerOptions.paths) - .filter(([key, value]) => { + .filter(([_key, value]) => { // use Typescript alias in Webpack only if this has value return !!value.length; }) diff --git a/generators/react/templates/webpack/webpack.common.js.ejs b/generators/react/templates/webpack/webpack.common.js.ejs index 5fc4c4b66e81..9401cb4d4e46 100644 --- a/generators/react/templates/webpack/webpack.common.js.ejs +++ b/generators/react/templates/webpack/webpack.common.js.ejs @@ -30,7 +30,7 @@ const MergeJsonWebpackPlugin = require('merge-jsons-webpack-plugin'); const utils = require('./utils.js'); const environment = require('./environment'); -const getTsLoaderRule = env => { +const getTsLoaderRule = () => { const rules = [ { loader: 'thread-loader', @@ -127,11 +127,9 @@ return merge( SERVER_API_URL: JSON.stringify(environment.SERVER_API_URL), }), new ESLintPlugin({ - baseConfig: { - parserOptions: { - project: ['../tsconfig.json'], - }, - }, + configType: 'flat', + eslintPath: 'eslint/use-at-your-own-risk', + extensions: ['ts', 'tsx'], }), new ForkTsCheckerWebpackPlugin(), new CopyWebpackPlugin({ diff --git a/generators/react/templates/webpack/webpack.dev.js.ejs b/generators/react/templates/webpack/webpack.dev.js.ejs index 53a2fb8ef009..d842c2f2a121 100644 --- a/generators/react/templates/webpack/webpack.dev.js.ejs +++ b/generators/react/templates/webpack/webpack.dev.js.ejs @@ -16,7 +16,6 @@ See the License for the specific language governing permissions and limitations under the License. -%> -const webpack = require('webpack'); const webpackMerge = require('webpack-merge').merge; const BrowserSyncPlugin = require('browser-sync-webpack-plugin'); const SimpleProgressWebpackPlugin = require('simple-progress-webpack-plugin'); diff --git a/generators/react/templates/webpack/webpack.microfrontend.js.jhi.react.ejs b/generators/react/templates/webpack/webpack.microfrontend.js.jhi.react.ejs index 5626f7dd2dd6..34f473c63e96 100644 --- a/generators/react/templates/webpack/webpack.microfrontend.js.jhi.react.ejs +++ b/generators/react/templates/webpack/webpack.microfrontend.js.jhi.react.ejs @@ -16,11 +16,6 @@ See the License for the specific language governing permissions and limitations under the License. -%> -<&_ if (fragment.importsSection) { -&> -<%_ if (applicationTypeMicroservice) { _%> -const { DefinePlugin } = require('webpack'); -<%_ } _%> -<&_ } -&> <&_ if (fragment.moduleFederationSection) { -&> <%_ if (applicationTypeMicroservice) { _%> exposes: { diff --git a/generators/vue/templates/webpack/webpack.microfrontend.js.jhi.vue.ejs b/generators/vue/templates/webpack/webpack.microfrontend.js.jhi.vue.ejs index 61bd1c7976d6..e30946d381c2 100644 --- a/generators/vue/templates/webpack/webpack.microfrontend.js.jhi.vue.ejs +++ b/generators/vue/templates/webpack/webpack.microfrontend.js.jhi.vue.ejs @@ -16,12 +16,6 @@ See the License for the specific language governing permissions and limitations under the License. -%> -<&_ if (fragment.importsSection) { -&> -<%_ if (applicationTypeMicroservice) { _%> -const { DefinePlugin } = require('webpack'); -<%_ } _%> -<&_ } -&> - <&_ if (fragment.configSection) { -&> <%_ if (applicationTypeGateway && clientFrameworkVue) { _%> resolve: {