Create React Appのカスタムテンプレートで最小構成のプロジェクトをつくってみた

## 記事のポイント

- Create React App のカスタムテンプレートの説明
- 最小構成のプロジェクトの紹介


## [Create React App](https://create-react-app.dev/) とは

以下のようなワンライナーで、Reactのプロジェクトを作成できるツールです。
通常、Reactで作成したプログラムをブラウザで動かすには、WebpackやBabelなど
のビルドツールを自分で設定する必要がありますが、その作業をスキップし、
すぐにコードを書き始めることができます。

```
yarn create react-app my-app
```

## カスタムテンプレートに関して

Create React App には いくつかのテンプレートが用意されています。
例えば、TypeScriptによるプロジェクトを作成したい場合、以下のように実行します。

```
yarn create react-app my-app --template typescript
```

テンプレートの実体は、src, public のなどのディレクトリや package.json であり、プロジェクトの作成時に、それらが適切なパスにコピーされているようです。テンプレートの具体的な内容は[ここ](https://github.com/facebook/create-react-app/tree/master/packages/cra-template-typescript)を参照ください。GitHubにあるTypeScriptのテンプレート例です。


このテンプレートは、自作することができます。[カスタムテンプレート](https://create-react-app.dev/docs/custom-templates/)と呼ばれ、有志によって様々なテンプレートが作成されています。[こちら](https://www.npmjs.com/search?q=cra-template-*)がnpmでの検索結果です。

この記事は、カスタムテンプレートを使ってテンプレート部分を可能な限り小さくし、Create React Appの構成を理解する記事にです。

## 最小構成のプロジェクトを作成する

テンプレートのディレクトリ構成は以下です。

```
.
├── README.md
├── package.json
├── template
│   ├── README.md
│   ├── gitignore
│   ├── public
│   │   └── index.html
│   └── src
│       └── index.js
└── template.json
```

トップの package.json はこのテンプレートを公開するためのファイルで、以下の記述が必要になりました。また、version は[セマンティックバージョンの形式](https://semver.org/lang/ja/)を守る必要がありました。
さらに、template.json は作成したプロジェクトの package.json に追加する項目を定義するファイルで空の JSON を記述しました。それ以外のファイルは空のファイルです。

```
{
  "name": "cra-template-minimum",
  "version": "1.0.0"
}
```

以下のコマンドでプロジェクトを作成できます。file:プレフィックスを使用することで、作成した
テンプレートをパッケージとして公開せずに、ローカル環境にプロジェクトを作成することができます。

```
yarn create react-app hoge --template file:cra-template-ykonomi
```

作成されたプロジェクトのディレクトリ構成は以下です。 
.git, node_modulesはリスト化する意味がないため、省略しています。
テンプレートにあったファイルが配置されるのが確認できると思います。


```
% tree -aI 'node_modules|.git'                                                                                                                                                                                                              master
.
├── .gitignore
├── README.md
├── package.json
├── public
│   └── index.html
├── src
│   └── index.js
└── yarn.lock
```

また、package.json は以下のようになります。スクリプトにあるコマンドは期待通り実行できます。(index.jsが空のため、yarn start しても真っ白ですが...)
ここからは推測ですが、自作のテンプレートとの差分はこのファイルのみです。そのため, Create React App は、テンプレート + react-scriptsで構成されるプロジェクトを提供するツールなのではと思います。ちなみに、eject コマンドによって react-scripts によるラップを外し、Webpack, Babel等のビルドツールを直接扱うことができます。


```
{
  "name": "hoge",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^17.0.2", "react-dom": "^17.0.2", "react-scripts": "4.0.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
```

## まとめや所感

カスタムテンプレートを使って、最小構成のプロジェクトを作成しました。
このプロジェクトを眺めることで, Create React App がやっていることを
なんとなく理解することができました。
ビルドの構成をツールに任せてしまうため、ビルド周りの設定をいじる際は
(当然)辛くなるツールですが、さくっとアプリを作りたい, なにかを検証したい際
には役立つツールだと思います。