Deno
作者 | ライアン・ダール |
---|---|
初版 | 2018年5月13日[1] |
最新版 |
1.40.5
/ 2024年2月15日 |
リポジトリ | |
プログラミング 言語 | |
対応OS | |
種別 | ランタイム環境 |
ライセンス | MITライセンス |
公式サイト |
deno |
Denoは、V8 JavaScriptエンジン及びRustプログラミング言語に基づいた、JavaScript及びTypeScriptのランタイム環境である。Node.jsの作者であるライアン・ダールによって作成され、セキュリティと生産性に焦点を当てている[2]。ライアン・ダールが2018年に行った講演「Node.jsに関する10の反省点」で発表された[3]。Denoは単一の実行ファイル内でランタイム環境とパッケージ管理システムの両方の役割を明示的に引き受けるので、別途パッケージ管理システムを必要としない[4][5]。
歴史
DenoはJSConf EU 2018でのライアン・ダールによる講演「Node.jsに関する10の反省点」で発表された[3]。ライアン・ダールはこの講演において、後悔しているNode.jsの初期設計での決定について言及し、以下の点を挙げている。[6]
- APIの設計でpromiseを使用しないという選択をしたこと
- 古いGYPビルドシステムを使用するようにしたこと
node_modules
とpackage.json
の採用- 拡張子を除外したこと
index.js
による魔法のようなモジュールの依存関係の解決- V8のサンドボックス環境の破壊
最終的に、彼はDenoのプロトタイプ版を発表し、Protocol Buffersのようなシリアライズツールを使用したメッセージの受け渡しを通じてシステムコールバインディングを実現し、アクセス制御用のコマンドラインフラグを提供することを目指した。
Denoは当初はGoで実装され、特権側 (Goとシステムコールアクセス) と非特権側 (V8) の間のシリアライズにProtocol Buffersを使用していた[7]。しかしながら、実行時間が2倍になることとガベージコレクションの圧力から、コードは直ぐにRustで再実装された[8]。非同期イベント駆動型プラットフォームとしてlibuvに代わってTokioが導入され、より高速な「ゼロ・コピー」シリアライゼーション及びデシリアライゼーションのためにFlatBuffersが導入された[9]が、2019年4月にシリアライゼーションの大幅なオーバーヘッドを測定したベンチマークが公開されたことによって[10]、FlatBuffersは同年8月の後半に削除された[11]。
Goの標準ライブラリをモデルとしたDenoの標準ライブラリは、広範なツール及びユーティリティを提供するために2018年11月に作成され、Node.jsの依存関係での爆発問題を部分的に解決した[12]。
概要
Denoは現代のプログラマのための生産的で安全なスクリプト環境を目指している[4]。Node.jsと同様に、Denoはイベント駆動型アーキテクチャに重点を置いており、非ブロッキングコアIOユーティリティのセットとそのブロッキング版を提供している。DenoはWebサーバの作成や科学計算に利用することができる。発音は当初デノだったがディーノ[13][14] となった模様。
Node.jsとの比較
DenoとNode.jsはGoogle ChromeなどのChromiumベースのウェブブラウザで採用されているV8 JavaScriptエンジン上に構築されたランタイム環境である。どちらも内部イベントループがあり、スクリプトと広範なコマンドラインユーティリティを実行するためのコマンドラインインタフェースを提供している。
DenoがNode.jsと異なる主な点は以下の通りである[4]:
- CommonJSの代わりに、ES Moduleをデフォルトのモジュールとシステムとして使用する。
- ウェブブラウザと同様に、依存関係 (ローカル及びリモート) を読み込むためにURLを使用する。
- リソースを取得するためのパッケージ管理システムが組み込まれているので、npmは不要である。
- キャッシングメカニズムを備えたスナップショットTypeScriptコンパイラを使用することによるTypeScriptのサポート。
- 幅広いWeb APIを実装することによるウェブブラウザとの互換性の向上。
- サンドボックスコードを実行するために、ファイルシステムとネットワークアクセスを制御することができる。
- promise、ES6及びTypeScriptの機能を利用するためにAPIを再設計したこと。
- コアAPIのサイズを最小限にしながら、外部に依存関係の無い大きな標準ライブラリを提供すること。
- 特権システムAPIを呼び出しとバインディングの使用のために、メッセージ受け渡しチャネルを使用すること。
例
以下は、読み取り / 書き込み / ネットワーク権限無しの基本的なDenoスクリプトの実行例である (サンドボックスモード):
deno run main.ts
権限を許可する場合は、明示的に対応するフラグを指定することが必要:
deno run --allow-read --allow-net main.ts
スクリプトの依存関係を検査する場合は、info
サブコマンドを使用する:
deno info main.ts
Denoでの基本的なHello worldは以下の通りである (Node.jsと同様):
console.log("Hello world");
Denoはウェブブラウザでは使用できない殆どのDeno固有のAPIにグローバル名前空間を提供する。UNIXのcat
コマンドは、以下のように実装することができる:
/* cat.ts */
/* Deno APIs are exposed through the `Deno` namespace. */
const { stdout, open, copy, args } = Deno;
// Top-level await is supported
for (let i = 0; i < args.length; i++) {
const filename = args[i]; // Obtains command-line arguments.
const file = await open(filename); // Opens the corresponding file for reading.
await copy(file, stdout); // Performs a zero-copy asynchronous copy from `file` to `stdout`.
}
上記のDeno.copy
関数は、Goのio.Copy
関数のように機能する。stdout
(標準出力) はWriter
に出力され、file
の入力はReader
である。このプログラムを実行するには、ファイルシステムの読み取り許可が必要である:
deno run --allow-read cat.ts myfile
以下はDenoによる基本的なHTTPサーバの実装である:
// Imports `serve` from the remote Deno standard library, using URL.
import { serve } from "https://deno.land/std@v0.21.0/http/server.ts";
const body = new TextEncoder().encode("Hello World\n");
// `serve` function returns an asynchronous iterator, yielding a stream of requests
for await (const req of serve(":8000")) {
req.respond({ body });
}
上記のスクリプトを実行すると、Denoはリモートの標準ライブラリファイルを自動的にダウンロードしてキャッシュし、コードをコンパイルする。同様に、URLを入力ファイル名として指定することで、明示的にダウンロードせずに標準ライブラリスクリプト (ファイルサーバなど) を直接実行することができる (-A
は全ての権限を有効にするフラグである):
$ deno run -A https://deno.land/std/http/file_server.ts
Download https://deno.land/std/http/file_server.ts
Compile https://deno.land/std/http/file_server.ts
...
HTTP server listening on http://0.0.0.0:4500/
脚注
- ^ “Contributors to denoland/deno”. GitHub. 2020年5月15日閲覧。
- ^ Dylan Schiemann (2018年12月26日). “Deno: Secure V8 TypeScript Runtime from Original Node.js Creator”. InfoQ. 2019年11月18日閲覧。
- ^ a b JSConf (2018年6月6日). “Node.jsに関する10の反省点”. YouTube. 2019年11月18日閲覧。
- ^ a b c “Deno Manual”. deno.land. 2019年11月18日閲覧。
- ^ Paul Krill (2018年6月21日). “Ryan Dahl’s Node.js regrets lead to Deno”. InfoWorld. 2019年11月18日閲覧。
- ^ Ryan Dahl (2018年6月). “Design Mistakes in Node”. 2019年11月18日閲覧。
- ^ “denoland/deno at golang”. GitHub. 2019年11月18日閲覧。
- ^ “Suggestion: Look into porting to Rust and using Tokio”. GitHub. 2019年11月18日閲覧。
- ^ “Protobuf seems like a lot of overhead for this use case?”. GitHub. 2019年11月18日閲覧。
- ^ “Replace flatbuffers”. GitHub. 2019年11月18日閲覧。
- ^ “Remove flatbuffers”. GitHub. 2019年11月18日閲覧。
- ^ “deno_std”. GitHub. 2019年11月18日閲覧。
- ^ “Pronunciation #5707”. GitHub. 2022年8月22日閲覧。
- ^ “マニュアル冒頭に発音が記載”. deno.com. 2024年1月12日閲覧。