去年にNext.jsの学習をしていたのですが、Amplifyとの相性が悪くて(Cognitoの認証周りでたいへん苦労した)使うのを辞めていました。
ただ、久しぶりに色々調べてみると、どうやら公式ドキュメントにもNext.js用のチュートリアルがあるみたいなのでちょっとチャレンジしてみます。
ついでに、ESLint + Prettierまわりも何やら推奨設定が変わってきてるそうなのでその辺にも対応した防備録的な記事を目指します。
(また来年新しい記事を書いてそう・・・)
下記は全てWindows環境で行っています。
必要最低限の環境構築
まず最初にこの記事を見てる方は大丈夫だと思うんですが、下記の環境は整えて下さい
章タイトルから察する方はプロジェクト構築へ飛ばして読んで下さい。
- Node.js(v10.x 以上)
- npm(v5.x 以上)、後々yarnを使いますが、自分はWindows環境なので一番最初にnpxを使います。
この記事を参考にする人はついでにyarnも入れといて下さい。 - git(v2.14.1以上)
上記が整っていれば最初のセットアップは進める事が出来ると思います。
プロジェクト構築
Next.jsのプロジェクトを作成する
Next.jsのプロジェクトを作成します。
LinuxやMac環境では
yarn create next-app プロジェクト名
でも作成可能だと思いますが、WindowsはNodeのパスに半角スペースが入ってる人が多いと思いますのでnpxでプロジェクトを作成します。
npx create-next-app next-amplified
プロジェクト名はAmplifyのドキュメントに習ってnext-amplified
にしてますが、なんでもいいです。
とりあえず問題無く動くか確認しておきたいので、Next.jsプロジェクトを実行してみます。
cd next-amplified yarn dev
http://localhost:3000
にアクセスして問題無く表示されれば大丈夫です。
TypeScriptのセットアップ
tscのインストール
もしTypeScriptのコンパイラがまだグローバルにインストールされてない場合はインストールして置いて下さい。
npm install -g typescript
tsconfig.jsonの作成
プロジェクトのルートディレクトリ(この場合はnext-amplified
直下)にtsconfig.json
を作成します。
tsc --init
上記のコマンドでtsconfig.json
が作成されます。
最初は別に空ファイルでも良いんですが、この辺は好みです。
開発に必要なライブラリの追加
あとは必要な依存ライブラリを入れておきます。
yarn add -D typescript @types/react @types/node
試しに動かしてみる
上記までで多分動きます。
試しにpagesに入ってるファイルをTypeScriptのファイルに変更してみます。
めんどくさいのでpages/index.js
のみをpages/index.tsx
に名前を変更します。
特に他の設定無しで、yarn dev
を実行すればhttp://localhost:3000
に先ほどと同様のページが表示されているかと思います。
(TypeScriptの設定がおかしければ、ここでコンパイルされずに表示されないので)
整理する
とりあえずコンパイルまでは良さそうなので一旦ファイルを整理します。
pages
ディレクトリはsrc
ディレクトリを作成してその直下に配置することにします。
(Next.jsのv9からデフォルトでsrc
直下でも認識するようになったようです。)
ついでにstyles
は削除しています。
やっぱり後で必要だったので残します
mkdir src mv pages src
あと、api
と_app.js
も今は不要なのでいったん消します。
Remove-Item .\src\pages\api\ -Recurse Remove-Item .\src\pages\_app.js
色々消してコンパイルが通らなくなるので、index.tsx
も編集しておきます。
import React from 'react' export default function Home() { return ( <div>hoge</div> ) }
とりあえずここまでで問題無いか実行してみます。
yarn dev
問題無ければ、Linterの設定などに行きましょう。
ESLint + Prettierの設定
構成
以前はESLintのプラグインでPrettierを走らせていたのですが、下記の記事でも紹介されているとおり公式の推奨が明示されました。
Prettier と ESLint の組み合わせの公式推奨が変わり plugin が不要になった
よって、この設定に従いprettier-eslintを利用してPrettier → ESLintと走るような環境を構築します。
何はともあれESLintとPrettierをセットアップします。
(余談ですが、この辺からIDEを利用した方が色々補完が効いて楽かもしれません)
ESLint
ESLintのインストール
ESLintをTypeScriptで走るようにセットアップしていきます。
この辺は昔と変わらず、素直にインストールします。
yarn add -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react
eslintをグローバル環境でセットアップしてる人は、適宜って感じです。
ESLintの設定
ESLintの設定ファイル.eslintrc.js
をプロジェクトのルートディレクトリに置いておきます。
こちらも、以前の設定と変更無しです。
module.exports = { env: { browser: true, node: true, es6: true }, parser: '@typescript-eslint/parser', parserOptions: { ecmaFeatures: { jsx: true }, sourceType: "module" }, plugins: [ "react", '@typescript-eslint' ], extends: [ "eslint:recommended", "plugin:react/recommended", 'plugin:@typescript-eslint/recommended', ], rules: { }, overrides: [ { 'files': ["**/*.tsx"], 'rules': { 'react/prop-types': 'off' } } ] };
ESLintが走る用のコマンドをpackage.json
に記載しておきます。
"scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "eslint --ext .ts,.js,.tsx,.jsx src/**/*" },
チェックする対象は全てsrcディレクトリ内に収まると思うのでこうしておきます。
試しにsrc/pages/index.tsx
にわざとセミコロンを付けてESLintでチェックしてみます。
import React from 'react' export default function Home() { return ( <div>hoge</div> ) };
yarn lint
error Unnecessary semicolon @typescript-eslint/no-extra-semi
が出てる筈です。
良さそうなのでついでにfixも試してみます。
yarn lint --fix
おそらくセミコロンが消滅したと思います。
ESLintのセットアップは大丈夫そうです。
Prettier
ESLintとPrettierの競合を解消する方法は数種類ありますが、今回は最近TLで見かけたPrettier公式の推奨設定を参考にします。
(なにはともあれ、公式の推奨に従っておくのが賢い筈です)
Prettierのインストール
とりあえずPrettier、eslint-config-prettierをインストールします。
yarn add -D prettier eslint-config-prettier
とりあえずPrettierが動作するか試してみます。index.tsx
の最後に改行を入れまくるなどしてフォーマッタで修正されるであろう形にしてみて下さい。
その後
prettier --write "src/**/*.{js,jsx,ts,tsx}"
で修正されるかチェックします。問題無ければPrettierの設定は完了しているはずです。
eslint-config-prettierの設定
PrettierとESLintの競合を解消するために.eslintrc.js
を編集します。
~ extends: [ "eslint:recommended", "plugin:react/recommended", 'plugin:@typescript-eslint/recommended', "prettier", "prettier/@typescript-eslint", "prettier/react", ], ~
ESLintのextends
の設定は上から順に適応され、後ろの方で上書きされていきます。
なので
~ extends: [ [prettier以外のプラグインの設定], "prettier", "prettier/[対応されていプラグイン]", ], ~
という順番で記載することにより、競合が解消されるようです。
(ただし、この辺は理解が曖昧なので、もし挙動が異なっていたら後々修正します。)
※ 2021-06-28追記
"prettier"以降の記述は不要になりました。prettierを利用する時は"prettier"のみextendsに記載すれば良くなったみたいです。
ESLint + Prettier
たぶん上記まで対応はOKの筈なので、ESLintとPrettierが両方走るスクリプトを追加します。
ESLintとPrettierを両方実行するために、npm-run-all
をインストールします。
yarn add -D npm-run-all
このライブラリでpackage.json
に記載のあるscripts
を順次/並列実行できるようになります。
~ "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint --ext .ts,.js,.tsx,.jsx src/**/* --fix", "fix:prettier": "prettier --check --write \"src/**/*.{js,jsx,ts,tsx}\"" ~
これでyarn fix
でeslintとprettierが走るようになりました。
こまかいこと
Prettier→ESLintの順番で実行すれば.prettierrc.js
要らないんじゃね?とも思いましたが、細かいフォーマット規則も後々付け加えられるので.prettierrc.js
も準備します。
prettierrc
はjsonで作られてることが多そうなイメージですが、eslintrc
もjsで用意してるので一応合わせます。
個人的にセミコロン絶対に許さないマンになりたいのでその辺の設定をしておきます。
module.exports = { trailingComma: "es5", tabWidth: 2, semi: false, singleQuote: true, }
.eslintrc.js
の方にもセミコロン絡みの設定をしておきます。
~ rules: { "semi": ["error", "never", {"beforeStatementContinuationChars": "never"}], "semi-spacing": ["error", {"after": true, "before": false}], "semi-style": ["error", "first"], "no-extra-semi": "error", "no-unexpected-multiline": "error", "no-unreachable": "error" }, ~
※20210210加筆
なんかESLintに怒られた(Warning: React version not specified in eslint-plugin-react settings.
)ので、.eslintrc.js
の該当箇所に設定を追記。
~ settings: { react: { version: 'detect', }, }, ~
これで大丈夫です。
この辺まで来たらIDEによってはファイルウォッチャーに登録しても良さそうです。
ちょっと長くなったのでAmplifyに関しては別記事に分けます。