package.jsonのルートのpackageManagerとdevEnginesのpackageManagerの違い
はじめに
Turborepo はモノレポ向けのビルドツールである。試しに以下のコマンドでプロジェクトを作成したところ、
pnpm create turbo@latest myapp --package-manager pnpm
生成された package.json には以下のエントリが含まれていた。
{ ... "packageManager": "pnpm@9.0.0", ... }
本記事の執筆時点における pnpm の最新バージョンは 11.14.0 である。そのため、この値を 11.14.0 に書き換えようと packageManager エントリの仕様を調べたところ、この設定はもともと Node.js の Corepack のために策定された仕様であること、さらに Node.js 25 から Corepack が同梱されなくなることが分かった。
そこで本記事では、package.json のルートに記述する packageManager と、新たに導入された devEngines.packageManager の違いについて整理する。
1. そもそもルートの packageManager とは
package.json のトップレベル(ルート)に記述する "packageManager": "pnpm@9.0.0" のような設定は、もともと Node.js に同梱されていたツール Corepack のために策定された仕様である。
npm のドキュメントに記載されていない理由
npm は Corepack を介さず単体で動作するという設計思想を採用している。そのため、npm 公式の package.json ドキュメントには、このルートの packageManager エントリは記載されていない。実際、npm 単体ではこの設定を参照しない。
一方、pnpm や Yarn は Corepack が存在しない環境でも、このエントリを独自に解釈して使用するパッケージマネージャーのバージョンを切り替える機能を実装した。その結果、現在では packageManager は Corepack 以外でも広く利用されるようになっている。
ルート packageManager の限界
ルートの packageManager には、「バージョンを単一の固定値でしか指定できない」という制限がある。
例えば、以下のような指定は可能である。
"packageManager": "pnpm@9.0.0"
しかし、以下のようなセマンティックバージョニング(SemVer)による範囲指定は行えない。
^9.0.0 >=11.0.0
この柔軟性の欠如が、後述する devEngines が提案された背景の一つとなっている。
2. 新しい標準 devEngines の登場
ルートの packageManager が抱える制約を解消し、エコシステム全体で統一的に利用できる仕組みとして、OpenJS Foundation が主導して提案したのが devEngines である。
{ "devEngines": { "packageManager": { "name": "pnpm", "version": "^11.0.0", "onFail": "error" } } }
devEngines のメリット
devEngines には次のような利点がある。
バージョン範囲を指定できる
"version": "^11.0.0"のように、SemVer を用いた柔軟な指定が可能である。不一致時の動作を制御できる
バージョンが一致しない場合に、エラー (
error)・警告 (warn)・自動ダウンロード (download) などの挙動をonFailで指定できる。実行環境をまとめて管理できる
パッケージマネージャーだけでなく、Node.js などのランタイムのバージョンも同じ場所で管理できる。
3. 現時点での対応方法
現時点では、devEngines の対応状況はツールによって異なる。そのため、互換性を重視するのであれば、やや冗長ではあるものの、以下のように両方を記述しておくのが無難である。
{ "packageManager": "pnpm@11.14.0", "devEngines": { "packageManager": { "name": "pnpm", "version": "^11.14.0" } } }
一方、最新の npm や pnpm は devEngines に対応している。そのため、これらのツールのみを対象とするプロジェクトであれば、packageManager を省略し、devEngines のみを記述してもよい。
{ "devEngines": { "packageManager": { "name": "pnpm", "version": "^11.14.0" } } }
まとめ
- ルートの
packageManagerは Corepack のために策定された従来の仕様である。 - Node.js における Corepack の同梱終了を見据え、エコシステムは
devEnginesへの移行を進めている。 - 最新の npm や pnpm を利用するのであれば、
devEnginesを利用するだけで十分な場合が多い。
AWSのVPCのDNSの属性
はじめに
オンプレの権威DNSをVPCから利用するのに、VPCのenableDNSHostnamesとenableDNSSupportを有効化する必要があるとのことだが、このフラグの意味が分からなかったので、調査した。
公式ドキュメント
有効/無効のテーブル
enableDNSHostnamesとenableDNSSupportをそれぞれ有効/無効にしたときのマトリックスは以下の通り。
| enableDNSHostnames | enableDNSSupport | パブリックDNS名の付与 | パブリックDNS名の解決 | プライベートDNS名の付与 | プライベートDNS名の解決 |
|---|---|---|---|---|---|
| no | no | no | no | yes | no |
| no | yes | no | yes | yes | yes |
| yes | no | yes | no | yes | no |
| yes | yes | yes | yes | yes | yes |
パブリックDNS名の付与
パブリックDNS名の付与は、enableDNSHostnamesによって決定される。
| enableDNSHostnames | enableDNSSupport | パブリックDNS名の付与 | パブリックDNS名の解決 | プライベートDNS名の付与 | プライベートDNS名の解決 |
|---|---|---|---|---|---|
| no | no | no | no | yes | no |
| no | yes | no | yes | yes | yes |
| yes | no | yes | no | yes | no |
| yes | yes | yes | yes | yes | yes |
プライベートDNS名の付与
プライベートDNS名の付与は、enableDNSHostnamesにもenableDNSSupportにもよらず、常に付与される。
| enableDNSHostnames | enableDNSSupport | パブリックDNS名の付与 | パブリックDNS名の解決 | プライベートDNS名の付与 | プライベートDNS名の解決 |
|---|---|---|---|---|---|
| no | no | no | no | yes | no |
| no | yes | no | yes | yes | yes |
| yes | no | yes | no | yes | no |
| yes | yes | yes | yes | yes | yes |
DNS名の解決
DNS名の解決は、enableDNSSupportによって決定される。
| enableDNSHostnames | enableDNSSupport | パブリックDNS名の付与 | パブリックDNS名の解決 | プライベートDNS名の付与 | プライベートDNS名の解決 |
|---|---|---|---|---|---|
| no | no | no | no | yes | no |
| no | yes | no | yes | yes | yes |
| yes | no | yes | no | yes | no |
| yes | yes | yes | yes | yes | yes |
参考
現行のEC2のシリーズの一覧(2025/12時点)
はじめに
試験対策のため、AWSのEC2の現行のシリーズをまとめてみた。 数が多くて入れ替えも度々あるためか、公式ドキュメントも微妙に抜け漏れがある。
現行のEC2のシリーズの一覧
| カテゴリ | シリーズ | 説明 |
|---|---|---|
| 汎用 | M | 汎用 |
| Mac | macOS | |
| T | バースト可能パフォーマンス | |
| コンピューティング最適化 | C | コンピューティング最適化 |
| メモリ最適化 | R | メモリ最適化 |
| U | ハイメモリ | |
| X | メモリ集約型 | |
| ストレージ最適化 | D | 高密度ストレージ |
| H | (普通のHDD?) | |
| I | ストレージ最適化 | |
| Im | ストレージ最適化 (vCPUとメモリの比率が1対4) | |
| Is | ストレージ最適化 (vCPUとメモリの比率が1対6) | |
| 高速コンピューティング | DL | (Deep Learning ??) |
| F | FPGA | |
| G | グラフィックを多用する | |
| Inf | AWS 推論 | |
| P | GPU アクセラレーション | |
| Trn | AWS Trainium | |
| VT | ビデオトランスコーディング | |
| ハイパフォーマンスコンピューティング | Hpc | ハイパフォーマンスコンピューティング |
この表は、以下の公式ドキュメントを元にまとめている。
JavaScriptでのMapのソート (キーは文字列が前提)
はじめに
JavaScriptのMapで、キーが文字列である前提で、キーを基準にソートしたい。 ただし、ソートは普通の文字列比較で良いので、自分で比較関数を書きたくない。 結果、辿り着いたコードの書き方をメモしておく。
JavaScriptにもJavaのSortedMapみたいなのがあれば便利なんだけど。
キーでソートしたMapを得る
const myMap = new Map([ ["banana", 6], ["apple", 5], ["strawberry", 10], ["coconut", 7], ]); const result = new Map( [...myMap.keys()] .sort() .map(k => [k, myMap.get(k)]) ); console.log(result)
出力結果は以下。
Map(4) {
'apple' => 5,
'banana' => 6,
'coconut' => 7,
'strawberry' => 10
}
キーでソートしたMapの値の配列を得る
const myMap = new Map([ ["banana", 6], ["apple", 5], ["strawberry", 10], ["coconut", 7], ]); const result = [...myMap.keys()] .sort() .map(k => myMap.get(k)) console.log(result)
出力結果は以下。
[ 5, 6, 7, 10 ]
補足
ちなみに、ググると以下のコードも見つかったが、キーにカンマが存在すると正しく動作しない場合がある。
const myMap = new Map([ ["x", 5], ["x,1", 9], ]); const result = new Map([...myMap].sort()); console.log(result)
実行結果は以下。
Map(2) { 'x,1' => 9, 'x' => 5 }
理由は、sort()に比較関数を渡さない場合は要素を文字列化して比較されるので、ここでのキーはそれぞれ["x", 5].toString()で"x,5"に、["x,1", 9].toString()で"x,1,9"に変換されるためだと思われる。
Axiosのプロキシの設定
JavaScriptのHTTPクライアントであるAxiosについて。 Axiosにプロキシの設定はあるが、実行環境がNode.js専用らしく、実行環境がブラウザの場合は裏側で動いているHTTPエージェントを切り替える必要があるらしい。 そんなことができるのか。。。
具体的なコーディングはこちらが分かりやすい。
ちなみに、https-proxy-agentのソースコードはこちら。
もうちょっと言うと、これはモノレポになっていて、実際のhttps-proxy-agentのコードはこちららしい。