プログラムから無駄なものを削ぎ落として最小限の構成にしてみると動作を負いやすくなる。
React を始める時に、create-react-app を叩いて出てくるものは、親切に様々なファイルが同梱されており、逆に最も本質的な動作(結局どうやって動いているのか)が分かりづらい。
そこで、アイコンや画像CSS等の動作の理解には不要なファイルを全て削除して最小限のディレクトリ構成にしたものを眺めることで、必要最低限の動作を追うことにした。
今回見ていく物
エラーなくビルドと実行ができる最小限の React アプリケーションのソースを見ていく。アプリケーションと言っても、CSS による装飾もない、インタラクションもない、 HTML で記述するのと大した違いはないものである。
ディレクトリ構成は Github に上げてある。また、動作するアプリケーションは vercel 上にデプロイしてある。
それぞれのファイルを見ていく
まず、最小限のディレクトリ構成を作成すると以下のようになる。
.
├── public
│ └── index.html
├── src
│ ├── App.js
│ └── index.js
└── package.json
-
publicフォルダには、アプリケーションにアクセスすると最初に読み込まれるファイル群を格納する(エントリポイントのような役割) -
srcフォルダには、アプリケーションの具体的な実装ファイルが格納する -
package.jsonファイルには、 Node.js を実行するための設定を記述する
public/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
"root" の id を持つ要素の所に React DOM が生えてくる。
JavaScript ソースを指定していないが、ビルドすると次の src/index.js ファイルが指定されるようになる。
src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
index.htmlのスクリプトとして読み込まれる Javascript ファイル。 JSX で記述されている。
実行されると、まず、document.getElementById('root') により、 id="root" のエレメントが読み込まれる。
次に、 ReactDOM.createRoot(...) により id="root" のエレメントに React DOM が生えてくる。 root の子要素 App の内容は次の src/App.js ファイルに記述されている。
src/App.js
function App() {
return (
<div className="App">
<header className="App-header">
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
App は React DOM を返す関数として記述される。この際にも JSX が用いられる。
package.json
Node.js の機能を利用するための設定が記述される。
インストール、ビルド、実行に必要な分が記述してある。
{
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build"
},
"dependencies": {
"react": "^19.2.5",
"react-dom": "^19.2.5",
"react-scripts": "5.0.1"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
まず、npm install あるいは yarn install すると、 dependencies に記述されたパッケージとその依存先が全てインストールされる。
次に、npm run build あるいは yarn run build すると、 react-scripts build が実行され、 build ディレクトリが生えてくる。
最後に、npm run start あるいは yarn run start すると、 react-scripts build が実行され、サーバーが立ち上がり、アプリケーションのために使用されているポート番号がログに吐き出される。ログに記載された場所にアクセスするとブラウザからアプリケーションを使える。
なお、browserslist は無くても差し支えないが、ビルドする際に勝手に生えてくる。
build ディレクトリ
ビルドすると以下のような build ディレクトリが構成される。
.
└── build
├── static
│ └── js
│ ├── main.6f13a0b8.js
│ ├── main.6f13a0b8.js.LICENSE.txt
│ └── main.6f13a0b8.js.map
├── asset-manifest.json
└── index.html
アプリケーションにアクセスすると、index.html が開かれる。
その後 index.html の記述に従って、 main.6f13a0b8.js が読み込まれる。
余談:このくらい小さな構成でもビルド後の main.6f13a0b8.js ファイルに20万文字(フォーマットすると1万行分)の内容が記述されている。