9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

シーエー・アドバンスAdvent Calendar 2023

Day 13

知識ゼロから始めるモノレポ開発 (Node.js編)

Last updated at Posted at 2023-12-13

きっかけ

next.jsのアプリケーションをモノレポでやりたいというオーダーがあったが何から手をつければ… いう状態から調べたことを書き散らしていきます。

方針

  • モノレポ管理するツールの導入
  • workspacesで共通パッケージを使いたい
  • tsconfig, linter等のconfigをある程度共通化したい
  • UIコンポーネント等の密結合な実装はなし

モノレポ管理するツールの導入

今回は、共通のUIを実装する等の密結合な要望はなく、Next.jsアプリとAPIサーバを同じリポジトリに置いて管理したいというオーダだったため、Bun workspaces, Turborepo を採用することにしました。

Nxは高機能でモノリシックなシステム構築にフォーカスを置いており、コンポーネントの共通化等を行う予定は今回ないので、Turborepoを採用しました。

参考

Nx と Turborepo の比較 https://zenn.dev/okmttdhr/articles/a919bb29d9d5c9#nx-%E3%81%A8-turborepo-%E3%81%AE%E6%AF%94%E8%BC%83

Bun

Bunとは、JavaScriptランタイムで高速で動作するnpm, yarnのようなパッケージ管理機能を有しています。
パッケージのインストールや動作も速く、安定していてBun特有の地雷も特に見受けられない。
v1.0が出ているので使っていきます。

参考

Bun1.0がもうすぐリリースされるぞ! https://zenn.dev/dojineko/articles/bun-1-coming-soon

Bun workspaces

npmと同様にBunでもworkspaceの機能が搭載されています。
workspaceとは、パッケージをお互い参照できる形で管理でき、node_modulesをシェアすることで依存関係も共通化できるものと思っておけば良いと思います。

ルートのpackage.jsonworkspacesを設定し、

./package.json
{
  "name": "monorepo",
  "packageManager": "bun@1.0.0",
  "private": true,
  "workspaces": [
    "packages/*",
    "services/*"
  ]
}

./packages/xxx に使いまわしたいコードや設定ファイル、パッケージ群をnodeのプロジェクトとしておくことで

./packages/tsconfig/package.json
{
  "name": "@monorepo/tsconfig",
  "private": true,
  "version": "0.0.0",
  "devDependencies": {
    "@tsconfig/next": "^1.0.2",
    "@tsconfig/node-lts": "^18.12.5",
    "tsconfig-paths": "^4.2.0"
  }
}

./services/awesome-app から共通のパッケージとして利用することができるようになります。

./services/awesome-app/package.json
{
  "name": "awesome-app",
  "packageManager": "bun@1.0.0",
  "private": true,
  "devDependencies": {
    "@monorepo/eslint-config": "workspace:*",
    "@monorepo/jest-config": "workspace:*",
    "@monorepo/tsconfig": "workspace:*"
  }
}

workspaceでtsconfigを共通化

例として、./packages/tsconfigにtsconfigに関連するファイルを設置していきます

乱暴に説明すると、
./packages/tsconfig/に下記のファイルを用意することで@monorepo/tsconfig/tsconfig.json という名前でアクセスできるようになります

./packages/tsconfig/package.json
{
  "name": "@monorepo/tsconfig",
  "private": true,
  "version": "0.0.0",
  "devDependencies": {
    "@tsconfig/next": "^1.0.2",
    "tsconfig-paths": "^4.2.0"
  }
}
./packages/tsconfig/tsconfig.json
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "@tsconfig/next/tsconfig.json",
  "compilerOptions": {
    "allowJs": true
  }
}

上記のファイルを./services/awesome-app/tsconfig.jsonで読み込みたい場合は、devDependencies@monorepo/tsconfigを記載し、

./services/awesome-app/package.json
{
  "name": "awesome-app",
  "packageManager": "bun@1.0.0",
  "private": true,
  "engines": {
    "node": ">=16.0.0 <=18.x.x"
  },
  "devDependencies": {
    "@monorepo/tsconfig": "workspace:*"
  }
}

extendsで読み込むと良いでしょう。

./services/awesome-app/tsconfig.json
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "@monorepo/tsconfig/tsconfig.json",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./*"]
    }
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.mts",
    "**/*.tsx",
    "**/*.js",
    "**/*.mjs",
    ".next/types/**/*.ts"
  ],
  "exclude": ["node_modules"]
}

eslint等も同様にいけるので興味があれば、参考を追っていただけると!

参考

Bun workspace で始めるモノレポ生活 https://azukiazusa.dev/blog/bun-workspace/
monorepo (yarn workspace) で tsconfig や .eslintrc をいい感じに管理する https://zenn.dev/shinnoki/articles/3f008f53b2312f

Turborepo

workspaces配下のpackage.jsonをもとに、一括でテストやビルドを実行することができ、キャッシュもしてくれます。
turborepoをインストールして、% bun run testを実行するとなるとこんな感じのpackage.jsonになるかと思います。

./package.json
{
  "name": "monorepo",
  "packageManager": "bun@1.0.0",
  "private": true,
  "engines": {
    "node": ">=16.0.0 <=18.x.x"
  },
  "workspaces": [
    "packages/*",
    "services/*"
  ],
  "scripts": {
    "build": "turbo run build",
    "test": "turbo run test",
  },
  "devDependencies": {
    "turbo": "^1.11.1"
  }
}

Turborepoの設定例

turbo.json
{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "!.next/cache/**"]
    },
    "test": {}
  }
}

実行方法

下記コマンドを実行し、ログがいっぱい流れたら成功です(雑)
ビルド結果がキャッシュされるため、2回目以降の実行が爆速になるのがわかると思います。

% turbo run test

image.png

参考

Turborepo でモノレポ構成のプロジェクトを爆速でビルドする | DevelopersIO https://dev.classmethod.jp/articles/turborepo-superfast-monorepo-ci/

まとめ

流すように説明したので、実際動かしてみたい方は参考資料を見ていただけると幸いです。
車輪の再開発になりそうなjestやstorybook等のパッケージも置いていきたいなー

9
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?