とにかくやるだけ!Next.js + TypeScript + Chakra UI + ESLint + Prettier + commitlint + Jest + huskyの環境構築よくばりセット

JavaScript(TypeScript)開発環境の構築はセットアップすることが多くて大変ですよね。。。

ESLintを設定したり、Prettierを設定したり、テストを設定したりとやることが尽きません。
本記事のタイトルを見るだけでもその多さに疲れてしまいます。

ただでさえやることが多いのに最初の環境構築の手順なんかは大体忘れているので、環境構築のたびにいろんなサイトを横断してやり方を調べる・思い出すことに時間を費やしてしまっています。

そこで今回は自身の備忘録もふまえて、よく使いそうな構成の環境構築手順をまるっとまとめて記していきます。

この記事でできること
  • Next.js + TypeScriptの環境を構築できる
  • Chakra UIとChakra UIカスタムテーマを使用する環境を構築できる
  • ESLint, Prettier, commitlintによるフォーマット・チェックができる
  • Jest + React Testing Libraryでユニットテストを実行できる
  • husky + lint-stagedによるフォーマット・コードチェック・テストの自動化ができる
  • WebStorm(JetBrains製IDE)を利用した環境構築と設定ができる
目次

プロジェクト作成

まずは新規プロジェクトの作成。
ここではWebStormを使いますので、別のエディタやIDEを使用している場合はこの手順は無視してそれぞれのやり方でプロジェクトを作成してください。

Githubなどのリポジトリがすでにあるかどうかでプロジェクト作成方法が変わります。

新規作成

リポジトリを作成していない場合はこちら。

下記画像を参考に左から順に実施します。
クリックすると拡大できます。

リポジトリからクローン

すでにあるリポジトリからクローンしてプロジェクトを作成したい場合はこちら。

下記画像を参考に左から順に実施します。
クリックすると拡大できます。

Gitの設定

プロジェクト全体のソースコードを管理するためにgitを設定します。

STEP
Gitの初期化

rootで下記のコマンドを実行します。

git init

コマンドはIDE下部のターミナルからも実行可能です。
以降のコマンドはすべてIDEのターミナルから実行するものとします。

STEP
.gitignoreの作成

ついでに空の.gitignoreも作っておきます。

以降は必要に応じてリポジトリ管理不要なものを追記していきましょう。

これでプロジェクトの作成は完了!

Next.js + TypeScript

続いてNext.jsの環境構築を行います。
公式で用意されている便利なセットアップコマンドがあるのでそれを利用します。

参考リンク

セットアップ

STEP
インストール

rootで下記のコマンドを実行します。

npx create-next-app@latest --ts next
  • TypeScriptを使用するので--tsオプションを指定しています。
  • 最後の引数がプロジェクト名(フォルダ名)で、上記ではnextです。

処理が完了すると以下のように表示されます。

STEP
WebStormの実行設定

この状態でnpm run devを実行しても動きますが、WebStormからも実行できるように設定を施します。

下記画像を参考に左から順に実施します。
クリックすると拡大できます。

STEP
実行確認

設定後、実行ボタンを押してlocalhost:3000へアクセスして画面が表示されればOK!

ここまでで一旦コミットしておくと安心!

フォルダ構成の変更

create-next-appで作成したフォルダの構成は以下のようになっています。

next/
├── .next/
├── node_modules/
├── pages/
├── public/
└── styles/

next直下にソースコードがずらっと並んでしまい見通しが悪いです。

そのため、srcを作成してpagesstylesを移動します。

変更後のフォルダ構成は以下のようになります。

next/
├── .next/
├── node_modules/
├── public/
└── src/
    ├── pages/
    └── styles/

next.config.jsなどの設定ファイル系はsrcへ移動せず、next直下に置いたままにしておきます。

Next.jsアプリケーション全体のフォルダ構成については以下の記事で紹介しています。

パスのエイリアス設定

フォルダ構成の変更のついでに、モジュールパスのエイリアスを設定しておきます。

next/tsconfig.jsoncompilerOptionsに以下のように設定を追加します。

{
  "compilerOptions": {
...
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
...
}

以降は次のようにパスを指定できます。相対パスを書かなくて済むので楽♪

import {Sample} from '@/pages/test/Sample'
参考リンク

以上でNext.jsの設定は完了!

コミットしておきましょう!

Prettier

コードフォーマットを行うためにPrettierを導入します。

参考リンク

セットアップ

STEP
インストール

まずはインストール。
rootで下記のコマンドを実行します。

npm i -D prettier
STEP
設定ファイルの作成

続いてフォーマットルールの設定。
root.prettierrc.toml(ファイル形式はお好みでOK)を作成します。

root/
├── next/
├── node_modules/
├── .prettierrc.toml  <- 追加

設定ファイルの中身は以下。公式と同じように設定。

trailingComma = 'es5'
tabWidth = 2
semi = false
singleQuote = true

各ファイル形式ごとの書き方は下記リンク先のものをベースにすればOKです。

参考リンク

WebStormの設定

WebStorm上でPrettierによるフォーマットを行うために、以下のように設定しておきます。

Prettierによるコードフォーマット対象とするファイル形式を増やしたい場合は、「次のファイルに実行」の入力欄に拡張子を追加しておく必要があります。

これでPrettierの設定は終わり。

コミットしておきましょう!

ESLint

コードの静的検証にはESLintを使用します。

参考リンク

セットアップ

STEP
不要ファイルの削除

まず最初にcreate-next-appを実行した際にnext配下に.eslintrc.jsonが作成されていますので、それを削除します。

next/
├── .next/
├── node_modules/
├── public/
├── src/
├── .eslintrc.json  <-  削除
STEP
インストール

rootでインストールコマンドを実行します。

npm i -D eslint eslint-config-prettier

eslint-config-prettierはPrettierを使用する際に不要となるESLintのルールを無効化するものです。

STEP
設定ファイルの作成

Next.jsアプリケーション内で適用するESLintルールを作成します

初期設定に関しては対話形式で作成するのが個人的にわかりやすいと思います。
nextで下記コマンドを実行して質問に回答していきましょう。

npx eslint --init
You can also run this command directly using 'npm init @eslint/config'.
Need to install the following packages:
  @eslint/create-config
Ok to proceed? (y) y

? How would you like to use ESLint? … 
  To check syntax only
❯ To check syntax and find problems
  To check syntax, find problems, and enforce code style

? What type of modules does your project use? … 
❯ JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these

? Which framework does your project use? … 
❯ React
  Vue.js
  None of these

? Does your project use TypeScript? › Yes

? Where does your code run? …  (Press <space> to select, <a> to toggle all, <i> to invert selection)
✔ Browser
   Node

? What format do you want your config file to be in? … 
  JavaScript
❯ YAML
  JSON

eslint-plugin-react@latest @typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest
? Would you like to install them now with npm? › Yes

...
中略
...

Successfully created .eslintrc.yml file
STEP
設定ファイルの修正

対話形式での処理が完了後、next/.eslintrc.ymlが作成されます。
ファイルの中身は以下のようになっているはずです。

env:
  browser: true
  es2021: true
extends:
  - eslint:recommended
  - plugin:react/recommended
  - plugin:@typescript-eslint/recommended
parser: '@typescript-eslint/parser'
parserOptions:
  ecmaFeatures:
    jsx: true
  ecmaVersion: latest
  sourceType: module
plugins:
  - react
  - '@typescript-eslint'
rules: {}

設定内容を以下のように修正して完了です!

env:
  browser: true
  es2021: true
extends:
  - next/core-web-vitals
  - eslint:recommended
  - plugin:react/recommended
  - plugin:@typescript-eslint/recommended
  - prettier
parser: '@typescript-eslint/parser'
parserOptions:
  ecmaFeatures:
    jsx: true
  ecmaVersion: latest
  sourceType: module
plugins:
  - react
  - '@typescript-eslint'
rules: {
  react/react-in-jsx-scope: off
}

WebStormの設定

WebStorm上のコードチェックにESLintを使用するように設定します。

これでESLintの設定は終わり。

コミットしておきましょう!

環境変数

特別な設定はしないで、Next.js標準を使用します。

参考リンク

ちなみにprocess.envに展開される値にはJavaScriptのオブジェクトのように動的にはアクセスできないみたいです。知らなかった。。。

const name = 'NEXT_PUBLIC_TEST'
const test = process.env[name] // この方法では'NEXT_PUBLIC_TEST'の値は取得できない

Jest + React Testing Library

ユニットテストができるように設定をします。
選択肢はいくつかありますが、公式に記載のあるJest + React Testing Libraryの構成でいきます。

参考リンク

本項の手順は公式の手順を基本としていますが、エラーになる箇所がそこそこあったため、エラー解消が確認できた手順・設定にしています。
実行環境によっては違うエラーが発生するかもしれません。

セットアップ

STEP
インストール

nextでインストールコマンドを実行

npm i -D jest @testing-library/react @testing-library/jest-dom jest-environment-jsdom ts-jest
STEP
設定ファイルの作成

next/jest.setup.js next/jest.config.jsの2つの設定ファイルを作成します。

import '@testing-library/jest-dom'
/* eslint-disable @typescript-eslint/no-var-requires  */
const nextJest = require('next/jest')
const { compilerOptions } = require('./tsconfig.json')
const { pathsToModuleNameMapper } = require('ts-jest')

const createJestConfig = nextJest({
  // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
  dir: './',
})

// Add any custom config to be passed to Jest
const customJestConfig = {
  // Add more setup options before each test is run
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  // if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work
  moduleDirectories: ['node_modules', '<rootDir>/'],
  testEnvironment: 'jest-environment-jsdom',
  preset: 'ts-jest',
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths),
}

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig)
STEP
package.jsonの編集

next/package.jsontestスクリプトを追加します。

...
"scripts": {
...
  "test": "jest"
},
...
STEP
テストフォルダの作成

ユニットテスト用のフォルダnext/__tests__を作成します。

next/
├── .next/
├── __tests__  <- 追加/
├── node_modules/
├── public/
└── src/
    ├── pages/
    └── styles/

以降は__tests__配下にあるテストメソッドがテスト実行対象として認識されるようになりますので、テストファイルを*.test.jsのようなファイル名にする必要はありません。

STEP
サンプルテストの実行

__tests__/sample.tsxを作成して、公式と同様にテストを作成。

import { render, screen } from '@testing-library/react'
import Home from '@/pages/index'

describe('Home', () => {
  it('renders a heading', () => {
    render(<Home />)

    const heading = screen.getByRole('heading', {
      name: /welcome to next\.js!/i,
    })

    expect(heading).toBeInTheDocument()
  })
})

npm run testを実行してテストが成功すれば問題なし。

/bin/zsh % npm run test

> next@0.1.0 test
> jest

 PASS  __tests__/sample.tsx
  Home
    ✓ renders a heading (61 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.705 s, estimated 1 s
Ran all test suites.

これでユニットテストのセットアップは完了!

コミットしておきましょう!

husky + lint-staged

ESLint・Prettier・ユニットテストの自動化をしていきます。

使用するツールはhusky, lint-stagedの2つです。

husky

コミットやプッシュなどのgit操作をトリガーに、設定したコマンドなどの処理を実行するツール。

lint-staged

ステージング済のファイルを対象に、設定したコマンドなどの処理を実行するツール。筆者は勘違いしていましたが、ステージング操作をトリガーになにか処理を実行するためのツールではありません。

参考リンク

セットアップ

STEP
インストール

とにもかくにもまずはインストール。
rootで下記コマンドを実行します。

npm i -D husky lint-staged
STEP
lint-stagedの設定

lint-stagedでステージング済のファイルに対して以下を実行するように設定します。

  • Prettierによるコードフォーマット
  • ESLintによるコードチェック

root/.lintstagedrc.ymlを以下の内容で作成します。

'*.{js,jsx,ts,tsx}':
  - prettier --write
  - eslint --max-warnings 0

ESLintは厳しめの設定(警告1件以上でもエラー)です。お好みで変更してください。

これでlint-stagedを利用してステージング済のファイルに対してPrettier, ESLintが実行できるようになりました。

STEP
huskyの設定

続いてhuskyの設定です。

コミット前に以下を行い、エラーがある場合はコミットを中断させます。

  • Prettierによるコードフォーマット
  • ESLintによるコードチェック
  • Jestによるテスト実行
STEP

root/package.jsonに以下を追加します。

...
"scripts": {
  "test": "npm test --prefix next",
  "prepare": "husky install"
},
...

prepareを設定することでnpm install実行後に設定したコマンドを実行します。huskyはインストールするだけでは動作せず、husky installを実行しておく必要があるためprepareにコマンドを設定しておくことで実行忘れを防ぎます。

STEP

下記のコマンドをrootで実行します。

npx husky install
npx husky add .husky/pre-commit "npx lint-staged"
npx husky add .husky/pre-commit "npm test"

npx lint-stagedを実行することで下記2つを実行しています。

  • Prettierによるコードフォーマット
  • ESLintによるコードチェック

これでコミット時にPrettier, ESLint, テストを実行するようになりました!

コミットしておきましょう!

コミットメッセージ関連

コミットメッセージ関連の便利なツールを導入していきます。
ESLintやユニットテストに比べて、設定することでかえって面倒になる場合もあるので注意!

commitlint

コミットメッセージ用の検証ツールです。

ルールに従ったコミットメッセージでない場合にコミットを中断させることができます。

参考リンク
STEP
インストール

rootでインストール。

npm i -D @commitlint/cli @commitlint/config-conventional
STEP
設定ファイルの作成

root/.commitlintrc.ymlを以下の内容で作成します。

extends:
  - '@commitlint/config-conventional'

本記事で使用するルールはConventional Commitsという仕様に従ったもので、
コミットメッセージを以下の形式で書く必要があります。

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

詳しくは下記のリンク(日本語)をご覧ください。

STEP
huskyの設定

あとはhuskyを使って、コミット時にコミットメッセージの検証を実行するようにします。

npx husky add .husky/commit-msg "npx commitlint --edit"

ルールに従っていないメッセージでコミットしてみると無事エラーとなり、コミットが中断されるようになりました。

/bin/zsh % git commit -am "add commitlint"
...
⧗   input: add commitlint
✖   subject may not be empty [subject-empty]
✖   type may not be empty [type-empty]

✖   found 2 problems, 0 warnings
ⓘ   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

husky - commit-msg hook exited with code 1 (error)

commitlintはこれでOK!

コミットしておきましょう!

Git commit template (WebStormプラグイン)

commitlintで検証するのは良いことですが、慣れるまではルールに従ったコミットメッセージを作るのは大変かもしれません。

そのためコミットメッセージを作成するサポートツールを導入します。
※WebStorm(JetBrains製IDE)向けのプラグインです。

JetBrains製IDEを使用していない方はcommitizenというものがnpmで提供されてますので興味があればやってみても良いかもしれません。

STEP
プラグインのインストール

WebStormのプラグイン画面からインストールします。

STEP
WebStormの再起動

プラグインのインストール完了後、WebStormを再起動します。

STEP
動作確認

再起動後、プロジェクトを開いてコミット画面を見ると新しいアイコンが追加されています。
そこから画面に沿って進めていけば良い感じにコミットメッセージが作成できます。

Chakra UI

React向けのコンポーネントライブラリです。

すでに用意されている豊富なコンポーネントを利用してフロントエンドを実装できます。
基本的にはCSSファイルを用意することなく実装できるというのもメリットのひとつです。

参考リンク

セットアップ

STEP
インストール

nextでインストールを実施。

npm i @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^6
STEP
カスタムテーマの実装

スタイル関連はCSSを使用せずにChakra UIで管理したいため、カスタムテーマを使用できるように実装していきます。

参考リンク

カスタムテーマ用のフォルダnext/src/themeを作成します。

next/
├── .next/
├── __tests__ /
├── node_modules/
├── public/
└── src/
    ├── pages/
    ├── styles/
    └── theme  <- 追加/

以降は作成したtheme配下にコードを作成していきます。階層構造になっている場合はフォルダも合わせて作成します。

export const colors = {
  sample: {
    gray: '#D8D8D8',
  },
}
export const fonts = {}
export const styles = {
  global: {
    body: {
      bgColor: 'sample.gray',
    },
  },
}
export const Button = {
  variants: {
    orange: {
      bg: 'orange',
      color: 'white',
    },
  },
}
import { extendTheme } from '@chakra-ui/react'
import { colors } from '@/theme/colors'
import { styles } from '@/theme/styles'
import { fonts } from '@/theme/fonts'
import { Button } from '@/theme/components/button'

const customTheme = extendTheme({
  colors,
  components: {
    Button,
  },
  fonts,
  styles,
})

export default customTheme
STEP
ChakraProviderの設定

Chakra UIが提供するコンポーネントをプロジェクト内で使用できるように、
ChakraProvidernext/src/pages/_app.tsxに追加します。

import '../styles/globals.css'
import type { AppProps } from 'next/app'
import { ChakraProvider } from '@chakra-ui/provider'
import customTheme from '@/theme/customTheme'

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ChakraProvider theme={customTheme}>
      <Component {...pageProps} />
    </ChakraProvider>
  )
}

export default MyApp
STEP
動作確認

実際にChakra UIのコンポーネントが使えるかnext/src/pages/index.tsxを編集して確認しておきましょう。

import type { NextPage } from 'next'
import { Button, Heading } from '@chakra-ui/react'

const Home: NextPage = () => {
  return (
    <>
      <Heading>
        Welcome to <a href="https://nextjs.org">Next.js!</a>
      </Heading>
      <Button variant={'orange'}>test</Button>
    </>
  )
}

export default Home

実行して、localhost:3000が以下のように表示されていればOKです!

無事Chakra UIを使用できるようになりました!

ちなみに、src/stylesは必要に応じて削除してしまっても大丈夫です。

コミットしておきましょう!

カスタムテーマの自動補完

自身で作成したカスタムテーマの設定項目は自動補完させることができます。

参考リンク
STEP
インストール

自動補完定義を生成するためのツールをnextでインストールします。

npm install -D @chakra-ui/cli
STEP
自動補完定義の生成

続いて下記のコマンドを実行します。

npx chakra-cli tokens src/theme/customTheme.ts

実行後はカスタムテーマの定義が内部的に生成され、自動補完できるようになります。

STEP
huskyの設定

カスタムテーマを更新するたびに毎回上記のコマンドは必要となります。
そこでhuskyを使って少しでも自動化しておきます。

STEP

next/package.json root/package.jsonそれぞれに以下のスクリプトを追加します。

...
"scripts": {
  …
  "gen:theme-typings": "npx chakra-cli tokens src/theme/customTheme.ts"
},
...
...
"scripts": {
  …
  "gen:theme-typings": "npm run gen:theme-typings --prefix next"
},
...
STEP

rootで下記のコマンドを実行して、huskyに設定を追加します。

npx husky add .husky/post-merge "npm run gen:theme-typings"
npx husky add .husky/post-checkout "npm run gen:theme-typings"

これでチェックアウト時とマージ実行時(≒pull実行時)に自動補完定義の生成処理が実行されるようになりました。

自動補完定義の設定も完了です!

コミットしておきましょう!

最後に

以上で本記事における環境構築は完了です!

最近のJavaScript(TypeScript)の開発環境は環境構築だけで一苦労ですね。

正直「ここまでするなら別言語のほうが良いのでは?」と思ったりもしています。

とはいえ、まだしばらくはJavaScript(TypeScript)構成は使われると思いますので、毎回の環境構築で時間をかけたくない人の役に立てたら嬉しいです。

よかったらシェアしてね!
  • URLをコピーしました!
目次