RIT Tech Blog

株式会社RITのエンジニアが知見を共有する技術ブログです。

Blitz.js 迷った時のディレクトリ構成

こんにちは。エンジニアの岸本です。

Blitz.jsを使って開発をしている時に、「このファイルはどこに配置しよーかなー」と悩んだことはないでしょうか? 私は多々あります。主にutilsか?それともservicesか?とか。 感覚値で配置場所を決めてたこともあったので、この機会にシンプルにまとめたいと思います。

本記事の対象者

  • Blitz.jsユーザーでファイルの設置場所に悩むことがたまにある人

本記事で解決できること

  • ファイルの設置場所で悩む事による時間の無駄遣い

そして結論

基本的に以下の順序で一考すれば間違いない(と信じてる)

1. まずは基本に忠実にファイル構成を考える(以下は公式から参照)

├── app/
│   ├── core/
│   │   ├── components/
│   │   │   ├── Form.tsx
│   │   │   └── LabeledTextField.tsx
│   │   ├── hooks/
│   │   │   └── useCurrentUser.ts
│   │   └── layouts/
│   │       └── Layout.tsx
│   ├── pages/
│   │   ├── 404.tsx
│   │   ├── _app.tsx
│   │   ├── _document.tsx
│   │   ├── index.test.tsx
│   │   ├── index.tsx
│   │   └── projects/
│   │       ├── [id]/
│   │       │   └── edit.js
│   │       ├── [id].js
│   │       ├── index.js
│   │       └── new.js
│   ├── api/
│   │   └── stripe-webhook.js
│   ├── auth/
│   │   ├── components/
│   │   │   ├── LoginForm.tsx
│   │   │   └── SignupForm.tsx
│   │   ├── mutations/
│   │   │   ├── login.ts
│   │   │   ├── logout.ts
│   │   │   └── signup.ts
│   │   ├── pages/
│   │   │   ├── login.tsx
│   │   │   └── signup.tsx
│   │   ├── auth-utils.ts
│   │   └── validations.ts
│   ├── users/
│   │   └── queries/
│   │       └── getCurrentUser.ts
│   └── projects/
│       ├── components/
│       │   ├── Project.js
│       │   ├── ProjectForm.js
│       │   └── Projects.js
│       ├── mutations/
│       │   ├── createProject.js
│       │   ├── createProject.test.js
│       │   ├── deleteProject.js
│       │   ├── deleteProject.test.js
│       │   ├── updateProject.js
│       │   └── updateProject.test.js
│       └── queries/
│           ├── getProject.js
│           └── getProjects.js
├── db/
│   ├── index.ts
│   ├── schema.prisma
│   └── seeds.ts
├── integrations/
│   └── sentry.ts
├── public/
│   ├── favicon.ico*
│   └── logo.png
├── test/
│   ├── setup.ts
│   └── utils.tsx
├── README.md
├── babel.config.js
├── blitz.config.js
├── jest.config.js
├── package.json
├── tsconfig.json
├── types.ts
└── yarn.lock

2. 便利かつどちらかと言えば複雑度低めな関数(処理 ex.文字列の加工など)なら/utilsフォルダへ、どちらかと言えば複雑度高めなら/servicesフォルダへ

3. 深くネストしないような構成で考える(相対パスを使ったインポートが面倒 + ファイルが移動したときにそれらを更新するのも大変)

4. それでもしっくり来ないなら、よく一緒に変更するファイルを近くに置いておく!

公式からのサンプルに追記すると、以下のような構成にすれば個人的にはネストも深くせずにシンプルになるのではないでしょうか。

│   ├── users/
│   │   └── queries/
│   │       └── getCurrentUser.ts
│   │   └── services/   <----
│   │       └── serviceExample.ts
│   │   └── utils/   <----
│   │       └── utilsExample.ts

Blitz.jsの公式ページには以下記載があることからも、迷った場合はよく一緒に変更するファイルに記述すれば確実かもしれないですね。

Guiding Principles

  • Files that change together should live together.(一緒に変更されるファイルは一緒に配置しましょう)
  • Minimal requirements, maximum flexibility.(最小の用件を、最大の柔軟性で)

余談

「一緒に変更されるファイルは一緒に配置しましょう」という考え方・原則は「コロケーション」と呼ばれます。 コロケーションを採用することで手を動かすことを優先することが可能になることは、「Done is better than perfect.(完璧であることより、まず終わらせることが重要だ)」で有名なザッカーバーグ氏の思想を反映させたようにも感じますよね。