
モノレポでTypeScriptパッケージを作成する - 基本編
はじめに
こんにちは。今回はモノレポ(Monorepo)について解説します。モノレポとは、複数のプロジェクトやパッケージを1つのリポジトリで一元管理する手法です。
TypeScriptパッケージを作る利点
モノレポでTypeScriptパッケージを作成することで、以下のような利点があります:
- 型定義の共有による開発効率の向上
- コードの再利用性の向上
- プロジェクト間の一貫性維持
モノレポの基本構造
├── apps/ # アプリケーション
│ ├── web/ # Webアプリケーション
│ ├── admin/ # 管理画面
│ └── mobile/ # モバイルアプリ
│
├── packages/ # 共有パッケージ
│ ├── config/ # 設定ファイル
│ ├── ui/ # UIコンポーネント
│ ├── utils/ # ユーティリティ
│ └── types/ # 型定義パッケージ
```
このように、アプリケーションとパッケージを明確に分離した構成を取ります。
今回作るパッケージについて
@sample/types
というパッケージを作っていきます。これは、プロジェクト全体で使う型定義をまとめたパッケージです。APIのレスポンス型とか、共通のデータ構造とか、そういうのを全部ここで管理します!
さぁ、実際に作っていこう!
まずはpackage.jsonから
package.jsonは、パッケージの顔みたいなもの。ここでいろんな設定をしていきます:
{
"name": "@sample/types",
"version": "0.0.0",
"private": true,
"sideEffects": false, // Tree Shakingを効かせるためのフラグ!
"main": "./dist/index.js", // CommonJS用のエントリーポイント
"module": "./dist/index.mjs", // ES Modules用
"types": "./dist/index.d.ts", // TypeScript用の型定義ファイル
"files": [
"dist/**" // 公開するファイルはdistディレクトリの中身だけ!
],
"scripts": {
"lint": "eslint src/", // コードの品質チェック
"typecheck": "tsc --noEmit", // 型チェック
"build": "tsup", // ビルド
"dev": "tsup --watch", // 開発モード
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist" // お掃除用
},
"devDependencies": {
"@types/node": "^20.11.16",
"eslint": "^8.57.0",
"eslint-config-next": "^14.1.0",
"tsup": "^8.0.1", // 超便利なビルドツール!
"typescript": "^5.3.3"
}
}
TypeScriptの設定もバッチリ!
tsconfig.jsonは、TypeScriptの動作を決める大事な設定ファイル:
{
"compilerOptions": {
"target": "es2018", // モダンなJavaScriptを使うぞ!
"lib": ["esnext"], // 最新の機能を使えるように
"module": "esnext", // モジュールシステムも最新式
"moduleResolution": "node", // Node.js方式で解決
"declaration": true, // 型定義ファイルを出力
"declarationMap": true, // ソースマップも出力
"sourceMap": true, // デバッグ用のソースマップ
"outDir": "./dist", // 出力先ディレクトリ
"strict": true, // 厳格な型チェック
"esModuleInterop": true, // import文を使いやすく
"skipLibCheck": true, // 型チェックを最適化
"forceConsistentCasingInFileNames": true // ファイル名の大文字小文字を厳格に
},
"include": ["src/**/*"], // コンパイル対象
"exclude": ["node_modules", "dist"]
}
tsup.config.tsの設定
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['cjs', 'esm'],
dts: true,
splitting: false,
sourcemap: true,
clean: true,
});
型定義の実装
基本的な型の設計
// 基本的な型定義をエクスポート
export type Maybe<T> = T | null | undefined;
// 共通のレスポンス型
export interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
// ページネーション用の型
export interface PaginationParams {
page: number;
limit: number;
}
export interface PaginatedResponse<T> extends ApiResponse<T[]> {
total: number;
currentPage: number;
totalPages: number;
}
ビルドと動作確認
ビルドプロセス
1. 以下のコマンドでビルドを実行:
pnpm build
2. 生成される成果物:
-
dist/index.js
(CommonJS) -
dist/index.mjs
(ES Modules) -
dist/index.d.ts
(型定義)
他のパッケージやアプリケーションから以下のように使用できます:
import { ApiResponse, Maybe } from '@sample/types';
// 型の使用例
const response: ApiResponse<User> = {
data: user,
status: 200,
message: 'Success',
};
const optionalValue: Maybe<string> = null;
まとめ
このように、モノレポ環境でTypeScriptパッケージを作成することで、以下のメリットが得られます:
- プロジェクト全体で一貫した型定義の使用
- 開発効率の向上
- コードの再利用性の促進
```
```