パッケージの肥大化は「怠慢」の証である:`files`フィールドで制御するnpmの真の最適化術
君たちのプロジェクトの `node_modules` は、なぜあんなに重いのか。そして、君たちが公開した npm パッケージは、なぜ不要なテストファイルや開発用設定まで含んで全世界に撒き散らされているのか。
多くのエンジニアは、`.npmignore` を使って「除外リスト」を管理することで満足している。だが、それは「ブラックリスト方式」という設計上の敗北だ。今日は、パッケージ開発における「ホワイトリスト管理」への転換と、そこから生まれる圧倒的なインストール体験の向上について、アーキテクトの視点から説く。
—
1. なぜ「ブラックリスト(.npmignore)」では不十分なのか
`.npmignore` を使った除外管理は、直感的だが極めて危険だ。開発中に追加した新しいツール(例えば `cypress` や `storybook` 等)のフォルダや、一時的に作成した `scripts/debug.ts` などが、うっかり `npm publish` 時に混入するリスクが常に付きまとう。
さらに言えば、`.npmignore` は `.gitignore` との二重管理になりがちで、同期漏れが発生する。これでは、CI/CDのパイプライン上で「なぜかパッケージサイズが肥大化した」という怪現象をデバッグする羽目になる。
プロの解は `package.json` の `files` フィールドによるホワイトリスト管理だ。
推奨構成:package.json の「files」プロパティ
「必要なものだけを明示的に指定する」。これだけで、事故は0%になる。
{
“name”: “@your-scope/your-package”,
“version”: “1.0.0”,
// ホワイトリスト:ここに列挙されたファイル・ディレクトリのみがパッケージに含まれる
“files”: [
“dist”, // トランスパイル済みの実行可能コード
“README.md”, // ドキュメントは必須
“LICENSE”, // ライセンス表記は法的要件
“types” // 型定義ファイル(d.ts)
],
// .npmignoreは不要になる。存在しても無視される(filesが優先されるため)
}
—
2. 肥大化を防ぐための「ビルド・アーティファクト」最適化
`files` で指定したディレクトリ(例: `dist`)の中身も、当然最適化が必要だ。特に `sourceMap` や `test` コードが混入していないかを確認せよ。
実務で役立つ設定:npm-packlist の確認
パッケージを公開する前に、実際に何がアーカイブされるのかを確認するコマンドを叩く習慣をつけろ。
実際にローカルでnpm packを実行し、生成された.tgzの中身を確認する
npm pack –dry-run
もし、`dist` 内に `.map` ファイルが大量に含まれているなら、ビルド設定を見直せ。ライブラリ開発において、デバッグ用のソースマップを公開パッケージに同梱する必要は、原則としてない。
rollup/esbuild での最適化設定(例: rollup.config.js)
export default {
output: {
file: ‘dist/index.js’,
format: ‘esm’,
sourcemap: false, // 開発環境以外では必ずfalseにすること
},
// プラグインでテストコードなどをビルドターゲットから完全に除外する
plugins: [
terser({ compress: { drop_console: true } }) // コンソールログも削除し軽量化
]
};
—
3. チーム開発の生産性を最大化する「神設定」と共有ルール
個人の腕前に依存する開発は、スケールしない。チーム全体で「クリーンなパッケージ」を維持するための、アーキテクトの定石を紹介する。
必須の Husky & lint-staged 設定
コミット前にパッケージの健全性をチェックするフローを強制せよ。
// package.json
“lint-staged”: {
“.{ts,tsx}”: [
“eslint –fix”,
“prettier –write”
]
}
チーム開発における「絶対ルール」
1. `files` の外部は「聖域」: `files` に記述していないディレクトリにソースコードを配置するな。
2. `main`, `module`, `types` の厳密な設定:
ユーザーがインストールした際、解決されるエントリポイントを最適化しろ。
{
“main”: “dist/index.js”,
“module”: “dist/index.esm.js”,
“types”: “dist/index.d.ts”,
“sideEffects”: false // これを記述することで、webpack等のバンドラがツリーシェイキングを最適化できる
}
—
4. 最後に:なぜ「軽さ」に拘るのか
エンジニアの中には「今の時代、ストレージや帯域は潤沢だから多少重くても問題ない」と考える者がいる。だが、それは「CI/CDのオーバーヘッド」を理解していない証拠だ。
1. `npm install` の時間が 1 秒増える。
2. それが 10 人のチームで 1 日 10 回行われる。
3. 1 日で 100 秒、月に 40 分もの時間が「不要なファイルのダウンロード」に消えている。
さらに、パッケージが軽量であれば、エッジコンピューティングやブラウザ環境でのコールドスタートにも有利に働く。
君たちが書く数行の `package.json` が、世界中の開発者の環境で動く。その責任の重さを自覚し、「ホワイトリストによる統治」を今日から実践せよ。それが、一流のエンジニアとそれ以外を分かつ境界線だ。
さあ、今すぐ君たちのパッケージの `package.json` を開き、不要なファイルが含まれていないか確認しろ。それがアーキテクトとしての最初の仕事だ。