Deno

Denoの開発環境とDeno自体は未熟であり、本番環境で使用すべきではありません。
Denoの開発期間を考慮すると、Denoチームのパフォーマンスは芳しくなく、
Node.jsがDenoの機能に徐々に追いつき、Bunのような同じエコシステムの競合相手も現れました。
Denoの将来に自信を持つことは困難です。
  • Rustで開発されています。
  • APIは可能な限りWeb環境と互換性があります。
  • 独自の意見を持つ deno fmt, deno lint, deno test, =deno bench=。
  • デフォルトで安全であり、きめ細かなパーミッションシステムを持ち、動的なパーミッション要求をサポートします。
    現在、Denoは内部で使用されるフィールドが多いため、きめ細かなパーミッションは非常に不便で、最終的には粗いパーミッションの使用を余儀なくされる可能性があります。
  • TypeScriptをネイティブでサポートしており、JavaScriptコミュニティがTypeScriptに移行しているため、この点はますます重要になっています。
  • Node.js互換性。
Denoの組み込み機能は概して厳密なテストが不足しており、コミュニティのフィードバックに頼ってバグを修正しています。
LTSは様々なプロジェクトでますます短くなる傾向がありますが、Deno 2がリリース時に6ヶ月をLTSと宣言したことは、それでも笑いを誘います。
Deno Land Inc.は、他のエコシステム製品のクローン/代替品の開発に熱心です。
これらの製品は明らかに熟慮が不足しており、保守性に疑問があります。
この傾向はDeno自体にも影響を与えており、例えばNode.js互換性は、マーケティング上の誇大宣伝が実際の提供を凌駕した典型的な例です:
https://docs.deno.com/runtime/reference/node_apis/#fully-supported-modules
少し規模の大きいDenoプロジェクトではLSPの応答速度が遅くなり、Denoを使いたい開発者を簡単に遠ざけてしまいます。
対照的に、Node.jsとTypeScriptをベースにしたプロジェクトでは、同様の問題は全くありません。
DenoのLSPのデフォルト設定はかなり保守的で、例えば documentPreloadLimit のデフォルト値は1000ですが、実際の開発では簡単にそれを超えてしまいます。
WHATWGストリームモデルのデザインはかなり簡素で、Node.jsのストリームには遠く及びません。
例えば、ユーザーはストリームが閉じているかどうか、またはいつ閉じるかさえ知ることができません。
モジュールはインポートされる状況に応じてプロトコルを決定します。
モジュールがローカルモジュールとしてインポートされる場合、そのモジュールの import.meta.url はfileプロトコルになります。
モジュールがリモートモジュールとしてインポートされる場合、その import.meta.url はhttp/httpsプロトコルになります。
問題は、非常に多くのAPIが単一のプロトコルしかサポートしていないことで、例えば Deno.readFile はfileプロトコルのみをサポートし、http/httpsプロトコルをサポートしていません。
この状況は、開発者が import.meta.url を使用する際に、より多くの認知的負荷を負うことになります。
根本的な問題は、Denoがインポートされたモジュール(キャッシュ)のローカルパスを公開しないことにあり、これは設計段階で解決できる問題です。
https://github.com/denoland/deno/issues/5987
悲しいことに、Denoはfetch関数がfileプロトコルをサポートするようにすることで、ファイル読み込みに関する問題を解決しました。
https://github.com/denoland/deno/issues/3196
TypeScriptは .ts 拡張子のモジュールパスを .js 拡張子にコンパイルすることをサポートしていません。
一方、Denoのモジュールパスは常に .ts 拡張子です。
そのため、Node.jsモジュール用に設計されたTypeScriptプロジェクトのコードはDenoでは動作しません。
TypeScript 5からallowImportingTsExtensions設定項目のサポートが始まり、これによりプロジェクト内で .ts 拡張子を使用できますが、
この設定項目はnoEmitまたはemitDeclarationOnlyが設定されている場合にのみ使用可能という制限があり、
つまり .ts 拡張子を使用しながらNode.jsで使用可能なコードを生成することはできません。
Deno公式が推進するJavaScriptパッケージレジストリ。
JSRは宣伝上、現代のJavaScriptパッケージレジストリを謳っていますが、依然としてDeno版のnpmに過ぎません。
JSRはnpmのスーパーセットではありません、TypeScriptがJavaScriptのスーパーセットではないように。
このレジストリは、Denoに存在する依存関係管理の問題(Ryan Dahlが2018年に投げたブーメランがついに彼自身に当たった)を解決するために大きく貢献しています。
異なるモジュールが異なるレジストリから依存関係をインポートしたり、SemVerの欠如により同じレジストリの異なるサブバージョンの依存関係をインポートしたりします。
これにより、プロジェクトのサイズが膨張し(LSPの負担が増加)、インポートされた依存関係間で参照の同一性が失われます。
Deno公式は、元のパッケージレジストリdeno.land/xは引き続き使用可能であると述べていますが、
公式の標準ライブラリstdがdeno.land/xで更新停止していることを考えると、今後もdeno.land/xにパッケージを公開し続けることは無意味であると予想されます。
現在、専用プレフィックス jsr: を使用することで(Deno 1.28で追加されたnpmモジュールサポートのように)、URLを簡素化できます。
https://github.com/oakserver/oak
https://fresh.deno.dev/
Deno公式が2022年に発表したフルスタックWebフレームワークで、Next.jsをターゲットとしています。
以下の理由から、その使用はお勧めできません。
  • DenoサポートについてテストされているReactライブラリはほとんどありません。
  • 内部ではReactの軽量版であるPreactを使用しており、これは将来性のない技術路線です。
DenoはCDN経由でJSDOMをインポートできます。
import { JSDOM } from 'https://esm.sh/jsdom@22.1.0'
https://github.com/b-fuze/deno-dom
このプロジェクトはRustのhtml5everパッケージのバインディングです。
Deno FFIを使用したSQLite。
利点:
  • インターフェースはbetter-sqlite3とほぼ同じです。
  • 高性能。
WASMにコンパイルされたSQLite。
利点:
  • 最小限のパーミッション。
  • クロスプラットフォーム。
欠点:
  • DenoファイルシステムAPIの制限を受けます。
  • デフォルトで有効になっているコンパイルオプションが非常に少ないため、自分でコンパイルする必要がある可能性が高いです。
Deno 1.21以降、標準ライブラリはかなりの数のテスト機能を提供しており、
これにより、ほとんどの場合、サードパーティライブラリを使用せずにテストを完了できます。
Denoのこの技術選択は、Node.jsのテストにおけるベンダーロックインの問題を効果的に回避します。
現在、標準ライブラリはBDDスタイル、mock/stub、スナップショットマッチング、タイマーシミュレーションをすでにサポートしています。
https://deno.land/std@0.181.0/testing
https://github.com/denoland/deno_std/issues/1779
Denoは、プロジェクトを1つのスクリプトファイルにパッケージングするための組み込みコマンド deno bundle を提供します。
Ryan Dahlはかつてこのコマンドの削除を提案しましたが、このアイデアは後に撤回されました。
しかし、v1.31では、このコマンドはコミュニティの議論なしに非推奨としてリストアップされ、公式マニュアルではesbuildに切り替えることを推奨しました。
v2.4では、deno bundleは不可解にも復活し、その基盤にはesbuildが使用されています。
v2.5では、HTMLファイルをパッケージングのエントリーポイントとしてサポートします。
deno run コマンドでスクリプトを実行すると、TypeScriptタイプチェッカーがロードされ、Denoプロセスがより多くのメモリを使用します。
deno compile でコンパイルしてから実行すると、スクリプトのメモリ使用量が大幅に改善されます。