0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

pnpm の patchedDependencies で依存パッケージにパッチを当てる(patch/patch-commit 実践)

0
Posted at

pnpm patchedDependencies で依存にパッチを当てる

pnpm の patch / patch-commit を使えば、upstream 修正を待たずに依存パッケージのバグを安全に回避できます。本記事では patchedDependencies の運用フローと、実例として drizzle-zod の型定義パッチを紹介します。

パッチを当てたい状況

  • upstream 修正待ちだが、今すぐ直したい
  • fork して publish するほどではない
  • node_modules 直編集は再インストールで消えるので不可

正攻法:pnpm patch → patch-commit

pnpm がパッチファイル生成から patchedDependencies 登録まで自動化してくれます。lockfile も変更されるので、PR に含めましょう。

patches/ と pnpm-lock.yaml をコミットしておけば、CI/デプロイで pnpm install を実行する限り同じパッチが適用されます(pnpm専用)。

1. パッチ用ディレクトリを展開

pnpm patch <pkg>@<version>
# 例: pnpm patch drizzle-zod@0.8.3

一時ディレクトリのパスが表示されます。

2. 展開されたファイルを編集

表示されたディレクトリ内のファイルを直接編集します。

3. パッチを確定

pnpm patch-commit <展開されたパス>

# 共有/CI用(新規clone時の適用確認)
pnpm install

これで:

  • patches/ にパッチファイル(.patch)が生成(--patches-dir で変更可)
  • package.json の pnpm.patchedDependencies に自動登録
{
  "pnpm": {
    "patchedDependencies": {
      "some-pkg@1.2.3": "patches/some-pkg@1.2.3.patch"
    }
  }
}

手動で patchedDependencies を書く(非推奨)

仕組みとしては可能ですが、パス・差分元・改行・バージョン固定などでミスしやすいため、pnpm patch → patch-commit の流れを推奨します。

手動で書く場合も、pnpm patch で展開した実体を編集して git diff で .patch を作るのが事故が少ないです。

# 1) 展開
pnpm patch some-pkg@1.2.3

# 2) 展開先でファイルを編集

# 3) 差分生成(展開先で git init → git diff 等)

# 4) patches/ に .patch を配置し、package.json に登録
pnpm install

パッチの解除

公式修正が出たら、パッチを外して通常アップデートに戻します。

pnpm patch-remove <pkg>@<version>
pnpm install

patch-remove は patchedDependencies とパッチファイルを削除します。

依存を更新した後に ERR_PNPM_PATCH_NOT_APPLIED が出たら「パッチ更新 or 削除」のタイミングです。

ケーススタディ:drizzle-zod の SQLite 型推論バグ

問題

drizzle-zod 0.8.x で SQLite の text() が Buffer 型として推論される:

text('name').notNull()
// 期待: z.string()
// 実際: z.custom<Buffer>() 相当

Issue: #4705

原因

型定義の分岐が Buffer 側に寄るケースがあり、その結果 text() が Buffer 推論になります。

パッチ内容

対象ファイル(3つ):

  • column.types.d.ts
  • column.types.d.mts
  • column.types.d.cts

修正内容:

- : TColumn['_']['data'] extends Buffer ? z.ZodType<Buffer>
+ : TColumn['_']['dataType'] extends 'buffer' ? z.ZodType<Buffer>

data ではなく dataType を基準にすることで、SQLite text() が Buffer 側に落ちるのを回避します。

注意:zod/v4 import を揃える

drizzle-zod 内部が zod/v4 を参照するため、アプリ側も揃える:

import { z } from 'zod/v4'  // not 'zod'

参考

noteでは「AI × 技術 × ビジネス」視点で書いています

Qiitaでは純粋な技術Tipsを、noteでは「その技術をどう活かすか」というPM/事業視点の記事を書いています。

  • Qiita: ハマりポイント、解決策、設定方法
  • note: AI駆動開発の実践、技術選定の判断軸、放置プロジェクトの救い方

👉 note.com/ebiyy

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?