From fe51e9a1f22123f4d4f439bc73297203495acf4b Mon Sep 17 00:00:00 2001 From: Houssein Djirdeh Date: Tue, 8 Jun 2021 10:21:53 -0400 Subject: [PATCH 1/6] lots of eslint updates --- docs/api-reference/cli.md | 9 ++-- .../next.config.js/ignoring-eslint.md | 41 +++++++++++++++ docs/basic-features/eslint.md | 39 +++++++++----- docs/manifest.json | 4 ++ packages/next/build/index.ts | 5 +- packages/next/cli/next-build.ts | 4 +- packages/next/cli/next-lint.ts | 8 ++- packages/next/lib/eslint/customFormatter.ts | 19 ++++--- packages/next/lib/eslint/runLintCheck.ts | 11 ++-- packages/next/lib/find-dir.ts | 13 +++++ .../next/lib/has-necessary-dependencies.ts | 15 +++--- .../eslint/ignore-during-builds/.eslintrc | 7 +++ .../ignore-during-builds/next.config.js | 9 ++++ .../ignore-during-builds/pages/index.js | 8 +++ test/integration/eslint/test/index.test.js | 51 +++++++------------ 15 files changed, 167 insertions(+), 76 deletions(-) create mode 100644 docs/api-reference/next.config.js/ignoring-eslint.md create mode 100644 packages/next/lib/find-dir.ts create mode 100644 test/integration/eslint/ignore-during-builds/.eslintrc create mode 100644 test/integration/eslint/ignore-during-builds/next.config.js create mode 100644 test/integration/eslint/ignore-during-builds/pages/index.js diff --git a/docs/api-reference/cli.md b/docs/api-reference/cli.md index ab91148fb834a..f13204ad7808f 100644 --- a/docs/api-reference/cli.md +++ b/docs/api-reference/cli.md @@ -86,12 +86,15 @@ npx next start -p 4000 ## Lint -`next lint` runs ESLint for all files in the `pages` directory and provides a guided setup to install any required dependencies if ESLint is not already configured in your application. +`next lint` runs ESLint for all files in the `pages`, `components`, and `lib` directories. It also +provides a guided setup to install any required dependencies if ESLint is not already configured in +your application. -You can also run ESLint on other directories with the `--dir` flag: +If you have other directories that you would like to lint, you can specify them using the `--dir` +flag: ```bash -next lint --dir components +next lint --dir utils ``` ## Telemetry diff --git a/docs/api-reference/next.config.js/ignoring-eslint.md b/docs/api-reference/next.config.js/ignoring-eslint.md new file mode 100644 index 0000000000000..19d7ff665d4cc --- /dev/null +++ b/docs/api-reference/next.config.js/ignoring-eslint.md @@ -0,0 +1,41 @@ +--- +description: Next.js reports ESLint errors and warnings during builds by default. Learn to opt-out of this behavior here. +--- + +# Ignoring ESLint + +When ESLint is detected in your project, Next.js fails your **production build** (`next build`) when errors are present. + +If you'd like Next.js to dangerously produce production code even when your application has ESLint errors, you can disable the built-in linting step completely. + +> Be sure you have configured ESLint to run in a separate part of your workflow (for example, in CI or a pre-commit hook). + +Open `next.config.js` and enable the `ignoreDuringBuilds` option in the `eslint` config: + +```js +module.exports = { + eslint: { + // !! WARN !! + // Dangerously allow production builds to successfully complete even if + // your project has ESLint errors. + // !! WARN !! + ignoreDuringBuilds: true, + }, +} +``` + +## Related + +
+ + Introduction to next.config.js: + Learn more about the configuration file used by Next.js. + +
+ +
+ + ESLint: + Get started with ESLint in Next.js. + +
diff --git a/docs/basic-features/eslint.md b/docs/basic-features/eslint.md index 040bb5fb95758..d94a809f68bab 100644 --- a/docs/basic-features/eslint.md +++ b/docs/basic-features/eslint.md @@ -7,13 +7,13 @@ description: Next.js provides an integrated ESLint experience by default. These Since version **11.0.0**, Next.js provides an integrated [ESLint](https://eslint.org/) experience out of the box. To get started, run `next lint`: ```bash -next lint +npx next lint ``` If you don't already have ESLint configured in your application, you will be guided through the installation of the required packages. ```bash -next lint +npx next lint # You'll see instructions like these: # @@ -42,25 +42,36 @@ We recommend using an appropriate [integration](https://eslint.org/docs/user-gui Once ESLint has been set up, it will automatically run during every build (`next build`). Errors will fail the build, while warnings will not. -If you do not want ESLint to run as a build step, it can be disabled using the `--no-lint` flag: - -```bash -next build --no-lint -``` - -**This is not recommended** unless you have configured ESLint to run in a separate part of your workflow (for example, in CI or a pre-commit hook). +If you do not want ESLint to run as a build step, refer to the documentation for [Ignoring ESLint](/docs/api-reference/next.config.js/ignoring-eslint.md): ## Linting Custom Directories -By default, Next.js will only run ESLint for all files in the `pages/` directory. However, you can specify other custom directories to run by using the `--dir` flag in `next lint`: +By default, Next.js will run ESLint for all files in the `pages/`, `components/`, and `lib/` directories. However, you can specify other custom directories to run by using the `--dir` flag in `next lint`: ```bash -next lint --dir components --dir lib +npx next lint --dir utils --dir custom ``` ## ESLint Plugin -Next.js provides an ESLint plugin, [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next), making it easier to catch common issues and problems in a Next.js application. The full set of rules can be found in the [package repository](https://github.com/vercel/next.js/tree/master/packages/eslint-plugin-next/lib/rules). +Next.js provides an ESLint plugin, [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next), making it easier to catch common issues and problems in a Next.js application. The full set of rules is as follows: + +| | Rule | Description | +| :-: | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| ✔️ | [next/google-font-display](https://nextjs.org/docs/messages/google-font-display) | Enforce optional or swap font-display behavior with Google Fonts | +| ✔️ | [next/google-font-preconnect](https://nextjs.org/docs/messages/google-font-preconnect) | Enforce preconnect usage with Google Fonts | +| ✔️ | [next/link-passhref](https://nextjs.org/docs/messages/link-passhref) | Enforce passHref prop usage with custom Link components | +| ✔️ | [next/no-css-tags](https://nextjs.org/docs/messages/no-css-tags) | Prevent manual stylesheet tags | +| ✔️ | [next/no-document-import-in-page](https://nextjs.org/docs/messages/no-document-import-in-page) | Disallow importing next/document outside of pages/document.js | +| ✔️ | [next/no-head-import-in-document](https://nextjs.org/docs/messages/no-head-import-in-document) | Disallow importing next/head in pages/document.js | +| ✔️ | [next/no-html-link-for-pages](https://nextjs.org/docs/messages/no-html-link-for-pages) | Prohibit HTML anchor links to pages without a Link component | +| ✔️ | [next/no-img-element](https://nextjs.org/docs/messages/no-img-element) | Prohibit usage of HTML <img> element | +| ✔️ | [next/no-page-custom-font](https://nextjs.org/docs/messages/no-page-custom-font) | Prevent page-only custom fonts | +| ✔️ | [next/no-sync-scripts](https://nextjs.org/docs/messages/no-sync-scripts) | Forbid synchronous scripts | +| ✔️ | [next/no-title-in-document-head](https://nextjs.org/docs/messages/no-title-in-document-head) | Disallow using <title> with Head from next/document | +| ✔️ | [next/no-unwanted-polyfillio](https://nextjs.org/docs/messages/no-unwanted-polyfillio) | Prevent duplicate polyfills from Polyfill.io | + +- ✔: Enabled in the recommended configuration ## Base Configuration @@ -82,14 +93,14 @@ You can see the full details of the shareable configuration in the [`eslint-conf ## Disabling Rules -If you would like to modify any rules provided by the supported plugins (`react`, `react-hooks`, `next`), you can directly modify them using the `rules` property in your `.eslintrc`: +If you would like to modify or disable any rules provided by the supported plugins (`react`, `react-hooks`, `next`), you can directly change them using the `rules` property in your `.eslintrc`: ```js { "extends": "next", "rules": { "react/no-unescaped-entities": "off", - "@next/next/no-page-custom-font": "error", + "@next/next/no-page-custom-font": "off", } } ``` diff --git a/docs/manifest.json b/docs/manifest.json index ceefa4ceca61c..e87c8b06e3866 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -344,6 +344,10 @@ "title": "Configuring onDemandEntries", "path": "/docs/api-reference/next.config.js/configuring-onDemandEntries.md" }, + { + "title": "Ignoring ESLint", + "path": "/docs/api-reference/next.config.js/ignoring-eslint.md" + }, { "title": "Ignoring TypeScript Errors", "path": "/docs/api-reference/next.config.js/ignoring-typescript-errors.md" diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index e5c44640df2e9..292b2aae30f1b 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -119,8 +119,7 @@ export default async function build( dir: string, conf = null, reactProductionProfiling = false, - debugOutput = false, - runLint = true + debugOutput = false ): Promise { const nextBuildSpan = trace('next-build') @@ -213,7 +212,7 @@ export default async function build( typeCheckingSpinner.stopAndPersist() } - if (runLint) { + if (!Boolean(config.eslint?.ignoreDuringBuilds)) { await nextBuildSpan .traceChild('verify-and-lint') .traceAsyncFn(async () => { diff --git a/packages/next/cli/next-build.ts b/packages/next/cli/next-build.ts index c9afca528d5b2..b0b0b52c838f0 100755 --- a/packages/next/cli/next-build.ts +++ b/packages/next/cli/next-build.ts @@ -98,9 +98,7 @@ const nextBuild: cliCommand = (argv) => { } return preflight() - .then(() => - build(dir, null, args['--profile'], args['--debug'], !args['--no-lint']) - ) + .then(() => build(dir, null, args['--profile'], args['--debug'])) .catch((err) => { console.error('') console.error('> Build error occurred') diff --git a/packages/next/cli/next-lint.ts b/packages/next/cli/next-lint.ts index cc8216c840151..65923e42202f2 100755 --- a/packages/next/cli/next-lint.ts +++ b/packages/next/cli/next-lint.ts @@ -2,6 +2,8 @@ import { existsSync } from 'fs' import arg from 'next/dist/compiled/arg/index.js' import { resolve, join } from 'path' +import chalk from 'chalk' + import { cliCommand } from '../bin/next' import { runLintCheck } from '../lib/eslint/runLintCheck' import { printAndExit } from '../server/lib/utils' @@ -66,7 +68,11 @@ const nextLint: cliCommand = (argv) => { runLintCheck(baseDir, lintDirs) .then((results) => { - if (results) console.log(results) + if (results) { + console.log(results) + } else { + console.log(chalk.green('✔ No ESLint warnings or errors')) + } }) .catch((err) => { printAndExit(err.message) diff --git a/packages/next/lib/eslint/customFormatter.ts b/packages/next/lib/eslint/customFormatter.ts index 5e7d6cf9c3118..5d956860a568f 100644 --- a/packages/next/lib/eslint/customFormatter.ts +++ b/packages/next/lib/eslint/customFormatter.ts @@ -70,12 +70,15 @@ function formatMessage( } export function formatResults(baseDir: string, results: LintResult[]): string { - return ( - results - .filter(({ messages }) => messages?.length) - .map(({ messages, filePath }) => - formatMessage(baseDir, messages, filePath) - ) - .join('\n') + '\n' - ) + const formattedResults = results + .filter(({ messages }) => messages?.length) + .map(({ messages, filePath }) => formatMessage(baseDir, messages, filePath)) + .join('\n') + + return formattedResults.length > 0 + ? formattedResults + + `\n\n${chalk.bold( + 'Need to disable some ESLint rules? Learn more here:' + )} https://nextjs.org/docs/basic-features/eslint#disabling-rules\n` + : '' } diff --git a/packages/next/lib/eslint/runLintCheck.ts b/packages/next/lib/eslint/runLintCheck.ts index 5dd2e8cdb1d9f..6a2636c9583e7 100644 --- a/packages/next/lib/eslint/runLintCheck.ts +++ b/packages/next/lib/eslint/runLintCheck.ts @@ -7,9 +7,10 @@ import * as CommentJson from 'next/dist/compiled/comment-json' import { formatResults } from './customFormatter' import { writeDefaultConfig } from './writeDefaultConfig' + import { getPackageVersion } from '../get-package-version' +import { findDir } from '../find-dir' import { findPagesDir } from '../find-pages-dir' - import { CompileError } from '../compile-error' import { hasNecessaryDependencies, @@ -74,6 +75,8 @@ async function lint( } const pagesDir = findPagesDir(baseDir) + const componentsDir = findDir(baseDir, 'components') + const libDir = findDir(baseDir, 'lib') if (nextEslintPluginIsEnabled) { let updatedPagesDir = false @@ -98,10 +101,12 @@ async function lint( } } - // If no directories to lint are provided, only the pages directory will be linted + // If no directories to lint are provided, the pages, components, and lib directories will be linted const filesToLint = lintDirs ? lintDirs.map(linteableFiles) - : linteableFiles(pagesDir) + : [pagesDir, componentsDir, libDir] + .filter((dir) => dir && dir.length > 0) + .map(linteableFiles) const results = await eslint.lintFiles(filesToLint) diff --git a/packages/next/lib/find-dir.ts b/packages/next/lib/find-dir.ts new file mode 100644 index 0000000000000..2135c30c41de0 --- /dev/null +++ b/packages/next/lib/find-dir.ts @@ -0,0 +1,13 @@ +import path from 'path' +import { existsSync } from './find-pages-dir' + +export function findDir(dir: string, dirName: string): string { + // prioritize ./pages over ./src/pages + let curDir = path.join(dir, dirName) + if (existsSync(curDir)) return curDir + + curDir = path.join(dir, dirName) + if (existsSync(curDir)) return curDir + + return '' +} diff --git a/packages/next/lib/has-necessary-dependencies.ts b/packages/next/lib/has-necessary-dependencies.ts index 9d6abff18d371..cf69f826994f7 100644 --- a/packages/next/lib/has-necessary-dependencies.ts +++ b/packages/next/lib/has-necessary-dependencies.ts @@ -70,18 +70,15 @@ export async function hasNecessaryDependencies( const removalLintMsg = `\n\n` + (lintDuringBuild - ? `If you do not want to run ESLint during builds, run ${chalk.bold.cyan( - 'next build --no-lint' - )}` + + ? `If you do not want to run ESLint during builds, ` + (!!eslintrcFile - ? ` or remove the ${chalk.bold( + ? `remove the ${chalk.bold( basename(eslintrcFile) - )} file from your package root.` + )} file from your package root` : pkgJsonEslintConfig - ? ` or remove the ${chalk.bold( - 'eslintConfig' - )} field from package.json.` - : '') + ? `remove the ${chalk.bold('eslintConfig')} field from package.json` + : '') + + ' or disable it in next.config.js.\n\nSee https://nextjs.org/docs/api-reference/next.config.js/ignoring-eslint.' : `Once installed, run ${chalk.bold.cyan('next lint')} again.`) const removalMsg = checkTSDeps ? removalTSMsg : removalLintMsg diff --git a/test/integration/eslint/ignore-during-builds/.eslintrc b/test/integration/eslint/ignore-during-builds/.eslintrc new file mode 100644 index 0000000000000..22b9919b24161 --- /dev/null +++ b/test/integration/eslint/ignore-during-builds/.eslintrc @@ -0,0 +1,7 @@ +{ + "extends": "next", + "root": true, + "rules": { + "@next/next/no-html-link-for-pages": 0 + } +} diff --git a/test/integration/eslint/ignore-during-builds/next.config.js b/test/integration/eslint/ignore-during-builds/next.config.js new file mode 100644 index 0000000000000..f16ff3157d7a6 --- /dev/null +++ b/test/integration/eslint/ignore-during-builds/next.config.js @@ -0,0 +1,9 @@ +module.exports = { + eslint: { + // !! WARN !! + // Dangerously allow production builds to successfully complete even if + // your project has ESLint errors. + // !! WARN !! + ignoreDuringBuilds: true, + }, +} diff --git a/test/integration/eslint/ignore-during-builds/pages/index.js b/test/integration/eslint/ignore-during-builds/pages/index.js new file mode 100644 index 0000000000000..ca1cd577585d0 --- /dev/null +++ b/test/integration/eslint/ignore-during-builds/pages/index.js @@ -0,0 +1,8 @@ +const Home = () => ( +
+

Home

+ /* Badly formatted comment */ +
+) + +export default Home diff --git a/test/integration/eslint/test/index.test.js b/test/integration/eslint/test/index.test.js index 7a4a71d9e6102..62f545e108661 100644 --- a/test/integration/eslint/test/index.test.js +++ b/test/integration/eslint/test/index.test.js @@ -8,15 +8,7 @@ jest.setTimeout(1000 * 60 * 2) const dirFirstTimeSetup = join(__dirname, '../first-time-setup') const dirCustomConfig = join(__dirname, '../custom-config') - -async function eslintVersion() { - const eslint = require.resolve('eslint') - const { ESLint, Linter } = await import(eslint) - - if (!ESLint && !Linter) return null // A very old version ( { describe('Next Build', () => { @@ -46,18 +38,22 @@ describe('ESLint', () => { }) const output = stdout + stderr - const version = await eslintVersion() + expect(output).toContain( + 'Error: Comments inside children section of tag should be placed inside braces' + ) + }) - if (!version || (version && semver.lt(version, '7.0.0'))) { - expect(output).toContain( - 'Your project has an older version of ESLint installed' - ) - expect(output).toContain('Please upgrade to v7 or later') - } else { - expect(output).toContain( - 'Error: Comments inside children section of tag should be placed inside braces' - ) - } + test('ignore during builds', async () => { + const { stdout, stderr } = await nextBuild(dirIgnoreDuringBuilds, [], { + stdout: true, + stderr: true, + }) + + const output = stdout + stderr + expect(output).not.toContain('Failed to compile') + expect(output).not.toContain( + 'Error: Comments inside children section of tag should be placed inside braces' + ) }) }) @@ -88,18 +84,9 @@ describe('ESLint', () => { }) const output = stdout + stderr - const version = await eslintVersion() - - if (!version || (version && semver.lt(version, '7.0.0'))) { - expect(output).toContain( - 'Your project has an older version of ESLint installed' - ) - expect(output).toContain('Please upgrade to v7 or later') - } else { - expect(output).toContain( - 'Error: Comments inside children section of tag should be placed inside braces' - ) - } + expect(output).toContain( + 'Error: Comments inside children section of tag should be placed inside braces' + ) }) }) }) From f57a0469e7f6799d6d3ac0db79a783a7078b0304 Mon Sep 17 00:00:00 2001 From: Houssein Djirdeh Date: Tue, 8 Jun 2021 12:26:46 -0400 Subject: [PATCH 2/6] adds eslint: dirs flag to next.config.js --- docs/basic-features/eslint.md | 14 +++++++-- packages/next/build/index.ts | 5 +++- packages/next/cli/next-lint.ts | 17 ++++++----- packages/next/lib/eslint/runLintCheck.ts | 17 ++--------- packages/next/lib/find-dir.ts | 13 --------- packages/next/lib/verifyAndLint.ts | 15 +++++++++- .../eslint/custom-directories/.eslintrc | 7 +++++ .../eslint/custom-directories/custom/index.js | 7 +++++ .../eslint/custom-directories/next.config.js | 5 ++++ .../eslint/custom-directories/pages/index.js | 8 +++++ .../eslint/custom-directories/utils/index.js | 3 ++ test/integration/eslint/test/index.test.js | 29 +++++++++++++++++-- 12 files changed, 99 insertions(+), 41 deletions(-) delete mode 100644 packages/next/lib/find-dir.ts create mode 100644 test/integration/eslint/custom-directories/.eslintrc create mode 100644 test/integration/eslint/custom-directories/custom/index.js create mode 100644 test/integration/eslint/custom-directories/next.config.js create mode 100644 test/integration/eslint/custom-directories/pages/index.js create mode 100644 test/integration/eslint/custom-directories/utils/index.js diff --git a/docs/basic-features/eslint.md b/docs/basic-features/eslint.md index d94a809f68bab..d4f2c5eb4018c 100644 --- a/docs/basic-features/eslint.md +++ b/docs/basic-features/eslint.md @@ -46,10 +46,20 @@ If you do not want ESLint to run as a build step, refer to the documentation for ## Linting Custom Directories -By default, Next.js will run ESLint for all files in the `pages/`, `components/`, and `lib/` directories. However, you can specify other custom directories to run by using the `--dir` flag in `next lint`: +By default, Next.js will run ESLint for all files in the `pages/`, `components/`, and `lib/` directories. However, you can specify which directories using the `dirs` option in the `eslint` config in `next.config.js` for production builds: + +```js +module.exports = { + eslint: { + dirs: ['pages', 'utils'], // Only run ESLint on the 'pages' and 'utils' directories during production builds (next build) + }, +} +``` + +Similarly, the `--dir` flag can be used for `next lint`: ```bash -npx next lint --dir utils --dir custom +npx next lint --dir pages --dir utils ``` ## ESLint Plugin diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 292b2aae30f1b..56b2339f9bd8a 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -212,12 +212,15 @@ export default async function build( typeCheckingSpinner.stopAndPersist() } - if (!Boolean(config.eslint?.ignoreDuringBuilds)) { + const ignoreESLint = Boolean(config.eslint?.ignoreDuringBuilds) + const lintDirs = config.eslint?.dirs + if (!ignoreESLint) { await nextBuildSpan .traceChild('verify-and-lint') .traceAsyncFn(async () => { await verifyAndLint( dir, + lintDirs, config.experimental.cpus, config.experimental.workerThreads ) diff --git a/packages/next/cli/next-lint.ts b/packages/next/cli/next-lint.ts index 65923e42202f2..02e4216008fb8 100755 --- a/packages/next/cli/next-lint.ts +++ b/packages/next/cli/next-lint.ts @@ -57,14 +57,15 @@ const nextLint: cliCommand = (argv) => { } const dirs: string[] = args['--dir'] - const lintDirs = dirs - ? dirs.reduce((res: string[], d: string) => { - const currDir = join(baseDir, d) - if (!existsSync(currDir)) return res - res.push(currDir) - return res - }, []) - : null + const lintDirs = (dirs ?? ['pages', 'components', 'lib']).reduce( + (res: string[], d: string) => { + const currDir = join(baseDir, d) + if (!existsSync(currDir)) return res + res.push(currDir) + return res + }, + [] + ) runLintCheck(baseDir, lintDirs) .then((results) => { diff --git a/packages/next/lib/eslint/runLintCheck.ts b/packages/next/lib/eslint/runLintCheck.ts index 6a2636c9583e7..29595c40a4902 100644 --- a/packages/next/lib/eslint/runLintCheck.ts +++ b/packages/next/lib/eslint/runLintCheck.ts @@ -9,7 +9,6 @@ import { formatResults } from './customFormatter' import { writeDefaultConfig } from './writeDefaultConfig' import { getPackageVersion } from '../get-package-version' -import { findDir } from '../find-dir' import { findPagesDir } from '../find-pages-dir' import { CompileError } from '../compile-error' import { @@ -31,7 +30,7 @@ const linteableFiles = (dir: string) => { async function lint( deps: NecessaryDependencies, baseDir: string, - lintDirs: string[] | null, + lintDirs: string[], eslintrcFile: string | null, pkgJsonPath: string | null ): Promise { @@ -75,8 +74,6 @@ async function lint( } const pagesDir = findPagesDir(baseDir) - const componentsDir = findDir(baseDir, 'components') - const libDir = findDir(baseDir, 'lib') if (nextEslintPluginIsEnabled) { let updatedPagesDir = false @@ -101,15 +98,7 @@ async function lint( } } - // If no directories to lint are provided, the pages, components, and lib directories will be linted - const filesToLint = lintDirs - ? lintDirs.map(linteableFiles) - : [pagesDir, componentsDir, libDir] - .filter((dir) => dir && dir.length > 0) - .map(linteableFiles) - - const results = await eslint.lintFiles(filesToLint) - + const results = await eslint.lintFiles(lintDirs.map(linteableFiles)) if (ESLint.getErrorResults(results)?.length > 0) { throw new CompileError(await formatResults(baseDir, results)) } @@ -118,7 +107,7 @@ async function lint( export async function runLintCheck( baseDir: string, - lintDirs: string[] | null, + lintDirs: string[], lintDuringBuild: boolean = false ): Promise { try { diff --git a/packages/next/lib/find-dir.ts b/packages/next/lib/find-dir.ts deleted file mode 100644 index 2135c30c41de0..0000000000000 --- a/packages/next/lib/find-dir.ts +++ /dev/null @@ -1,13 +0,0 @@ -import path from 'path' -import { existsSync } from './find-pages-dir' - -export function findDir(dir: string, dirName: string): string { - // prioritize ./pages over ./src/pages - let curDir = path.join(dir, dirName) - if (existsSync(curDir)) return curDir - - curDir = path.join(dir, dirName) - if (existsSync(curDir)) return curDir - - return '' -} diff --git a/packages/next/lib/verifyAndLint.ts b/packages/next/lib/verifyAndLint.ts index 3b0a48a56157f..798f2b6ff9360 100644 --- a/packages/next/lib/verifyAndLint.ts +++ b/packages/next/lib/verifyAndLint.ts @@ -1,8 +1,11 @@ import chalk from 'chalk' import { Worker } from 'jest-worker' +import { existsSync } from 'fs' +import { join } from 'path' export async function verifyAndLint( dir: string, + configLintDirs: string[] | undefined, numWorkers: number | undefined, enableWorkerThreads: boolean | undefined ): Promise { @@ -17,7 +20,17 @@ export async function verifyAndLint( lintWorkers.getStdout().pipe(process.stdout) lintWorkers.getStderr().pipe(process.stderr) - const lintResults = await lintWorkers.runLintCheck(dir, null, true) + const lintDirs = (configLintDirs ?? ['pages', 'components', 'lib']).reduce( + (res: string[], d: string) => { + const currDir = join(dir, d) + if (!existsSync(currDir)) return res + res.push(currDir) + return res + }, + [] + ) + + const lintResults = await lintWorkers.runLintCheck(dir, lintDirs, true) if (lintResults) { console.log(lintResults) } diff --git a/test/integration/eslint/custom-directories/.eslintrc b/test/integration/eslint/custom-directories/.eslintrc new file mode 100644 index 0000000000000..22b9919b24161 --- /dev/null +++ b/test/integration/eslint/custom-directories/.eslintrc @@ -0,0 +1,7 @@ +{ + "extends": "next", + "root": true, + "rules": { + "@next/next/no-html-link-for-pages": 0 + } +} diff --git a/test/integration/eslint/custom-directories/custom/index.js b/test/integration/eslint/custom-directories/custom/index.js new file mode 100644 index 0000000000000..3735bac42588d --- /dev/null +++ b/test/integration/eslint/custom-directories/custom/index.js @@ -0,0 +1,7 @@ +const Custom = () => ( +
+