プログラミング
Denoとの友情は終わり、今やNodeが私の親友だ
Friendship ended with Deno, now Node is my best friend (dbushell.com)
要約
著者は長年Denoを使用してきたが、最近のNode.jsの進化に驚き、DenoからNode.jsへの回帰を決意した。Node.jsはECMAScriptの糖衣構文をサポートし、APIも近代化されており、TypeScriptのネイティブ実行も可能になった。一方、Denoはスタートアップ文化への傾倒や技術的な問題から勢いを失っており、著者はNode.jsの改善されたエコシステムと開発体験を高く評価している。
全文翻訳
Denoとの友情は終わり、今やNodeが私の親友だ
2026年10月3日 土曜日
ついにNodeに這って戻る時が来た!
今月、SvelteKitのクライアントプロジェクトでNodeをヘビーに使っている。いつからNodeはこんなに良くなったのだろうか? Denoはあまりにも長い間私の定番ランタイムだったので、Nodeの使い方を忘れてしまっていた。今戻ってみると、すべてのECMAScript†シュガーがサポートされており、古い面倒なAPIは置き換えられたり近代化されたりしている。最も重要なのは、require() を二度と見なくて済むことだ。
† Oracleの商標紛争は、肯定的な結末を迎えそうにないようだ。
パッケージ管理
公式のNodeドキュメントでは、NVMをインストールしてNodeとNPMを管理するために、インターネットスクリプトを直接bashにパイプすることを推奨している(我々は決して学ばない)。NVMとNPMに関する私の(古い)経験は、輝かしいものではなかった。Fast Node Manager (FNM) がNodeのバージョンを切り替えるのに優れていると聞いた。明らかに私は最先端を使っているが、クライアントプロジェクトには安定性が求められる。
すぐにpwnedされないように、PNPMも採用した。(NPMの「M」は「malware」を意味する。)私が使用する一部のスクリプトには、ハードコードされたバイナリ名‡があるため、2つのエイリアスを追加した。
alias npm=pnpm
alias npx=pnpx
コピーコード
それは犯罪かもしれないが、今のところ完璧に機能している。
‡ 編集:様々なバイナリをシンボリックリンクした時期と混同している可能性がある。エイリアスは、NPMがインストールされていることを前提としたインストールガイドから手順をコピーする際に役立つ。
PNPMはまた、インストール後のスクリプトをブロックする。
NPMはまだそれらをyoloするのか?
マルウェアの更新を遅延させるために、pnpm-workspace.yamlにさらに設定を追加した。
minimumReleaseAge: 1440
trustPolicy: no-downgrade
コピーコード
最初は、Microsoftが報告されたマルウェアを削除するのに少なくとも1ヶ月かかるため、minimum release ageを「1ヶ月」に設定しようとした。これにより、PNPMが適切なバージョンを見つけるのに苦労する依存関係の問題が発生した。私は「1日」に落ち着いた。これは、次のShai‑Huludのベータテストを他の誰かにやらせるのに十分な長さだ。
TypeScript
Nodeは今や、星が揃わないと赤ん坊のように癇癪を起こすことなく、TypeScriptを実行できるようになった。とはいえ、NPMにTypeScriptパッケージを公開するのは簡単ではない。
error: [ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING]: Stripping types is currently unsupported for files under node_modules
コピーコード
なぜ? ただ型を剥がせばいいのに、君ならできると知っている!悪魔と契約させてくれ!
パッケージ作成者がTypeScriptで書かれたパッケージを公開することを思いとどまらせるために、Node.jsはnode_modulesパス下のファイル内のTypeScriptファイルを処理することを拒否する。
Node.js v26.10.0 ドキュメント
この制限は技術的なものではなく、哲学的なものだ。しかし、理解はできる。TypeScriptはMicrosoftの製品だ。そのゲートを開放すると、エコシステム全体が汚染されるだろう。誰もMicrosoftを増やしたくない。ECMAScriptに軽量な「ネイティブ型」があれば嬉しい。型アノテーションの提案がある。それらが実を結ぶ前に私は引退するだろうと推測している。
TypeScriptパッケージがないということは、私のものをバンドルするために最新の使い捨てスラッグを見つける必要があるということだ。Tsdownがその役目を果たし、追加のドットファイルはわずか2つだった。それはあまり気に入っていない(すべてのドットファイルは間違いを表す)。Deno.jsonなどを削除した後、損益は相殺されるだろう。
Microsoftのロックインといえば、GitHubを台無しにされたので、私は自分のForgejoインスタンスをセルフホストしている。NPMの制限により、私のパッケージは「出所」を失った。自分のものを許可するためにPNPMの信頼ポリシーを設定する必要があった。楽しい時間だった。
私のウェブサイトの移行
Nodeの最後のテストは、静的サイトジェネレーターをDenoから移行することだった。数バージョン前のNodeであれば、メジャーなリファクタリングが必要だっただろう。今日、Node v26.10.0では、驚くほど少ない作業で済んだ。
必要な変更は、DenoのファイルシステムAPIをnode:fsに置き換えることだけだった。これは私が覚えているもの(文字通り約10年前)よりもはるかに改善されている。それ以外では、Deno.serveをHonoのnodeアダプター(node:httpのラッパー)に置き換える必要があった。
この最小限の実行可能な移行の後、ビルドが15%速くなったことにショックを受けた。私のコードベースはまだ慣用的なDenoを好んでいる。他の組み込みNode APIを使用しないことで、パフォーマンスを犠牲にしているのだろう。それは後で探求すべきことだ。唯一さらに行った変更は、Denoの@std/pathをnode:pathに置き換えることだった。これは直接的なインポートの置き換えだ。
だから、もし途中でTL;DRするとすれば:Nodeは輝きを取り戻した、すごい!
おそらくあなたはしばらく前から知っていたのだろう。私は習慣と慣れ親しんだことからDenoを使い続けていた。そして、最近サーバーサイドJavaScriptを書くことに熱心ではなかった。
Denoの衰退
これは死んだ馬を鞭打っているので、この部分は埋葬する。結局のところ、Denoはシリコンバレーのサーカスに「成功」を定義させることで失敗した。Denoは革新的なモダンJavaScriptランタイムから、魅力のない製品を持つ退屈なスタートアップになった。従業員の半数が解雇され、残った人々はAIの幻想をツイートしたり、Temu Cloudflareでバイブコーディングしたりしている。
今日、Denoランタイムを使用する理由はない。Deno Land Inc.は数年前にそこで革新を止めた。Nodeは着実に追いつき、いくつかの点でDenoを追い越した。
私を最終的に遠ざけたのは以下の点だった:
数週間にわたるZSH統合の破損
JSRの攻撃的な「429 (Too Many Requests)」
Denoが同時HTTPリクエストでクラッシュするバグ(複数)
基本的に、私の他の批判の上に、使用をほぼ不可能にするようなものだった。JSRサポートは、リクエストに応じて私のアカウントを非常に迅速に削除してくれた。インターネット上にデッドプロファイルを残したくない。私のパッケージはどれも表示されないが、古いバージョンはインストール可能だ。
初期は楽しかったが、今はさよならを言う時だ。
brew uninstall deno
コピーコード