18
4

More than 1 year has passed since last update.

モノレポでいこう!~yarn workspacesを使ってみた~

Last updated at Posted at 2022-03-18

モノレポとは

概要

単一のリポジトリで複数のプロジェクトを管理することをモノレポという。
その分リポジトリの内容は複雑になるので、そこそこ運用知識が必要となる。

メリット、デメリット

モノレポのメリット、デメリットは下記のようなものが挙げられる。

メリット

  • 依存パッケージの管理をまとめてできる
  • 共有リソースを有効に利用する
  • npm scriptの一括操作

デメリット

  • Issue や PR をすべて 1 つのリポジトリで管理する必要がある
  • モノレポでの開発ワークフローを理解している必要がある

モノレポ作成

今回の背景

  • Next.jsでHeadressCMSなプロジェクトを作成する
  • 検証環境(SSR)、本番環境(SSG)とする
  • リポジトリ1つに検証環境と本番環境をまとめて管理したい(リポジトリは分けない)
  • ホスティンング環境はAWS Amplifyを使用する

パッケージ管理ツール選定

パッケージ管理ツールとしてNx、Lernaなど機能がリッチなものもあるが、今回は検証用であり、そこまで高度なことは求めていないので、より低レベルな機能を持つyarn workspacesを使用する。

yarn workspaces

Yarn1.0以降でデフォルトで使用できるパッケージアーキテクチャを設定するための新しい手法。
下記のようなことが可能。

  • 複数 npm パッケージを単一リポジトリで一元管理
  • yarn install コマンドを使った Monorepo すべての依存パッケージを一括インストール
  • yarn workspaces コマンドを使った Monorepo で管理しているパッケージが持っている npm-scripts の一括実行
  • 単一のyarn.lockファイルですべての依存関係を管理

参考:https://classic.yarnpkg.com/lang/en/docs/workspaces/

手順

  1. リポジトリのルートにpackage.json(プライベート・パッケージ)を作成
    yarn init -p

 1-1. 下記のようなpackage.jsonが作成される

privatetrueとしている。

package.json
{
  "name": "monorepo",
  "version": "1.0.0",
  "license": "UNLICENSED",
  "private": true
}

 1-2. 作成するワークスペースを定義する

workspaces/packages配下をglobパターンで指定する

package.json
{
  "name": "monorepo",
  "version": "1.0.0",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

2.リポジトリのルートにpackagesディレクトリを作成

├── /packages
└── package.json

3.ワークスペースを作成
 3-1. packagesディレクトリ配下にcommon(共通ライブラリ)を作成

├── /packages
│   └── /common
└── package.json

 3-2. commonにpackage.jsonを作成
cd packages/common && yarn init

├── /packages
│   └── /common
│     └── package.json
└── package.json

nameがワークスペース名となる

common/package.json
{
  "name": "@projects/common",
  "version": "1.0.0",
  "main": "index.ts"
}

 3-3. packagesディレクトリ配下にprd(Next.js本番環境)を作成
yarn create next-app /packages/prd

├── /packages
│   └── /common
│   │  └── package.json
│   └── /prd
│      └── package.json
└── package.json

 3-4. ワークスペース名を編集する

prd/package.json
{
  "name": "@projects/prd",
  "version": "1.0.0"
  ## 以下省略
}

 3-5. packagesディレクトリ配下にstg(Next.js検証環境)を作成
yarn create next-app /packages/stg

├── /packages
│   ├── /common
│   │  └── package.json
│   ├── /prd
│   │  └── package.json
│   ├── /stg
│      └── package.json
└── package.json

 3-6. ワークスペース名を編集する

stg/package.json
{
  "name": "@projects/stg",
  "version": "1.0.0"
  ## 以下省略
}

4.common(共通ライブラリ)をprd、stgから参照できるようにする

package.json
{
 ## 以上省略
  "dependencies": {
    "@projects/common": "*"
  }
  ## 以下省略
}

5.各ワークスペースのpackage.jsonのパッケージをルートのpackage.jsonに転記する

※Amplifyの仕様上、dependeciesnextは各Next.jsプロジェクトのルート直下のpackage.jsonに記述されている必要がある。(Amplify側がNext.jsプロジェクトかの判別に使っていると思われる)

package.json
{
 ## 以上省略
  "dependencies": {
    "@projects/common": "*",
    ## 各ワークスペースのパッケージを転記する
  },
 "devDependencies": {
    ## 各ワークスペースのパッケージを転記する
  }
  ## 以下省略
}

6.各scriptを記述する
リポジトリのルートから各ワークスペースのscriptの実行、またはワークスペース全てにscript実行できるようにpackage.jsonにscriptを記述する。

package.json
{
  "scripts": {
    "build-all": "yarn build:prd & yarn build:stg",
    "build:prd": "yarn workspace @project/prd build",
    "build:stg": "yarn workspace @project/stg build",
    "dev-all": "yarn dev:prd & yarn dev:stg",
    "dev:prd": "yarn workspace @project/prd dev",
    "dev:stg": "yarn workspace @project/stg dev",
    "start-all": "yarn start:prd & yarn start:stg",
    "start:prd": "yarn workspace @project/prd start:local",
    "start:stg": "yarn workspace @project/stg start:local",
    "lint-all": "yarn workspaces run lint",
    "lint:prd": "yarn workspace @project/prd lint",
    "lint:stg": "yarn workspace @project/stg lint",
    "lint:common": "yarn workspace @project/common lint"
  }
}

Amplifyでのモノレポ運用

Amplifyはモノレポに対応しており、下記のようなことが可能。

  • モノレポのサブフォルダを接続する際のビルド設定の自動検出
  • 特定のアプリプロジェクト内でコードが変更された場合にのみビルドトリガーする
  • 単一のビルド仕様ファイル(amplify.yml)で複数のアプリのビルド設定を定義する

Amplifyのビルド設定には、モノレポのルートにamplify.ymlを作成する。
今回はprdとstgをそれぞれAmplifyでホスティングする。
下記のようにamplify.ymlを定義する。

amplify.yml
version: 1
applications:
  - appRoot: packages/prd
    frontend:
      phases:
        preBuild:
          commands:
            - cd ../../
            - yarn
        build:
          commands:
            - cd packages/prd
            - yarn build
      artifacts:
        baseDirectory: out
        files:
          - '**/*'
      cache:
        paths:
          - ../../node_modules
          - ./node_modules
          - .next/cache/**/*
  - appRoot: packages/stg
    frontend:
      phases:
        preBuild:
          commands:
            - cd ../../
            - yarn
        build:
          commands:
            - cd packages/stg
            - yarn build
      artifacts:
        baseDirectory: .next
        files:
          - '**/*'
      cache:
        paths:
          - ../../node_modules
          - ./node_modules
          - .next/cache/**/*

参考:
AWS Blog: Set up continuous deployment and hosting for a monorepo with AWS Amplify Console

AWS Doc: Monorepo build settings

18
4
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
18
4