Jaybanuan's Blog

どうせまた調べるハメになることをメモしていくブログ

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 には次のような利点がある。

  1. バージョン範囲を指定できる

    "version": "^11.0.0" のように、SemVer を用いた柔軟な指定が可能である。

  2. 不一致時の動作を制御できる

    バージョンが一致しない場合に、エラー (error)・警告 (warn)・自動ダウンロード (download) などの挙動を onFail で指定できる。

  3. 実行環境をまとめて管理できる

    パッケージマネージャーだけでなく、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の属性

はじめに

オンプレの権威DNSVPCから利用するのに、VPCのenableDNSHostnamesとenableDNSSupportを有効化する必要があるとのことだが、このフラグの意味が分からなかったので、調査した。

公式ドキュメント

docs.aws.amazon.com

有効/無効のテーブル

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

参考

walk0204.hatenablog.com

現行の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 ハイパフォーマンスコンピューティング

この表は、以下の公式ドキュメントを元にまとめている。

docs.aws.amazon.com

docs.aws.amazon.com

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"に変換されるためだと思われる。

developer.mozilla.org

Axiosのプロキシの設定

JavaScriptのHTTPクライアントであるAxiosについて。 Axiosにプロキシの設定はあるが、実行環境がNode.js専用らしく、実行環境がブラウザの場合は裏側で動いているHTTPエージェントを切り替える必要があるらしい。 そんなことができるのか。。。

github.com

具体的なコーディングはこちらが分かりやすい。

qiita.com

ちなみに、https-proxy-agentソースコードはこちら。

github.com

もうちょっと言うと、これはモノレポになっていて、実際のhttps-proxy-agentのコードはこちららしい。

github.com

github.com