إضافة ESLint

يوفر Next.js إضافة ESLint، eslint-plugin-next، مضمنة مسبقًا ضمن التكوين الأساسي الذي يمكّن من اكتشاف المشكلات الشائعة في تطبيق Next.js.

المرجع

يتم استخدام مجموعات القواعد الموصى بها من إضافات ESLint التالية ضمن eslint-config-next:

سيأخذ هذا الأسبقية على التكوين من next.config.js.

القواعد

مجموعة القواعد الكاملة هي كما يلي:

مفعّل في التكوين الموصى بهالقاعدةالوصف
Check Icon@next/next/google-font-displayفرض سلوك font-display مع خطوط جوجل.
Check Icon@next/next/google-font-preconnectالتأكد من استخدام preconnect مع خطوط جوجل.
Check Icon@next/next/inline-script-idفرض سمة id على مكونات next/script مع محتوى مضمن.
Check Icon@next/next/next-script-for-gaتفضيل مكون next/script عند استخدام السكريبت المضمن لتحليلات جوجل.
Check Icon@next/next/no-assign-module-variableمنع تعيين متغير module.
Check Icon@next/next/no-async-client-componentمنع مكونات العميل من أن تكون دوال غير متزامنة.
Check Icon@next/next/no-before-interactive-script-outside-documentمنع استخدام استراتيجية beforeInteractive لـ next/script خارج pages/_document.js.
Check Icon@next/next/no-css-tagsمنع علامات أنماط CSS يدوية.
Check Icon@next/next/no-document-import-in-pageمنع استيراد next/document خارج pages/_document.js.
Check Icon@next/next/no-duplicate-headمنع استخدام مكرر لـ <Head> في pages/_document.js.
Check Icon@next/next/no-head-elementمنع استخدام عنصر <head>.
Check Icon@next/next/no-head-import-in-documentمنع استخدام next/head في pages/_document.js.
Check Icon@next/next/no-html-link-for-pagesمنع استخدام عناصر <a> للتنقل بين صفحات Next.js الداخلية.
Check Icon@next/next/no-img-elementمنع استخدام عنصر <img> بسبب بطء LCP وزيادة استهلاك النطاق الترددي.
Check Icon@next/next/no-page-custom-fontمنع الخطوط المخصصة للصفحات فقط.
Check Icon@next/next/no-script-component-in-headمنع استخدام next/script في مكون next/head.
Check Icon@next/next/no-styled-jsx-in-documentمنع استخدام styled-jsx في pages/_document.js.
Check Icon@next/next/no-sync-scriptsمنع السكربتات المتزامنة.
Check Icon@next/next/no-title-in-document-headمنع استخدام <title> مع مكون Head من next/document.
Check Icon@next/next/no-typosمنع الأخطاء الإملائية الشائعة في دوال جلب البيانات في Next.js
Check Icon@next/next/no-unwanted-polyfillioمنع تكرار polyfills من Polyfill.io.

نوصي باستخدام تكامل مناسب لعرض التحذيرات والأخطاء مباشرة في محرر الأكواد أثناء التطوير.

أمثلة

فحص المجلدات والملفات المخصصة

افتراضيًا، سيقوم Next.js بتشغيل ESLint لجميع الملفات في مجلدات pages/، app/، components/، lib/، و src/. ومع ذلك، يمكنك تحديد المجلدات باستخدام خيار dirs في تكوين eslint في next.config.js لعمليات البناء الإنتاجية:

next.config.js
module.exports = {
  eslint: {
    dirs: ['pages', 'utils'], // تشغيل ESLint فقط على مجلدات 'pages' و 'utils' أثناء عمليات البناء الإنتاجية (next build)
  },
}

بالمثل، يمكن استخدام وسيطات --dir و --file مع next lint لفحص مجلدات وملفات محددة:

Terminal
next lint --dir pages --dir utils --file bar.js

تحديد مجلد جذر ضمن monorepo

إذا كنت تستخدم eslint-plugin-next في مشروع حيث لم يتم تثبيت Next.js في مجلد الجذر الخاص بك (مثل monorepo)، يمكنك إخبار eslint-plugin-next بمكان العثور على تطبيق Next.js الخاص بك باستخدام خاصية settings في ملف .eslintrc:

eslint.config.mjs
import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
  // import.meta.dirname متاح بعد Node.js v20.11.0
  baseDirectory: import.meta.dirname,
})

const eslintConfig = [
  ...compat.config({
    extends: ['next'],
    settings: {
      next: {
        rootDir: 'packages/my-app/',
      },
    },
  }),
]

export default eslintConfig

يمكن أن يكون rootDir مسارًا (نسبي أو مطلق)، نمطًا (مثل "packages/*/")، أو مصفوفة من المسارات و/أو الأنماط.

تعطيل الذاكرة المؤقتة

لتحسين الأداء، يتم تخزين معلومات الملفات التي تمت معالجتها بواسطة ESLint في ذاكرة مؤقتة افتراضيًا. يتم تخزين هذا في .next/cache أو في مجلد البناء المحدد لديك. إذا كنت تريد تضمين أي قواعد ESLint تعتمد على أكثر من محتوى ملف مصدر واحد وتحتاج إلى تعطيل الذاكرة المؤقتة، استخدم وسيطة --no-cache مع next lint.

Terminal
next lint --no-cache

تعطيل القواعد

إذا كنت ترغب في تعديل أو تعطيل أي قواعد مقدمة من الإضافات المدعومة (react، react-hooks، next)، يمكنك تغييرها مباشرة باستخدام خاصية rules في ملف .eslintrc:

eslint.config.mjs
import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
  // import.meta.dirname متاح بعد Node.js v20.11.0
  baseDirectory: import.meta.dirname,
})

const eslintConfig = [
  ...compat.config({
    extends: ['next'],
    rules: {
      'react/no-unescaped-entities': 'off',
      '@next/next/no-page-custom-font': 'off',
    },
  }),
]

export default eslintConfig

مع Core Web Vitals

يتم تفعيل مجموعة القواعد next/core-web-vitals عند تشغيل next lint لأول مرة واختيار خيار strict.

eslint.config.mjs
import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
  // import.meta.dirname متاح بعد Node.js v20.11.0
  baseDirectory: import.meta.dirname,
})

const eslintConfig = [
  ...compat.config({
    extends: ['next/core-web-vitals'],
  }),
]

export default eslintConfig

يقوم next/core-web-vitals بتحديث eslint-plugin-next لإظهار أخطاء في عدد من القواعد التي تكون تحذيرات افتراضيًا إذا كانت تؤثر على Core Web Vitals.

يتم تضمين نقطة الدخول next/core-web-vitals تلقائيًا للتطبيقات الجديدة المبنية باستخدام Create Next App.

مع TypeScript

بالإضافة إلى قواعد ESLint الخاصة بـ Next.js، سيضيف create-next-app --typescript أيضًا قواعد فحص TypeScript المحددة مع next/typescript إلى تكوينك:

eslint.config.mjs
import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
  // import.meta.dirname متاح بعد Node.js v20.11.0
  baseDirectory: import.meta.dirname,
})

const eslintConfig = [
  ...compat.config({
    extends: ['next/core-web-vitals', 'next/typescript'],
  }),
]

export default eslintConfig

هذه القواعد مبنية على plugin:@typescript-eslint/recommended. راجع typescript-eslint > Configs لمزيد من التفاصيل.

مع Prettier

يحتوي ESLint أيضًا على قواعد تنسيق الأكواد، والتي قد تتعارض مع إعداد Prettier الحالي لديك. نوصي بتضمين eslint-config-prettier في تكوين ESLint لجعل ESLint و Prettier يعملان معًا.

أولاً، قم بتثبيت التبعية:

Terminal
npm install --save-dev eslint-config-prettier

yarn add --dev eslint-config-prettier

pnpm add --save-dev eslint-config-prettier

bun add --dev eslint-config-prettier

ثم، أضف prettier إلى تكوين ESLint الحالي لديك:

eslint.config.mjs
import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
  // import.meta.dirname متاح بعد Node.js v20.11.0
  baseDirectory: import.meta.dirname,
})

const eslintConfig = [
  ...compat.config({
    extends: ['next', 'prettier'],
  }),
]

export default eslintConfig

تشغيل الفحص على الملفات المؤقتة

إذا كنت ترغب في استخدام next lint مع lint-staged لتشغيل الفاحص على ملفات git المؤقتة، ستحتاج إلى إضافة ما يلي إلى ملف .lintstagedrc.js في جذر مشروعك لتحديد استخدام وسيطة --file.

.lintstagedrc.js
const path = require('path')

const buildEslintCommand = (filenames) =>
  `next lint --fix --file ${filenames
    .map((f) => path.relative(process.cwd(), f))
    .join(' --file ')}`

module.exports = {
  '*.{js,jsx,ts,tsx}': [buildEslintCommand],
}

تعطيل الفحص أثناء عمليات البناء الإنتاجية

إذا كنت لا تريد أن يعمل ESLint أثناء next build، يمكنك تعيين خيار eslint.ignoreDuringBuilds في next.config.js إلى true:

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  eslint: {
    // تحذير: يسمح هذا لعمليات البناء الإنتاجية بالإكمال بنجاح حتى إذا
    // كان مشروعك يحتوي على أخطاء ESLint.
    ignoreDuringBuilds: true,
  },
}

export default nextConfig
const nextConfig = {
  eslint: {
    // تحذير: يسمح هذا لعمليات البناء الإنتاجية بالإكمال بنجاح حتى إذا
    // كان مشروعك يحتوي على أخطاء ESLint.
    ignoreDuringBuilds: true,
  },
}

export default nextConfig

ترحيل التكوين الحالي

إذا كان لديك بالفعل ESLint مضبوطًا في تطبيقك، نوصي بالتمديد من هذه الإضافة مباشرة بدلاً من تضمين eslint-config-next إلا إذا توفرت بعض الشروط.

مجموعة القواعد الموصى بها للإضافة

إذا كانت الشروط التالية صحيحة:

  • لديك واحدة أو أكثر من الإضافات التالية مثبتة بالفعل (إما بشكل منفصل أو من خلال تكوين مختلف مثل airbnb أو react-app):
    • react
    • react-hooks
    • jsx-a11y
    • import
  • قمت بتحديد parserOptions محددة مختلفة عن كيفية تكوين Babel داخل Next.js (هذا غير موصى به إلا إذا كنت قد خصصت تكوين Babel الخاص بك)
  • لديك eslint-plugin-import مثبتًا مع Node.js و/أو TypeScript resolvers محددة للتعامل مع الاستيرادات

ثم نوصي إما بإزالة هذه الإعدادات إذا كنت تفضل كيفية تكوين هذه الخصائص ضمن eslint-config-next أو التمديد مباشرة من إضافة ESLint لـ Next.js بدلاً من ذلك:

module.exports = {
  extends: [
    //...
    'plugin:@next/next/recommended',
  ],
}

يمكن تثبيت الإضافة بشكل طبيعي في مشروعك دون الحاجة إلى تشغيل next lint:

Terminal
npm install --save-dev @next/eslint-plugin-next

yarn add --dev @next/eslint-plugin-next

pnpm add --save-dev @next/eslint-plugin-next

bun add --dev @next/eslint-plugin-next

هذا يزيل خطر التصادمات أو الأخطاء التي يمكن أن تحدث بسبب استيراد نفس الإضافة أو المحلل عبر تكوينات متعددة.

إعدادات إضافية

إذا كنت تستخدم بالفعل تكوينًا منفصلاً لـ ESLint وتريد تضمين eslint-config-next، تأكد من أنه يتم تمديده أخيرًا بعد التكوينات الأخرى. على سبيل المثال:

eslint.config.mjs
import js from '@eslint/js'
import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
  // import.meta.dirname is available after Node.js v20.11.0
  baseDirectory: import.meta.dirname,
  recommendedConfig: js.configs.recommended,
})

const eslintConfig = [
  ...compat.config({
    extends: ['eslint:recommended', 'next'],
  }),
]

export default eslintConfig

تكوين next يتعامل بالفعل مع تعيين القيم الافتراضية لخصائص parser و plugins و settings. ليست هناك حاجة لإعادة تعريف أي من هذه الخصائص يدويًا إلا إذا كنت بحاجة إلى تكوين مختلف لحالة استخدامك.

إذا قمت بتضمين أي تكوينات أخرى قابلة للمشاركة، سوف تحتاج إلى التأكد من عدم تعديل أو استبدال هذه الخصائص. وإلا، نوصي بإزالة أي تكوينات تشارك السلوك مع تكوين next أو التمديد مباشرة من إضافة Next.js لـ ESLint كما ذكر أعلاه.