Next.jsに専用のESLintが追加された!
Next.js11がついに発表されましたね。
next/script
、Next.js Liveなど、興味深い機能が色々ですが、自分が地味に嬉しかったのはNext.js専用のESLint設定がデフォルトでサポートされたことです。
create-next-app
でESLint設定済みのNext.jsプロジェクトが作成できる
ReactやNext.jsのプロジェクトを立ち上げる際、結構面倒くさい難しいのがESLintの設定です。
.eslintrc
ファイルの記述とか、extends
の記述順によって優先されるルールとかも変わってくるので、慣れないうちはなかなか難しい作業でしょう。(自分はいまだに試行錯誤してます…)
しかし、今ではcreate-next-app
を使うと、専用のESLintが設定済みのNext.jsプロジェクトを作成してくれます。
実際にコマンドを実行した結果を見ていきましょう。
$ npx create-next-app app --typescript # `app`は任意のプロジェクト名でOK
Creating a new Next.js app in /Users/johnnydoe/Documents/app
Using npm.
Installing dependencies:
- react
- react-dom
- next
added 268 packages, and audited 269 packages in 9s
44 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Installing devDependencies:
- eslint
- eslint-config-next # ←Next.js用のESLint設定
- typescript
- @types/react
added 217 packages, and audited 486 packages in 10s
78 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Initialized a git repository.
Success! Created app at /Users/johnnydoe/Documents/app
Inside that directory, you can run several commands:
npm run dev
Starts the development server.
npm run build
Builds the app for production.
npm start
Runs the built app in production mode.
We suggest that you begin by typing:
cd app
npm run dev
メッセージを見ると、この時点でESLintとNext.js専用のeslint-config-next
をインストールしてくれているのがわかります。
さらに作成されたプロジェクトを見ると、すでに.eslintrc
ファイルが作成されています。
package.json
のscripts
にも"link": "next lint"
というコマンドが新規で追加されています。
{
"name": "app",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "11.0.0",
"react": "17.0.2",
"react-dom": "17.0.2"
},
"devDependencies": {
"@types/react": "17.0.11",
"eslint": "7.28.0",
"eslint-config-next": "11.0.0",
"typescript": "4.3.3"
}
}
このnext lint
を実行すると、以下の処理が実行されるようです。
- (まだプロジェクトにインストールされていない場合、)
eslint
とeslint-config-next
をインストールするよう促すメッセージを表示。 - (まだプロジェクト内に作成されてない場合、)
.eslintrc
を作成。 - プロジェクト内のコードに
warning
やerror
が無いか、設定されているESLintルールに沿って検査。
1.と2.については、既存のNext.js10のプロジェクトをNext.js11へアップグレードした場合などに便利ですね。
eslint-config-next
はどんな設定になっているのか
eslint-config-nextのソースコードを見てみると、以下のような設定になってました。
module.exports = {
extends: [
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:@next/next/recommended',
],
plugins: ['import', 'react', 'jsx-a11y'],
rules: {
'import/no-anonymous-default-export': 'warn',
'react/react-in-jsx-scope': 'off',
'react/prop-types': 'off',
'jsx-a11y/alt-text': [
'warn',
{
elements: ['img'],
img: ['Image'],
},
],
},
**省略**
}
react
、react-hooks
、import
、jsx-a11y
など、ReactやNext.jsのプロジェクトに導入されることの多いプラグインは一通り入ってますね。@next/next
はNext.js独自のルールのようです。
どんなルールがあるのか
まだ全部検証できているわけではないですが、デフォルトの状態で有効になっているNext.js独自のルールをいくつかピックアップしてみます。
no-html-link-for-pages
Do not use the HTML
<a>
tag to navigate to ${hrefPath}. Use Link from 'next/link' instead. See: https://nextjs.org/docs/messages/no-html-link-for-pages.
サイト内リンクを<a>
タグで貼ろうとすると、next/link
からインポートした<Link>
コンポーネントを使うように警告されます。
no-image-element
Do not use
<img>
. Use Image from 'next/image' instead. See https://nextjs.org/docs/messages/no-img-element.
画像を貼る際に<img>
タグを使おうとすると、next/Image
からインポートした<Image>
コンポーネントを使うよう警告されます。
no-sync-script
External synchronous scripts are forbidden. See: https://nextjs.org/docs/messages/no-sync-scripts.
<script>
タグで、なにかしらのスクリプトを読み込もうとすると、「(Webサイトのパフォーマンスに影響を与える可能性のある)同期スクリプトが使用されました」とエラーが出ます。代わりにnext/script
からインポートした<Script>
コンポーネントを使用すると、そのスクリプトが必要となったタイミングで読み込んでくれるようです。
終わりに
公式で用意されているESLintルールは、総じてNext.jsの機能を最大限に発揮させるために制定されている感じですね。
恐らく実務で使用する上では、これらのデフォルトで設定されているルールを微調整する必要はあるでしょうが、これまでは一から自分たちで設定する必要があったことを考えれば、こうして公式が最低限必要なルールを制定してくれるのは、とても助かりますね。
修正とお詫び
本記事において、当初「Next.jsの<Link>
コンポーネントとjsx-a11y/achor-is-valid
を併用した際に起こるエラー」について、さも公式ESLintが対応しているかのように紹介していましたが、これは誤りでした。
もう一度、eslint-config-nextのソースコードをご覧ください。
module.exports = {
extends: [
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:@next/next/recommended',
],
plugins: ['import', 'react', 'jsx-a11y'],
rules: {
'import/no-anonymous-default-export': 'warn',
'react/react-in-jsx-scope': 'off',
'react/prop-types': 'off',
'jsx-a11y/alt-text': [
'warn',
{
elements: ['img'],
img: ['Image'],
},
],
},
**省略**
}
ご覧の通り、jsx-a11y/alt-text
しか有効になってません。
つまりNext.jsのデフォルトのESLint設定ではそもそもjsx-a11y/anchor-is-valid
のエラーなど起こりようが無いと言うことですね…
当初の内容をそのままにしておくと間違った認識を広めてしまいかねないので、「<Link>
コンポーネントとjsx-a11y/anchor-is-valid
を併用する際に起こる問題」について言及した部分に関しては、すべて削除しました。
私の思い込みと確認不足によって誤った情報を載せてしまい、大変申し訳ありませんでした。🙇♂️
Discussion