2
0

More than 3 years have passed since last update.

10分で理解: react アプリ開発環境を準備 (TypeScript, commitlint, husky, Sourcetree)

Last updated at Posted at 2021-09-05

概要

react アプリを TypeScipt で開発する際の定番の設定をまとめておく。

  • TypeScript で記述
  • eslint で構文チェック(クォーテーションマークの統一、import 文のソート)
  • jest でユニットテスト
  • commitlint で commit log が semantic versioning に準拠しているかチェックし、エラーが出たときには commit 中止
  • commit 前に eslint, jest を自動実行し、エラーが出たときには commit 中止
  • Sourcetree からも上記のフックが正しく実行されるように細工

この環境設定を行なった git repo はこちら。https://gitlab.com/ken.miyasita/react-app-on-gitlab-pages/-/tree/main

全体像

react アプリケーションの雛形を準備

参照: Create React App

$ node --version
v15.14.0
$ npx create-react-app react-app-on-gitlab-pages --template typescript
$ cd react-app-on-gitlab-pages
$ yarn start

eslint

参照
* Getting Started with ESLint - ESLint - Pluggable JavaScript linter
* Getting Started - Linting your TypeScript Codebase
* eslint-plugin-simple-import-sort

lint ルールをいくつか設定しておく。

  • 文字列は、全てシングルクオートマークにする
  • import 文は、いくつかのカテゴリに分け、それぞれのカテゴリー内は import 対象のパス名でソートする
$ yarn add eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-simple-import-sort --dev
.eslintrc.json
{
    "env": {
        "browser": true,
        "es6": true,
        "node": true
    },
    "parser": "@typescript-eslint/parser",
    "plugins": [
        "@typescript-eslint",
        "simple-import-sort"
    ],
    "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/recommended"
    ],
    "rules": {
        "quotes": [
            "error",
            "single"
        ],
        "simple-import-sort/imports": "error",
        "simple-import-sort/exports": "error"
    }
}
package.json
  "scripts": {
    "lint": "eslint . --ext .ts,.tsx"
  },

jest

参照:Running Tests | Create React App

Create react app が自動生成する package.json の script 定義は以下のようになっており、
環境変数 CI が設定されているか否かで test の挙動が変化するようになっている。

package.json
  "scripts": {
    "test": "react-scripts test",
  },
  • CI が定義されていないときには watch モードで動作。ソースコードが変更されるたびに、変更されたソースコードに関連するテストのみ実行される。
  • CI が定義されているときには、全テストを実行。Predefined variables reference - GitLab によると GitLab CI/CD 環境でも CI=true が設定されている。
  • もしくは yarn test --watchAll=false として起動すれば、全テストを実行。この機能は後で commit 時に test を実行するために利用する。

commitlint を husky を使って起動する

参照:
* commitlint - Lint commit messages
* commitlint - Lint commit messages > Guide: Local setup

commit log を semantic versioning に準拠した形に維持するために commitlint を導入する。

$ yarn add @commitlint/{cli,config-conventional} --dev
$ echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js
$ yarn add husky --dev
$ npm set-script prepare "husky install"
$ yarn prepare
$ yarn husky add .husky/commit-msg 'yarn commitlint --edit $1'

semantic versioning に適合しない commit log を指定して commit しようとしてもエラーとなることが確認できる。

$ git commit -m'foo:aaa'
yarn run v1.22.11
$ /Users/kmiyashita/gitlab/react-app-on-gitlab-pages/node_modules/.bin/commitlint --edit .git/COMMIT_EDITMSG
⧗   input: foo:aaa
✖   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

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
husky - commit-msg hook exited with code 1 (error)

commit 時に lint, jest を起動する

せっかく husky を導入したので、commit 時には lint, jest が必ずパスすることを確認することにする。

$ yarn husky add .husky/pre-commit 'yarn lint && yarn test --watchAll=false'

確かに、lint と jest が実行されることを確認できた。

$ git commit -m 'feat: run lint and jest at every commit'
yarn run v1.22.11
$ eslint . --ext .ts,.tsx
✨  Done in 0.58s.
yarn run v1.22.11
$ react-scripts test --watchAll=false
 PASS  src/App.test.tsx
  ✓ renders learn react link (14 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.006 s
Ran all test suites.
✨  Done in 1.56s.
yarn run v1.22.11
$ /Users/kmiyashita/gitlab/react-app-on-gitlab-pages/node_modules/.bin/commitlint --edit .git/COMMIT_EDITMSG
✨  Done in 0.21s.
[main 0a560aa] feat: run lint and jest at every commit
 2 files changed, 5 insertions(+), 1 deletion(-)
 create mode 100755 .husky/pre-commit

ただ、開発中の feature branch では lint, jest が一時的にパスしない状態でも commit をして状態保存をしながら開発し、最後に interactive rebase で commit log を整理してから main branch にマージすることも多々あると予想される。それを考えると常に lint, jest がパスしないと commit できないというルールは厳しすぎるかもしれないので、結局以下のように main branch でのみこのルールを発動するようにした。

.husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

branch="$(git rev-parse --abbrev-ref HEAD)"

if [ "$branch" = "main" ]; then
    yarn lint && yarn test --watchAll=false
fi

Sourcetree から commit したときにも commit hook を動作させる

参考:
* Launching a macOS application with a custom path
* Can I change the application icon of an Automator script?

ここまでで Terminal から git 操作した時の挙動はうまく設定できたが、Sourcetree から commit をしようとするとうまく動作しない。以下のように yarn が見つからないというエラーが出る。

image.png

これは、Sourcetree のように Dock / Finder から起動されたアプリにとっては PATH 変数がデフォルト設定のままになっており、自分で yarn 等をインストールしたフォルダーを .zshrc 等で PATH 変数に追加していてもそれが反映されないことが原因である。

この問題を回避するためには、Automator を利用して下図のように .zshrc 等を読み込んでから Sourcetree を起動すれば良い。ある意味、shell script を Dock / Finder に置いていると考えられる。

image.png

このようにして PATH 設定をした状態の Sourcetree を用いると、下図のように commit 時に lint, jest が起動される。

image.png

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0