TuBrief
Subscribed Channels
Videos
Community

pnpmモノレポをNubに移行する中で直面したハマりポイントと解決策

TuBrief Editorial
July 27, 2026
0
Computing/Software

Written with AI assistance from the source video. The video is the authority.

日本語한국어EnglishEspañol中文हिन्दीFrançaisPortuguêsDeutschРусскийالعربيةBahasa Indonesia

Related Video

There's a NEW Package Manager!? (Bun Alternative)8:29

There's a NEW Package Manager!? (Bun Alternative)

Better Stack

More from the community

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

September 13, 2026

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

September 13, 2026

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

September 13, 2026

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

September 13, 2026

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

September 12, 2026

Apple Won the AI Race

September 12, 2026

Comments (0)

Log in to leave a comment

No posts yet

© 2026 . All rights reserved.

TuBrief
Subscribed Channels
Videos
Community
Log in

pnpmモノレ포をNubに移行する中で直面したハマりポイントと解決策

Node.jsエコシステムは疲弊しています。tsx、dotenv-cli、nvm、pnpmを何層にも重ね上げたビルド環境は重く、何か一つ更新するたびにスクリプトが絡み合って壊れます。Rust製の統合ツールキットであるNubが、このパッケージのカオスを単一バイナリにまとめてくれると登場したとき、正直嬉しくもありつつ半信半疑でした。

実際にプロダクション環境のpnpm-workspaceモノレポをNubへ移行してみると、かなり魅力的ではありました。しかし、すんなり移行できるほど甘くはありませんでした。依存関係の衝突、24時間のセキュリティロックダウンポリシー、CIキャッシュの分離問題まで、実務ですぐにぶつかる障害が次々と現れました。

ワークスペース移行時に発生する依存関係ツリーの制御方法

Nubのパッケージエンジンであるaubeは、既存のpnpm-workspace.yamlやpackage.jsonのworkspacesを即座に認識します。pnpm-lock.yaml v9 スキーマとバイトレベルで互換性があるという説明通り、既存の仮想Store構造(node_modules/.store/)をデフォルトで活用します。

問題となるのは、平坦化(hoisted)されたnode_modules構造を暗黙の前提としていた古いツール群です。マイグレーション直後に実行するとMODULE_NOT_FOUNDエラーを吐いてクラッシュします。今すぐサービスを動かせる状態にするには、--node-linker hoistedオプションでパッケージツリーを展開した状態で進める必要があります。

キャッシュが適用されたWarmインストール基準で、デフォルトのGVSモードは346 msかかります。Hoistedモードは1461 msと4倍以上遅くなりますが、pnpm v10+の3453 msに比べれば依然として2倍以上高速です。最初はHoistedモードで互換性を確保し、古いツールの依存関係を排除しながらデフォルトのGVSモードへ移行していく方が精神的に楽です。

`bash
#!/usr/bin/env bash
set -euo pipefail

echo "==> [1/4] Nubバイナリの確認"
if ! command -v nub &> /dev/null; then
echo "Error: Nubが見つかりません。'npm i -g @nubjs/nub'を先に実行してください。"
exit 1
fi

echo "==> [2/4] pnpm-lock.yamlスキーマのチェック"
if [ -f "pnpm-lock.yaml" ]; then
nub pm use nub
fi

echo "==> [3/4] package.json内に実行エンジンを明記"
node -e '
const fs = require("fs");
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
pkg.devEngines = pkg.devEngines || {};
pkg.devEngines.packageManager = {
name: "nub",
version: "^0.4.0",
onFail: "warn"
};
fs.writeFileSync("package.json", JSON.stringify(pkg, null, 2) + "\n");
'

echo "==> [4/4] Lockfileの生成"
nub install --frozen-lockfile=false
`

このスクリプトでpnpm-lock.yamlをnub.lockに変換すれば、毎回スクリプトの修正で潰れていた時間を週あたり2時間以上節約できます。

24時間のリリース経過時間制限と緊急ホットフィックス対応

Nubのセキュリティポリシーはかなり厳格です。ライフサイクルスクリプトをデフォルトでブロックし、npm Provenance署名がない場合はERR_NUB_TRUST_DOWNGRADEを投げます。最も戸惑うのはminimumReleaseAgeオプションです。リリースされてから24時間が経過していないパッケージバージョンはセキュリティ検証待ち状態とみなされ、インストールがブロックされます。

普段は素晴らしい防壁となりますが、ゼロデイ脆弱性が発覚して1時間前にリリースされたパッチバージョンを即座にデプロイしなければならない時には「嘆きの壁」と化します。この場合、ルートのpackage.jsonにビルドスクリプトを許可するパッケージを明記し、コマンドで制限を突破する必要があります。

json { "name": "@org/monorepo-root", "private": true, "allowBuilds": { "esbuild": true, "sharp": true, "@fast-cve/patch-pkg": true } }

ブロックされたホットフィックスパッケージを迂回して反映するフローは以下の通りです。

`bash

1. 24時間未満のホットフィックスパッケージを手動承認して追加

nub add --allow-build=@fast-cve/patch-pkg @fast-cve/patch-pkg@1.0.1-hotfix

2. 承認キューに入ったビルドスクリプトを一括承認

nub approve-builds
`

nub approve-buildsを実行するとブロックリストが解除され、ビルドが即座に再開されます。なお、OSVデータベースにマルウェア(MAL-*)として登録されているパッケージはこのコマンドでも解除できないため、その場合は上位の代替バージョンを探す必要があります。

GitHub ActionsとDockerにおけるキャッシュレイヤーの分離

CI/CDの速度を極限まで上げるには、Nubのキャッシュパスを把握しておく必要があります。Nodeバイナリは~/.cache/nub/node/<version>/に入り、パッケージのCAS(Content-Addressable Store)は~/.cache/nub/とnode_modules/.store/に分散されます。

Dockerのマルチステージビルドでは、BuildKitのキャッシュマウントを使用してインストールレイヤーを完全に隔離しないとキャッシュ効果を得られません。

`dockerfile
FROM ghcr.io/nubjs/nub:latest AS base
WORKDIR /app

FROM base AS dependencies
COPY package.json nub.lock pnpm-workspace.yaml ./
COPY packages/core/package.json ./packages/core/
COPY packages/api/package.json ./packages/api/

BuildKitキャッシュマウントでストアを再利用

RUN --mount=type=cache,target=/root/.cache/nub
nub ci --prefer-offline

FROM dependencies AS builder
COPY . .
RUN nub run build --filter=@org/api

FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production

COPY --from=builder /app/packages/api/dist ./dist
COPY --from=builder /app/node_modules ./node_modules

EXPOSE 3000
CMD ["node", "dist/index.js"]
`

GitHub Actionsでは、actions/setup-nodeの代わりにnubjs/setup-nub@v0を使用します。

`yaml
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

  - uses: nubjs/setup-nub@v0
    with:
      cache: true

  - run: nub ci
  - run: nub -r run build
  - run: nub -r run test

`

setup-nubとキャッシュを組み合わせたnub ciの速度は346 ms程度です。従来のpnpm(3453 ms)と比べてパイプラインのパッケージインストール時間が大幅に短縮され、CIビルド全体にかかる時間が半減します。月末のクラウドインフラ請求書を見ると、間違いなく気分が良くなります。

シェルラッパーによるチームメンバーの開発環境の一括統一

Nubはoxcベースのメモリトランスパイラを内蔵しているため、tsxやts-nodeを使うことなくTypeScriptコードを直接実行できます。.envファイルも自動で読み込んでくれます。pnpm run(442.7 ms)を使用するたびに発生していたNode.jsプロセスのブートストラップオーバーヘッドが消失し、nub runによるスクリプト実行時間は14.7 msまで短縮されます。この体感差はかなり大きいです。

チームメンバー間でのNode.jsバージョンの不一致を防ぐには、ルートに.node-versionを配置しておきます。

bash echo "22.15.0" > .node-version nub src/index.ts

Node 22.15.0以降では、同期的なmodule.registerHooks()のおかげでコールドスタートの遅延が完全に解消されます。新しくチームに参加したメンバーが来た際も、複雑な説明なしで一発で環境を揃えられるよう、自動化スクリプトを1つ用意しておくのが最もスマートです。

`bash
#!/usr/bin/env bash
set -euo pipefail

echo "==> 開発環境のセットアップを開始"

if ! command -v nub &> /dev/null; then
if command -v brew &> /dev/null; then
brew install nubjs/tap/nub
else
npm install -g --ignore-scripts=false @nubjs/nub
fi
fi

pnpm, npm コマンドをNubエンジンへ自動ルーティング

nub pm shim
nub node install
nub install

if [ ! -f ".env.local" ] && [ -f ".env.example" ]; then
cp .env.example .env.local
fi

echo "==> セットアップ完了。'nub run dev'で実行してください。"
`

nub pm shimを実行しておけば、習慣的にpnpm installやnpm runを入力してもNubの実行ファイルが横取りして処理してくれます。CLIの実行オーバーヘッドがpnpm exec(191 ms)からnubx(11 ms)に削減される上に、「自分の環境では動かないんですが」といった言葉を聞きながらデバッグする時間を週に2時間は削減できます。