最近流行りのフレームワークたちをlernaを使ってモノレポ化する。
構成はこんな感じになる想定。
. ├── lerna.json ├── package.json └── packages ├── client <-------- Next.js │ └── package.json └── server <-------- NestJS └── package.json
どこまでやるか
今回モノレポ化したい一番の目的が、package.jsonのscriptsコマンドの一括操作。
つまりリポジトリ直下でyarn dev
と実行したら、クライアント側とサーバー側の両方のyarn dev
が実行される形。
node_modulesの共通化はやらない。
クライアントとサーバーを作成する
各自Next.jsとNestJSのコマンドを使って作成する。もうすでにclientとserverのディレクトリが作成済みの人はここの作業は不要。別にNext.jsやNestJSじゃなくても全く構わない。
まずはclientとserverをまとめるためのmonorepo
ディレクトリを作成する。
mkdir monorepo cd monorepo
今後の作業はこのmonorepo
ディレクトリの中でおこなっていく。
Next.jsでクライアントの作成
# クライアントの作成 @See https://nextjs.org/docs
npx create-next-app
コマンドを実行するといくつか質問を聞かれるが全部ENTERでOK。最初に聞かれるプロジェクト名だけclient
と入力する。
create-next-app
で作成すると自動的にgit管理になるが、今回は邪魔になるので.git
を削除しておく。
rm -rf client/.git
yarn dev
を実行した後、http://localhost:3000
にアクセスしてページが表示されたらOK。
cd client
yarn dev
NestJSでサーバーの作成
# サーバーの作成 @See https://docs.nestjs.com/first-steps # 'server'という名前で作成する nest new server
ここもコマンドを実行するといくつか質問を聞かれるが全部ENTERでOK。
nest new
で作成すると自動的にgit管理になるが、今回は邪魔になるので.git
を削除しておく。
rm -rf server/.git
yarn start:dev
を実行した後、http://localhost:3000
にアクセスしてページが表示されたらOK。
cd server
yarn start:dev
ただ、このままだとクライアント側とポート番号が3000
で衝突して同時に環境を立ち上げることができないのでポート番号を変更しておく。
$ vim src/main.ts import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(3001); // <------- 3001に変更 } bootstrap();
また、クライアントとサーバー側でscriptsコマンドの名前を同じにしておきたいので、package.json
も編集しておく。yarn dev
で環境を立ち上げられるようにする。
$ vim package.json ...略 "scripts": { "dev": "nest start --watch",
lernaを導入してモノレポ化する
さっそくlernaでモノレポ化する。現在のディレクトリ構造は下記。
monorepo ├── client │ └── package.json └── server └── package.json
lernaの導入
npm install -g lerna
npx
でその場だけでlerna
をインストールしてもいいが、今回はグローバルでインストールしておく。
lerna initで初期環境を構築
cd monorepo
lerna init
実行するとlerna.json
,package.json
,packages
の3つが作成される。
monorepo ├── lerna.json ├── package.json ├── packages ├── client └── server
client、serverをパッケージ化する
lerna create
コマンドでパッケージの作成とともにディレクトリを生成されるが、今回はすでにclient, serverを作ってあるので、それをpackages配下に移動させてからコマンドを実行する。
mv server packages mv client packages lerna create @monorepo/server ./packages/server lerna create @monorepo/client ./packages/client
@monorepo
の部分がパッケージ名となるが、あとから変更可能なので気軽につける。
また、lerna create
をすると各パッケージ配下にいくつかファイルが作成される。
__tests__
やREADME.md
は不要なので削除してもOK。lib
は必要なので消さないでおく。
scriptsコマンドの一括操作
ディレクトリ直下のpackage.jsonにscriptsコマンドを追加する。
vim package.json { "name": "root", "private": true, "scripts": { "dev": "lerna run dev --parallel --stream --scope=@monorepo/{client,server}" }, "devDependencies": { "lerna": "^4.0.0" } }
ディレクトリ直下でyarn dev
を実行すると、clientとserverの両方が立ち上がる。
これで終了
コマンドまとめ
mkdir monorepo cd monorepo # クライアント作成 npx create-next-app rm -rf client/.git # サーバー作成 nest new server rm -rf server/.git # モノレポ化 lerna init mv server packages mv client packages lerna create @monorepo/server ./packages/server lerna create @monorepo/client ./packages/client
終わり
ただ、node_modulesの共通化はyarn workspaceとlernaをセットで使ったりと、少し複雑になってきそうだったのでやらなかったけど、モノレポ化と言ったらリポジトリの軽量化みたいなところもあるので別の機会でちゃんとやる。