水戸地図(β)

2026年01月24日

Jクラブ経営情報ポータルを再構築 技術編

Jクラブ経営情報ポータルを具体的にどのように再構築したのかを、この記事で解説します。

プロジェクト構造を再編しました。旧サイトでは Gatsby 単体のプロジェクトとして制作していましたが、今回は Monorepo で構成しています。データ部分をパッケージとして扱い、ビルドしたパッケージを App 内でインポートする仕組みにしました。

.
├── apps
│   ├── vercel-api // APIプロジェクト (予定)
│   └── web // Next.jsプロジェクト
├── packages
│   ├── core // コアパッケージ
│   ├── data // データパッケージ
│   ├── eslint-config
│   ├── statistics // 統計パッケージ (experimental)
│   ├── typescript-config
│   └── utils // ユーティリティパッケージ
├── scripts // README.mdの自動生成などのスクリプト
├── eslint.config.mjs
├── package-lock.json
├── package.json
├── README.md
├── tsconfig.json
├── turbo.json
└── vitest.config.ts
広告

以前のプロジェクト構造

旧サイトでは、CSVから生成した元のYAMLファイルを、GatsbyのSourceプラグインとTransformerプラグインで読み込む構成でした。Gatsby Node APIを使って読み込みの過程でデータを整形し、各ページのテンプレート内でGraphQLのクエリを用いてデータを読み込むという手順でデータ処理を行っていました。

Gatsbyが死んでいなければこの辺りも記事化できるのですが、もはや書き記す意味はないでしょう。

旧サイトのリポジトリ

データパッケージ

ここでは、データパッケージの構造について簡単に書き記します。

データパッケージでは、datasetに格納された元のYAMLファイルをJSONファイルに加工・整形し、distディレクトリに出力しています。

packages/data/
├── __tests__
├── dataset // クラブ毎のYAMLファイルを格納
│   ├── albirex
│   │   ├── 2005.yml
│   │   ├── 2006.yml
│   │   ├── ...
│   │   └── 2024.yml
│   ├── antlers
│   ├── ardija
│   ├── ...
│   └── zweigen
├── dist // クラブ毎のJSONファイルを出力
│   ├── albirex
│   │   ├── 2005.json
│   │   ├── 2006.json
│   │   ├── ...
│   │   ├── 2024.json
│   │   ├── index.cjs
│   │   ├── index.d.ts
│   │   └── index.mjs
│   ├── antlers
│   ├── ardija
│   ├── ...
│   ├── zweigen
│   ├── index.cjs
│   ├── index.d.ts
│   └── index.mjs
├── scripts
├── src
├── eslint.config.mjs
├── package.json
├── tsconfig.json
├── tsdown-for-clubs.config.ts
└── tsdown.config.ts

distのルートにindexファイルを置き、各JSONファイルを読み込む関数を提供しています。

import {
  getDataByClub,
  getDataByYear,
} from "@cieloazul310/jclub-financial/data";

const mito = await getDataByClub("mitohollyhock");
// => Array(20) [FinancialDatum, FinancialDatum, ...]

const latest = await getDataByYear(2024);
// => Array(62) [FinancialDatum, FinancialDatum, ...]

それに加えて、クラブ毎のディレクトリにもエントリポイントとなるindexファイルを置き、クラブ単位でデータを読み込む関数も提供しています。

import { getData } from "@cieloazul310/jclub-financial/data/mitohollyhock";

const mito = await getData();
// => Array(20) [FinancialDatum, FinancialDatum, ...]

const latestDecades = await getData(2015, 2024);
// => Array(10) [FinancialDatum, FinancialDatum, ...]

内部でfspathを使用しているのでNode.js環境が前提になりますが、React Server Componentsでは利用可能です。

データの加工・整形と型安全性

YAMLからJSONへの加工・整形の際には、Zodを使って型安全性を担保しています。

Zod
zod.dev

元のファイルがYAMLなのは、旧サイトのリソースの再利用という側面もありますが、メンテナンス性を考慮してのことです。

パッケージとして配布

元のファイルがYAMLなのは、旧サイトのリソースの再利用という側面もありますが、メンテナンス性を考慮してのことです。

@cieloazul310/jclub-financial

パッケージ名は現在、個人アカウント名である@cieloazul310のスコープを付けていますが、organizationを作成して専用のスコープを付けることも考えています。ただ、NPMのorganizationを個人で気軽に作ってよいのかわからず、躊躇しているところです。

きかいにおまかせ / 家主 (2023)

広告

2026年01月24日

Jクラブ経営情報ポータルを再構築 技術編

制作物

Top

水戸地図(β)