TuBrief
Subscribed Channels
Videos
Community

Migrer un monorepo pnpm vers Nub : galères et solutions

TuBrief Editorial
July 27, 2026
0
Computing/Software

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

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

Related Video

Un NOUVEAU gestionnaire de paquets !? (Une alternative à Bun)8:29

Un NOUVEAU gestionnaire de paquets !? (Une alternative à Bun)

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

Migrer un monorepo pnpm vers Nub : galères et solutions

L'écosystème Node.js est épuisé. Un environnement de build superposant tsx, dotenv-cli, nvm et pnpm est lourd, et le moindre script s'emmêle les pinceaux à chaque mise à jour. Quand Nub, un toolkit intégré développé en Rust, a débarqué en promettant de rassembler ce bazar de paquets dans un binaire unique, j'étais franchement ravi, mais aussi un peu sceptique.

En passant concrètement un monorepo pnpm-workspace de production sous Nub, le résultat s'est avéré plutôt séduisant. Cependant, les choses se déroulent rarement sans accroc. Conflits de dépendances, politique de verrouillage de sécurité de 24 heures ou encore isolation du cache CI : nous avons rapidement heurté des obstacles très concrets sur le terrain.

Comment maîtriser l'arbre de dépendances lors de la transition d'un workspace

aube, le moteur de paquets de Nub, reconnaît immédiatement les workspaces du pnpm-workspace.yaml et du package.json existants. Comme promis par sa compatibilité au octet près avec le schéma v9 de pnpm-lock.yaml, il utilise par défaut la structure de Store virtuel existante (node_modules/.store/).

Le problème vient des anciens outils qui présupposent implicitement une structure node_modules aplatie (hoisted). Si vous les exécutez juste après la migration, ils plantent en renvoyant une erreur MODULE_NOT_FOUND. Pour remettre immédiatement le service sur rails, il faut commencer par étaler l'arbre de paquets avec l'option --node-linker hoisted.

En installation à chaud (warm) avec cache appliqué, le mode GVS par défaut prend 346 ms. Le mode Hoisted prend 1461 ms, ce qui est plus de 4 fois plus lent, mais cela reste plus de 2 fois plus rapide que les 3453 ms de pnpm v10+. Au début, il est plus simple d'assurer la compatibilité avec le mode Hoisted, puis de passer au mode GVS par défaut au fur et à mesure que vous éliminez les dépendances envers les anciens outils.

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

echo "==> [1/4] Vérification du binaire Nub"
if ! command -v nub &> /dev/null; then
echo "Error: Nub est introuvable. Exécutez d'abord 'npm i -g @nubjs/nub'."
exit 1
fi

echo "==> [2/4] Vérification du schéma pnpm-lock.yaml"
if [ -f "pnpm-lock.yaml" ]; then
nub pm use nub
fi

echo "==> [3/4] Déclaration du moteur d'exécution dans 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] Génération du Lockfile"
nub install --frozen-lockfile=false
`

En convertissant pnpm-lock.yaml en nub.lock avec ce script, vous pouvez économiser plus de 2 heures par semaine auparavant perdues à réparer des scripts cassés.

Restriction d'âge des releases de 24 heures et gestion des hotfix d'urgence

Nub applique une politique de sécurité assez stricte. Il bloque par défaut les scripts de cycle de vie et renvoie une erreur ERR_NUB_TRUST_DOWNGRADE si la signature npm Provenance est absente. Le plus déroutant reste l'option minimumReleaseAge. Les versions de paquets publiées depuis moins de 24 heures sont considérées comme en attente de vérification de sécurité, ce qui en bloque l'installation.

En temps normal, c'est un excellent bouclier, mais lorsqu'une vulnérabilité zero-day éclate et qu'il faut déployer immédiatement un correctif sorti il y a 1 heure, cela devient un mur d'incompréhension. Dans ce cas, il faut déclarer les paquets autorisés à exécuter des scripts de build dans le package.json racine et forcer le passage via des commandes.

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

Voici le flux pour contourner et appliquer un paquet de hotfix bloqué :

`bash

1. Approbation manuelle et ajout du paquet de hotfix de moins de 24 heures

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

2. Approbation en masse des scripts de build placés en file d'attente

nub approve-builds
`

L'exécution de nub approve-builds débloque la liste et poursuit le build immédiatement. Les paquets enregistrés comme malveillants (MAL-*) dans la base de données OSV ne pourront pas être débloqués, même avec cette commande ; il faudra alors chercher une version alternative supérieure.

Isolation des couches de cache dans GitHub Actions et Docker

Pour booster la vitesse de votre CI/CD, il est essentiel de connaître les chemins de cache de Nub. Le binaire Node se trouve dans ~/.cache/nub/node/<version>/, tandis que le CAS (Content-Addressable Store) des paquets est réparti entre ~/.cache/nub/ et node_modules/.store/.

Dans un build multi-stage Docker, il faut utiliser le mount de cache de BuildKit afin d'isoler complètement la couche d'installation pour bénéficier de l'effet de cache.

`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/

Réutilisation du dépôt grâce au mount de cache 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"]
`

Dans GitHub Actions, on charge nubjs/setup-nub@v0 au lieu de actions/setup-node.

`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

`

La vitesse de nub ci combiné à setup-nub et au cache tourne autour de 346 ms. Par rapport à pnpm (3453 ms), le temps d'installation des paquets dans le pipeline est considérablement réduit, ce qui divise par deux le temps total de build CI. En regardant la facture d'infrastructure cloud à la fin du mois, on retrouve le sourire.

Harmoniser l'environnement de développement de l'équipe grâce à un wrapper shell

Nub intègre un transpiler en mémoire basé sur oxc, ce qui permet d'exécuter du code TypeScript directement sans passer par tsx ou ts-node. Il lit également les fichiers .env automatiquement. En éliminant le surcoût de démarrage du processus Node.js qui survenait à chaque fois avec pnpm run (442,7 ms), le temps d'exécution des scripts avec nub run chute à 14,7 ms. La différence est très nette à l'usage.

Pour éviter la fragmentation des versions de Node.js entre les membres de l'équipe, il suffit de placer un fichier .node-version à la racine.

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

À partir de Node 22.15.0, la méthode synchrone module.registerHooks() élimine complètement la latence au démarrage à froid (cold start). Lorsqu'un nouveau membre rejoint l'équipe, configurer un script d'automatisation reste le moyen le plus propre de lui fournir un environnement prêt à l'emploi sans longues explications.

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

echo "==> Début de la configuration de l'environnement de développement"

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

Routage automatique des commandes pnpm et npm vers le moteur Nub

nub pm shim
nub node install
nub install

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

echo "==> Configuration terminée. Exécutez 'nub run dev' pour lancer."
`

En exécutant nub pm shim, toute saisie réflexe de pnpm install ou npm run sera interceptée et traitée par l'exécuteur Nub. Le surcoût d'exécution de la CLI passe de pnpm exec (191 ms) à nubx (11 ms), et vous économisez au moins 2 heures par semaine à déboguer des problèmes du type « ça marche pas sur ma machine ».