【Node.js】npmからpnpmに乗り換える

記事

当サイトにはプロモーション・広告が含まれています。

先月、有名なnpmパッケージがマルウェアに汚染されるという出来事があった。

npm debug and chalk packages compromised

今までにもnpmパッケージの汚染は度々起こっていたらしいが、今回は20億ダウンロードを誇るパッケージで起こったということもあり、事情に疎い私もこの騒動を知ったのだった。

SNSを見ていると「npm installするのも怖い…」「npm installする前にチェックする方法はないのか」といった意見が見られた。その中でpnpmに事前チェック機能があるらしいことを知ったので、安全面を考えてnpmからpnpmに移行することにした。

pnpmとは

Node.jsのパッケージマネージャーで、“Performant npm”の略。“Performant”からも分かるように、パッケージインストールが高速でディスク容量が節約できて効率的なのが特徴である。

Fast, disk space efficient package manager | pnpm

npmが各プロジェクトごとにnode_moduleディレクトリにインストールするのに対し、pnpmはグローバルに一度インストールしたものをプロジェクトで共有する形をとる。各プロジェクト内のnode_moduleはシンボリックリンクが配置される。

npmからの移行手順

環境

ローカルPC:Windows11

  • Node.js:v22.20.0
  • Volta:1.1.1

ホスティング:Cloudflare Pages

  • Framework preset: None
  • Build command: npm run build

pnpmのインストール

以下のVoltaコマンドでpnpmをインストールする

volta install pnpm

node_moduleフォルダを削除

既存のnode_moduleフォルダを削除する。

rm -rf node_modules

package.jsonに追加

プロジェクトで使用するパッケージマネージャーを pnpm に限定するための設定を追加する。package.jsonのscriptsの項目に以下を記述する。

{   
    ...
    "scripts": {
        "preinstall": "npx only-allow pnpm", 
        ...
    }
}

パッケージを移行する

既存のパッケージをpnpmへ移行する。

pnpm import

このコマンドにより、既存のロックファイル(npmの場合はpackage-lock.json)を読み込み、pnpmのロックファイルpnpm-lock.yamlが作成される。

package-lock.jsonの削除

不要になったpackage-lock.jsonファイルを削除

rm package-lock.json

パッケージをインストール

pnpm install

すると、以下のような警告が出た。

Warning ignore build scripts: esbuild, sharp

pnpm10以降には、デフォルトでプログラムの自動実行をブロックする機能がある。悪意のあるパッケージがインストールされるリスクを防ぐためである。

esbuild(JavaScriptビルドツール)とsharp(画像処理ライブラリ)は信頼性の高いパッケージなので、実行を許可しても問題はない。メッセージ通りにコマンドを実行する。

pnpm approve-builds

pnpm-workspace.yamlファイルが作成され、以下のような記述がされる。

ignoredBuiltDependencies:
  - esbuild
  - sharp

「ビルドの依存関係を無視する」とは…? Google検索で出てこなかったのでChatGPT君(無料版)に訊いた。

ignoredBuiltDependencies は「特定の依存パッケージをインストール時のビルド対象から除外する設定」で、「ネイティブ依存の不要なビルドを避けて、インストールを軽量化・安定化する」のだそうだ(ITリテラシーが低いので、フワッとしか理解しかできていない)。

node_moduleフォルダ内を見ると、以下のようになっている。

node_moduleフォルダ

npmのときは一体何に使っているのかというくらいたくさんのフォルダがあったが、pnpmはフォルダ数が少なく、矢印でグローバルを参照している(シンボリックリンク)。

pnpmのコマンド

npmと互換性が高く、大抵の操作はnpmをpnpmに置き換えて行うことができる。

# npm
npm instal package-name
# pnpm
pnpn instal package-name

やっておいたほうがよい設定

pnpm10以降には、デフォルトでプログラムの自動実行をブロックする機能があるが、更にセキュリティを強化しておきたい。

pnpm 10.16から、パッケージ公開から最低限の日数が経過するまでインストール対象外にするオプションが追加された。マルウェアに汚染されたパッケージは、基本的にパッケージ公開後1日以内に発見されて駆除される。なので、更新から一定期間経過したパッケージのみインストールするよう設定しておけば、リスクを軽減できるということである。

グローバルに設定

pnpm config set minimumReleaseAge 1440

グローバル設定ファイルは、Windows11の場合C:\Users\PC_User\AppData\Local\pnpm\config\rcにある。設定できたかどうかはpnpm config listで確認できる。

プロジェクトのpnpm-workspace.yamlに記述

minimumReleaseAge: 1440

Cloudflare Pagesの設定

npmからpnpmに変更になったことで、Cloudflare Pagesの設定も変更しなければならないかと思ったが、普通にビルドできた。package.json"preinstall"の項目を追加した以外は変更していない。


pnpmに換えれば必ずしも安全というわけではないが、npmで無防備でいる頃よりもセキュリティが高まったのではないかと思う。

おまけ

pnpmのタブがアクティブになっている

Astroをインストールするコマンドが記述されている箇所だが、2番目のpnpmがアクティブになっている。

Install Astro | Docs

npmを1番目にして立てつつ、pnpmを推しているような印象(※個人の感想です)。

参考ページ

☕コーヒーをおごる

Buy Me A Coffee

このブログについて

コーディングやWeb関連技術の記事と、買い物など日々のメモから成り立っています。 →少しだけ詳しく

広告