🌕 moonでのmonorepo管理とpackemonでのCJS/ESMのdual package
🌕 moon
- 一貫性を持ったmonorepo管理ツール for JavaScript
 - ハッシュを使ったファイルキャッシュ
 - プロジェクトのパッケージ間の依存関係の分析とタスク実行
 - Node.js/npmパッケージマネージャーのバージョン管理と一貫性
 - TypeScriptのProject Referendcesの一貫性
 
比較
- Nx: The Framework + Pluginで拡張する
- Lerna: Nx傘下、ライブラリ公開向け
 
 - Turborepo: タスク実行の最適化をする
 - moon: monorepoでの一貫性を提供する
- Packemon: moonと同じ作者。ESM/CJSのライブラリ公開向け
 
 
比較(言語)
[^1]: Ref Nx and Turborepo
🌕 moon
- 将来的なカバー範囲の予想
- Nx >= 🌕 moon > Turborepo
 
 - Moonでは、Remote caching/分散ビルドはこれから
 - Moonは、プラグインというよりはコマンドなので、拡張性はNxの方が高そう
 
🌕 moonの特徴
- 一貫性
 - Node.jsやnpmといった実行環境に関してもmoonで管理できる
- Voltaに近い仕組み
 
 
🌕 moonのStructure
- Workspace: monorepoのルートのこと
- チーム開発なら1つのチームがいるスペース
 - WorkspaceのNodeやパッケージマネージャーの環境を統一できる
 
 - Project: 各Packagesのこと
- client/server/commonみたいなパッケージなど
 - Project間の依存関係を管理して、常に同期できる
 
 

🌕 moon 使い方のイメージ 1
- .moon/workspace.ymlにワークスペースの設定を定義する
- どのディレクトリをProjectにするか
 - Node/npm/TypeScript/VSC(git)などの共通設定
 
 - .moon/project.ymlにプロジェクトの共通タスクを定義する
 <プロジェクト>/project.ymlにプロジェクト固有のタスクを設定する
🌕 moon 使い方のイメージ 2
moon run <プロジェクト名>:<タスク名>でタスクを実行できるclientのbuildを実行するならmoon run client:buildmoon run :buildで全てのプロジェクトのbuildを実行できる(lerna run <script>相当)
- 実行するタスクとそのプロジェクトがものは自動で実行される
 
🌕 moon 使い方のイメージ 3
moon runでタスクを実行する前に、workspaceの定義と実行してる環境が一致するかをチェックしてる- 一致してないなら環境を一致させるmoon syncが自動的に叩かれる
 - Node/npmのバージョン、TSのProject Referencesの依存関係、ローカルのキャッシュの状態などが意識せずに合うように同期される
 - チーム開発での環境のばらつきが抑えられて一貫性が保てる
 
🌕 moonの特徴
- 意識しなくても常に
moon syncが行われている- workspaceのNode.jsやnpmのバージョンを変更したら、自動的にバイナリがダウンロードされるし
.nvmrcとかに同期される(syncVersionManagerConfig) - workspaceにprojectを増やしたら、TSのProject Referencesが自動的に更新される(syncProjectWorkspaceDependencies)
 - Project間の依存は、package.jsonにも反映される(syncProjectReferences)
 
 - workspaceのNode.jsやnpmのバージョンを変更したら、自動的にバイナリがダウンロードされるし
 - チーム開発で「変更入れたので、ローカルでこのコマンド実行しておいてください」みたいのが減る
 
🌕 moonの面白いポイント
moon ciというCI向けのコマンドが用意されている- project.ymlのタスクの定義に基づき、自動的にタスクが実行される
- タスク側に 
runInCI: falseとなければとりあえず実行される 
 - タスク側に 
 
比較
🔥 Packemon
Packemon
- 🌕 moonと作者は同じ
 - ESM/CJSのdual packageに対応したライブラリを公開する用途のbundler/build tool
- Babel/rollupをいい感じにまとめて、package.jsonの設定も自動的に修正される
 
 
Packemonの特徴
package.jsonのpackemonフィールドに出力形式を設定する と- → 自動的に 
main/exports/types/type/enginesなど公開するための設定が追加される 
  "packemon": [
    {
      "inputs": {
        "index": "./src/index.ts"
      },
      "platform": "node",
      "format": "cjs"
    },
    {
      "inputs": {
        "node": "./src/index.ts"
      },
      "platform": "node",
      "format": "mjs"
    }
  ],
  "types": "./dts/index.d.ts",
  "main": "./cjs/index.cjs",
  "engines": {
    "node": ">=14.15.0",
    "npm": ">=6.14.0"
  },
  "exports": {
    "./package.json": "./package.json",
    "./*": {
      "types": "./dts/*.d.ts",
      "node": {
        "import": "./mjs/*.mjs",
        "require": "./cjs/*.cjs"
      }
    },
    ".": {
      "types": "./dts/index.d.ts",
      "node": {
        "import": "./mjs/index.mjs",
        "require": "./cjs/index.cjs"
      }
    }
  },
  "files": [
    "cjs/**/*.{cjs,mjs,map}",
    "dts/**/*.d.ts",
    "mjs/**/*.{mjs,map}",
    "src/**/*.{ts,tsx,json}"
  ]

Packemon: その他
- Babelを使ったCJS <-> MJSのinterop変換が実装されている
 - index-wrapper.mjsというCJSをMJSとしてラップして、Dual package hazardを回避時する実装も持っている
- requireとimportで別のファイルを読み込むと、insteanceofがコケる問題の回避