From c021c2f7f72485482d4fac870f0dbd5be369dedb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josh=20Goldberg=20=E2=9C=A8?= Date: Thu, 27 Jun 2024 05:37:01 -0400 Subject: [PATCH] feat: enable @typescript-eslint/recommended in create-next-app --typescript (#52845) Co-authored-by: eps1lon --- .../07-configuring/02-eslint.mdx | 13 ++ examples/with-temporal/package.json | 4 +- .../templates/app-tw/ts/eslintrc.json | 2 +- .../templates/app/ts/eslintrc.json | 2 +- .../templates/default-tw/ts/eslintrc.json | 2 +- .../templates/default/ts/eslintrc.json | 2 +- packages/eslint-config-next/index.js | 15 +-- packages/eslint-config-next/package.json | 1 + packages/eslint-config-next/typescript.js | 3 + packages/next/src/lib/constants.ts | 20 --- .../src/lib/eslint/getESLintPromptValues.ts | 32 +++++ packages/next/src/lib/eslint/runLintCheck.ts | 15 ++- pnpm-lock.yaml | 100 ++++++++++++-- .../integration/eslint/test/next-lint.test.js | 2 + .../next-build-and-lint.test.ts.snap | 122 +++++++++++++++++- .../eslint/test/next-build-and-lint.test.ts | 16 ++- 16 files changed, 296 insertions(+), 55 deletions(-) create mode 100644 packages/eslint-config-next/typescript.js create mode 100644 packages/next/src/lib/eslint/getESLintPromptValues.ts diff --git a/docs/02-app/01-building-your-application/07-configuring/02-eslint.mdx b/docs/02-app/01-building-your-application/07-configuring/02-eslint.mdx index 4926de6334050..e626340a09604 100644 --- a/docs/02-app/01-building-your-application/07-configuring/02-eslint.mdx +++ b/docs/02-app/01-building-your-application/07-configuring/02-eslint.mdx @@ -202,6 +202,19 @@ The `next/core-web-vitals` rule set is enabled when `next lint` is run for the f > The `next/core-web-vitals` entry point is automatically included for new applications built with [Create Next App](/docs/app/api-reference/create-next-app). +### TypeScript + +In addition to the Next.js ESLint rules, `create-next-app --typescript` will also add TypeScript-specific lint rules with `next/typescript` to your config: + +```json filename=".eslintrc.json" +{ + "extends": ["next/core-web-vitals", "next/typescript"] +} +``` + +Those rules are based on [`plugin:@typescript-eslint/recommended`](https://typescript-eslint.io/linting/configs#recommended). +See [typescript-eslint > Configs](https://typescript-eslint.io/linting/configs) for more details. + ## Usage With Other Tools ### Prettier diff --git a/examples/with-temporal/package.json b/examples/with-temporal/package.json index cfe16dabbdb57..5a895270e6215 100644 --- a/examples/with-temporal/package.json +++ b/examples/with-temporal/package.json @@ -24,8 +24,8 @@ "@types/node-fetch": "^3.0.3", "@types/react": "^17.0.2", "@types/react-dom": "^17.0.1", - "@typescript-eslint/eslint-plugin": "^5.3.0", - "@typescript-eslint/parser": "^5.3.0", + "@typescript-eslint/eslint-plugin": "^6.1.0", + "@typescript-eslint/parser": "^6.1.0", "cross-env": "^7.0.3", "nodemon": "^2.0.12", "ts-node": "^10.2.1", diff --git a/packages/create-next-app/templates/app-tw/ts/eslintrc.json b/packages/create-next-app/templates/app-tw/ts/eslintrc.json index bffb357a71225..37224185490e6 100644 --- a/packages/create-next-app/templates/app-tw/ts/eslintrc.json +++ b/packages/create-next-app/templates/app-tw/ts/eslintrc.json @@ -1,3 +1,3 @@ { - "extends": "next/core-web-vitals" + "extends": ["next/core-web-vitals", "next/typescript"] } diff --git a/packages/create-next-app/templates/app/ts/eslintrc.json b/packages/create-next-app/templates/app/ts/eslintrc.json index bffb357a71225..37224185490e6 100644 --- a/packages/create-next-app/templates/app/ts/eslintrc.json +++ b/packages/create-next-app/templates/app/ts/eslintrc.json @@ -1,3 +1,3 @@ { - "extends": "next/core-web-vitals" + "extends": ["next/core-web-vitals", "next/typescript"] } diff --git a/packages/create-next-app/templates/default-tw/ts/eslintrc.json b/packages/create-next-app/templates/default-tw/ts/eslintrc.json index bffb357a71225..37224185490e6 100644 --- a/packages/create-next-app/templates/default-tw/ts/eslintrc.json +++ b/packages/create-next-app/templates/default-tw/ts/eslintrc.json @@ -1,3 +1,3 @@ { - "extends": "next/core-web-vitals" + "extends": ["next/core-web-vitals", "next/typescript"] } diff --git a/packages/create-next-app/templates/default/ts/eslintrc.json b/packages/create-next-app/templates/default/ts/eslintrc.json index bffb357a71225..37224185490e6 100644 --- a/packages/create-next-app/templates/default/ts/eslintrc.json +++ b/packages/create-next-app/templates/default/ts/eslintrc.json @@ -1,3 +1,3 @@ { - "extends": "next/core-web-vitals" + "extends": ["next/core-web-vitals", "next/typescript"] } diff --git a/packages/eslint-config-next/index.js b/packages/eslint-config-next/index.js index a17aa9d618f9f..4c95a88ad4fba 100644 --- a/packages/eslint-config-next/index.js +++ b/packages/eslint-config-next/index.js @@ -30,12 +30,13 @@ sortedPaths.push(...keptPaths) const hookPropertyMap = new Map( [ - ['eslint-plugin-import', 'eslint-plugin-import'], - ['eslint-plugin-react', 'eslint-plugin-react'], - ['eslint-plugin-jsx-a11y', 'eslint-plugin-jsx-a11y'], - ].map(([request, replacement]) => [ + '@typescript-eslint/eslint-plugin', + 'eslint-plugin-import', + 'eslint-plugin-react', + 'eslint-plugin-jsx-a11y', + ].map((request) => [ request, - require.resolve(replacement, { paths: sortedPaths }), + require.resolve(request, { paths: sortedPaths }), ]) ) @@ -96,10 +97,6 @@ module.exports = { parser: '@typescript-eslint/parser', parserOptions: { sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - warnOnUnsupportedTypeScriptVersion: true, }, }, ], diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 7e67a8d8a854f..38dae54bf6b1e 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -12,6 +12,7 @@ "dependencies": { "@next/eslint-plugin-next": "14.2.7", "@rushstack/eslint-patch": "^1.3.3", + "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", diff --git a/packages/eslint-config-next/typescript.js b/packages/eslint-config-next/typescript.js new file mode 100644 index 0000000000000..810b7df219d98 --- /dev/null +++ b/packages/eslint-config-next/typescript.js @@ -0,0 +1,3 @@ +module.exports = { + extends: ['plugin:@typescript-eslint/recommended'], +} diff --git a/packages/next/src/lib/constants.ts b/packages/next/src/lib/constants.ts index 825cb114c7665..9afc9f881a248 100644 --- a/packages/next/src/lib/constants.ts +++ b/packages/next/src/lib/constants.ts @@ -78,26 +78,6 @@ export const SSG_FALLBACK_EXPORT_ERROR = `Pages with \`fallback\` enabled in \`g export const ESLINT_DEFAULT_DIRS = ['app', 'pages', 'components', 'lib', 'src'] -export const ESLINT_PROMPT_VALUES = [ - { - title: 'Strict', - recommended: true, - config: { - extends: 'next/core-web-vitals', - }, - }, - { - title: 'Base', - config: { - extends: 'next', - }, - }, - { - title: 'Cancel', - config: null, - }, -] - export const SERVER_RUNTIME: Record = { edge: 'edge', experimentalEdge: 'experimental-edge', diff --git a/packages/next/src/lib/eslint/getESLintPromptValues.ts b/packages/next/src/lib/eslint/getESLintPromptValues.ts new file mode 100644 index 0000000000000..277546289a9fb --- /dev/null +++ b/packages/next/src/lib/eslint/getESLintPromptValues.ts @@ -0,0 +1,32 @@ +import findUp from 'next/dist/compiled/find-up' + +export const getESLintStrictValue = async (cwd: string) => { + const tsConfigLocation = await findUp('tsconfig.json', { cwd }) + const hasTSConfig = tsConfigLocation !== undefined + + return { + title: 'Strict', + recommended: true, + config: { + extends: hasTSConfig + ? ['next/core-web-vitals', 'next/typescript'] + : 'next/core-web-vitals', + }, + } +} + +export const getESLintPromptValues = async (cwd: string) => { + return [ + await getESLintStrictValue(cwd), + { + title: 'Base', + config: { + extends: 'next', + }, + }, + { + title: 'Cancel', + config: null, + }, + ] +} diff --git a/packages/next/src/lib/eslint/runLintCheck.ts b/packages/next/src/lib/eslint/runLintCheck.ts index 6e11c138d0604..b00f8fb1427ea 100644 --- a/packages/next/src/lib/eslint/runLintCheck.ts +++ b/packages/next/src/lib/eslint/runLintCheck.ts @@ -12,7 +12,6 @@ import { writeDefaultConfig } from './writeDefaultConfig' import { hasEslintConfiguration } from './hasEslintConfiguration' import { writeOutputFile } from './writeOutputFile' -import { ESLINT_PROMPT_VALUES } from '../constants' import { findPagesDir } from '../find-pages-dir' import { installDependencies } from '../install-dependencies' import { hasNecessaryDependencies } from '../has-necessary-dependencies' @@ -21,6 +20,10 @@ import * as Log from '../../build/output/log' import type { EventLintCheckCompleted } from '../../telemetry/events/build' import isError, { getProperError } from '../is-error' import { getPkgManager } from '../helpers/get-pkg-manager' +import { + getESLintStrictValue, + getESLintPromptValues, +} from './getESLintPromptValues' type Config = { plugins: string[] @@ -44,7 +47,7 @@ const requiredPackages = [ }, ] -async function cliPrompt(): Promise<{ config?: any }> { +async function cliPrompt(cwd: string): Promise<{ config?: any }> { console.log( bold( `${cyan( @@ -58,7 +61,7 @@ async function cliPrompt(): Promise<{ config?: any }> { await Promise.resolve(require('next/dist/compiled/cli-select')) ).default const { value } = await cliSelect({ - values: ESLINT_PROMPT_VALUES, + values: await getESLintPromptValues(cwd), valueRenderer: ( { title, @@ -355,10 +358,8 @@ export async function runLintCheck( } else { // Ask user what config they would like to start with for first time "next lint" setup const { config: selectedConfig } = strict - ? ESLINT_PROMPT_VALUES.find( - (opt: { title: string }) => opt.title === 'Strict' - )! - : await cliPrompt() + ? await getESLintStrictValue(baseDir) + : await cliPrompt(baseDir) if (selectedConfig == null) { // Show a warning if no option is selected in prompt diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 905bb77f9af37..bf64ecc322bc9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -749,6 +749,9 @@ importers: '@rushstack/eslint-patch': specifier: ^1.3.3 version: 1.3.3 + '@typescript-eslint/eslint-plugin': + specifier: ^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0 + version: 6.14.0(@typescript-eslint/parser@6.14.0)(eslint@8.31.0)(typescript@4.8.2) '@typescript-eslint/parser': specifier: ^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0 version: 6.14.0(eslint@8.31.0)(typescript@4.8.2) @@ -3670,6 +3673,16 @@ packages: jsdoc-type-pratt-parser: 4.0.0 dev: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.31.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.31.0 + eslint-visitor-keys: 3.4.3 + dev: false + /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3688,7 +3701,6 @@ packages: /@eslint-community/regexpp@4.5.1: resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true /@eslint/eslintrc@0.4.3: resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==} @@ -7094,13 +7106,8 @@ packages: '@types/node': 20.2.5 dev: true - /@types/semver@7.5.0: - resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} - dev: true - /@types/semver@7.5.6: resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} - dev: true /@types/send@0.14.4: resolution: {integrity: sha512-SCVCRRjSbpwoKgA34wK8cq14OUPu4qrKigO85/ZH6J04NGws37khLtq7YQr17zyOH01p4T5oy8e1TxEzql01Pg==} @@ -7222,6 +7229,35 @@ packages: dev: true optional: true + /@typescript-eslint/eslint-plugin@6.14.0(@typescript-eslint/parser@6.14.0)(eslint@8.31.0)(typescript@4.8.2): + resolution: {integrity: sha512-1ZJBykBCXaSHG94vMMKmiHoL0MhNHKSVlcHVYZNw+BKxufhqQVTOawNpwwI1P5nIFZ/4jLVop0mcY6mJJDFNaw==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.5.1 + '@typescript-eslint/parser': 6.14.0(eslint@8.31.0)(typescript@4.8.2) + '@typescript-eslint/scope-manager': 6.14.0 + '@typescript-eslint/type-utils': 6.14.0(eslint@8.31.0)(typescript@4.8.2) + '@typescript-eslint/utils': 6.14.0(eslint@8.31.0)(typescript@4.8.2) + '@typescript-eslint/visitor-keys': 6.14.0 + debug: 4.3.4 + eslint: 8.31.0 + graphemer: 1.4.0 + ignore: 5.2.4 + natural-compare: 1.4.0 + semver: 7.5.4 + ts-api-utils: 1.0.1(typescript@4.8.2) + typescript: 4.8.2 + transitivePeerDependencies: + - supports-color + dev: false + /@typescript-eslint/eslint-plugin@6.14.0(@typescript-eslint/parser@6.14.0)(eslint@8.56.0)(typescript@5.2.2): resolution: {integrity: sha512-1ZJBykBCXaSHG94vMMKmiHoL0MhNHKSVlcHVYZNw+BKxufhqQVTOawNpwwI1P5nIFZ/4jLVop0mcY6mJJDFNaw==} engines: {node: ^16.0.0 || >=18.0.0} @@ -7308,6 +7344,26 @@ packages: '@typescript-eslint/types': 6.14.0 '@typescript-eslint/visitor-keys': 6.14.0 + /@typescript-eslint/type-utils@6.14.0(eslint@8.31.0)(typescript@4.8.2): + resolution: {integrity: sha512-x6OC9Q7HfYKqjnuNu5a7kffIYs3No30isapRBJl1iCHLitD8O0lFbRcVGiOcuyN837fqXzPZ1NS10maQzZMKqw==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 6.14.0(typescript@4.8.2) + '@typescript-eslint/utils': 6.14.0(eslint@8.31.0)(typescript@4.8.2) + debug: 4.3.4 + eslint: 8.31.0 + ts-api-utils: 1.0.1(typescript@4.8.2) + typescript: 4.8.2 + transitivePeerDependencies: + - supports-color + dev: false + /@typescript-eslint/type-utils@6.14.0(eslint@8.56.0)(typescript@5.2.2): resolution: {integrity: sha512-x6OC9Q7HfYKqjnuNu5a7kffIYs3No30isapRBJl1iCHLitD8O0lFbRcVGiOcuyN837fqXzPZ1NS10maQzZMKqw==} engines: {node: ^16.0.0 || >=18.0.0} @@ -7420,6 +7476,25 @@ packages: - typescript dev: true + /@typescript-eslint/utils@6.14.0(eslint@8.31.0)(typescript@4.8.2): + resolution: {integrity: sha512-XwRTnbvRr7Ey9a1NT6jqdKX8y/atWG+8fAIu3z73HSP8h06i3r/ClMhmaF/RGWGW1tHJEwij1uEg2GbEmPYvYg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.31.0) + '@types/json-schema': 7.0.12 + '@types/semver': 7.5.6 + '@typescript-eslint/scope-manager': 6.14.0 + '@typescript-eslint/types': 6.14.0 + '@typescript-eslint/typescript-estree': 6.14.0(typescript@4.8.2) + eslint: 8.31.0 + semver: 7.6.2 + transitivePeerDependencies: + - supports-color + - typescript + dev: false + /@typescript-eslint/utils@6.14.0(eslint@8.56.0)(typescript@5.2.2): resolution: {integrity: sha512-XwRTnbvRr7Ey9a1NT6jqdKX8y/atWG+8fAIu3z73HSP8h06i3r/ClMhmaF/RGWGW1tHJEwij1uEg2GbEmPYvYg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -7428,12 +7503,12 @@ packages: dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@types/json-schema': 7.0.12 - '@types/semver': 7.5.0 + '@types/semver': 7.5.6 '@typescript-eslint/scope-manager': 6.14.0 '@typescript-eslint/types': 6.14.0 '@typescript-eslint/typescript-estree': 6.14.0(typescript@5.2.2) eslint: 8.56.0 - semver: 7.5.4 + semver: 7.6.2 transitivePeerDependencies: - supports-color - typescript @@ -13408,7 +13483,6 @@ packages: /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - dev: true /graphql@16.7.1: resolution: {integrity: sha512-DRYR9tf+UGU0KOsMcKAlXeFfX89UiiIZ0dRU3mR0yJfu6OjZqUcp68NnFLnqQU5RexygFoDy1EW+ccOYcPfmHg==} @@ -13951,7 +14025,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.1.1 transitivePeerDependencies: - supports-color dev: true @@ -22286,6 +22360,12 @@ packages: dependencies: lru-cache: 6.0.0 + /semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + requiresBuild: true + /send@0.17.1: resolution: {integrity: sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==} engines: {node: '>= 0.8.0'} diff --git a/test/integration/eslint/test/next-lint.test.js b/test/integration/eslint/test/next-lint.test.js index 21bb553008b22..fff6cfa9b94f2 100644 --- a/test/integration/eslint/test/next-lint.test.js +++ b/test/integration/eslint/test/next-lint.test.js @@ -120,7 +120,9 @@ describe('Next Lint', () => { 'We created the .eslintrc.json file for you and included your selected configuration' ) expect(eslintrcJson).toMatchObject({ extends: 'next/core-web-vitals' }) + }) + test('creates .eslintrc.json file with a default app router configuration', async () => { // App Router const { stdout: appStdout, eslintrcJson: appEslintrcJson } = await nextLintTemp(null, true) diff --git a/test/production/eslint/test/__snapshots__/next-build-and-lint.test.ts.snap b/test/production/eslint/test/__snapshots__/next-build-and-lint.test.ts.snap index c2daff29b4f3a..6ee5b00a60f13 100644 --- a/test/production/eslint/test/__snapshots__/next-build-and-lint.test.ts.snap +++ b/test/production/eslint/test/__snapshots__/next-build-and-lint.test.ts.snap @@ -223,7 +223,6 @@ exports[`Next Build production mode first time setup with TypeScript 1`] = ` }, "requireConfigFile": false, "sourceType": "module", - "warnOnUnsupportedTypeScriptVersion": true, }, "plugins": [ "react-hooks", @@ -231,6 +230,7 @@ exports[`Next Build production mode first time setup with TypeScript 1`] = ` "react", "import", "@next/next", + "@typescript-eslint", ], "rules": { "@next/next/google-font-display": [ @@ -296,6 +296,63 @@ exports[`Next Build production mode first time setup with TypeScript 1`] = ` "@next/next/no-unwanted-polyfillio": [ "warn", ], + "@typescript-eslint/ban-ts-comment": [ + "error", + ], + "@typescript-eslint/ban-types": [ + "error", + ], + "@typescript-eslint/no-array-constructor": [ + "error", + ], + "@typescript-eslint/no-duplicate-enum-values": [ + "error", + ], + "@typescript-eslint/no-explicit-any": [ + "error", + ], + "@typescript-eslint/no-extra-non-null-assertion": [ + "error", + ], + "@typescript-eslint/no-loss-of-precision": [ + "error", + ], + "@typescript-eslint/no-misused-new": [ + "error", + ], + "@typescript-eslint/no-namespace": [ + "error", + ], + "@typescript-eslint/no-non-null-asserted-optional-chain": [ + "error", + ], + "@typescript-eslint/no-this-alias": [ + "error", + ], + "@typescript-eslint/no-unnecessary-type-constraint": [ + "error", + ], + "@typescript-eslint/no-unsafe-declaration-merging": [ + "error", + ], + "@typescript-eslint/no-unused-vars": [ + "error", + ], + "@typescript-eslint/no-var-requires": [ + "error", + ], + "@typescript-eslint/prefer-as-const": [ + "error", + ], + "@typescript-eslint/triple-slash-reference": [ + "error", + ], + "constructor-super": [ + "off", + ], + "getter-return": [ + "off", + ], "import/no-anonymous-default-export": [ "warn", ], @@ -325,6 +382,69 @@ exports[`Next Build production mode first time setup with TypeScript 1`] = ` "jsx-a11y/role-supports-aria-props": [ "warn", ], + "no-array-constructor": [ + "off", + ], + "no-const-assign": [ + "off", + ], + "no-dupe-args": [ + "off", + ], + "no-dupe-class-members": [ + "off", + ], + "no-dupe-keys": [ + "off", + ], + "no-func-assign": [ + "off", + ], + "no-import-assign": [ + "off", + ], + "no-loss-of-precision": [ + "off", + ], + "no-new-symbol": [ + "off", + ], + "no-obj-calls": [ + "off", + ], + "no-redeclare": [ + "off", + ], + "no-setter-return": [ + "off", + ], + "no-this-before-super": [ + "off", + ], + "no-undef": [ + "off", + ], + "no-unreachable": [ + "off", + ], + "no-unsafe-negation": [ + "off", + ], + "no-unused-vars": [ + "off", + ], + "no-var": [ + "error", + ], + "prefer-const": [ + "error", + ], + "prefer-rest-params": [ + "error", + ], + "prefer-spread": [ + "error", + ], "react-hooks/exhaustive-deps": [ "warn", ], diff --git a/test/production/eslint/test/next-build-and-lint.test.ts b/test/production/eslint/test/next-build-and-lint.test.ts index db34abff5002d..0172785243a33 100644 --- a/test/production/eslint/test/next-build-and-lint.test.ts +++ b/test/production/eslint/test/next-build-and-lint.test.ts @@ -15,6 +15,10 @@ describe('Next Build', () => { test('first time setup', async () => { const next = await createNext({ files: new FileRef(dirFirstTimeSetup), + dependencies: { + // create-next-install will replace this with a version built from the local source + 'eslint-config-next': 'canary', + }, skipStart: true, }) @@ -33,14 +37,16 @@ describe('Next Build', () => { execSync(`pnpm next lint --strict`, { cwd: next.testDir, encoding: 'utf8', + stdio: 'inherit', }) }).toThrow('Command failed: pnpm next lint --strict') - const eslintConfigAfterSetupJSON = await execSync( + const eslintConfigAfterSetupJSON = execSync( `pnpm eslint --print-config pages/index.js`, { cwd: next.testDir, encoding: 'utf8', + stdio: ['pipe', 'pipe', 'inherit'], } ) const { parser, settings, ...eslintConfigAfterSetup } = JSON.parse( @@ -89,6 +95,10 @@ describe('Next Build', () => { test('first time setup with TypeScript', async () => { const next = await createNext({ files: new FileRef(dirFirstTimeSetupTS), + dependencies: { + // create-next-install will replace this with a version built from the local source + 'eslint-config-next': 'canary', + }, skipStart: true, }) @@ -107,14 +117,16 @@ describe('Next Build', () => { execSync(`pnpm next lint --strict`, { cwd: next.testDir, encoding: 'utf8', + stdio: 'inherit', }) }).toThrow('Command failed: pnpm next lint --strict') - const eslintConfigAfterSetupJSON = await execSync( + const eslintConfigAfterSetupJSON = execSync( `pnpm eslint --print-config pages/index.tsx`, { cwd: next.testDir, encoding: 'utf8', + stdio: ['pipe', 'pipe', 'inherit'], } ) const { parser, settings, ...eslintConfigAfterSetup } = JSON.parse(