DenoはV8 JavaScriptエンジンをベースに実装されたJavaScript/TypeScriptランタイムです。
「Node.jsに関する10の反省点」を修正すべく、Node.jsの開発者でもあるRyan Dahl氏を中心に開発が行われています。
Denoの特徴
Denoの特徴を要約すると、以下の点が挙げられます。
- TypeScriptを標準でサポート
- パーミッションシステム
- 生産性
- Web標準への準拠
- ES Modulesベースのモジュールシステム
- npmパッケージのサポート
- 最新のJavaScript仕様に準拠
これらについて詳しく説明していきます。
TypeScriptを標準でサポート
Denoの大きなメリットとして、TypeScriptをサポートしていることが挙げられます。
Node.jsでTypeScriptを使用したいときは、基本的にtypescript
やts-node
パッケージをnpmでインストールし、tsconfig.json
を用意する必要があるかと思います。
Denoは標準でTypeScriptをサポートしており、これらのセットアップ作業が不要になります。
例えば、以下のようなTypeScriptファイルがあったとします。
interface User {
id: number;
name: string;
}
const user: User = {
id: 1,
name: "foo",
};
console.log(user);
Denoでは、TypeScriptファイルをスクリプトとして実行することができます。
$ deno run sample.ts
このように、deno run
コマンドを使うことで、TypeScriptファイルをトランスパイルし、実行することができます。
また、トランスパイル後のJavaScriptコードはローカルのファイルシステムにキャッシュされるため、2回目以降に同じファイルを実行する際はトランスパイルなどがスキップされます。
型チェックについて
Deno v1.23以降のバージョンでは、deno run
コマンドはデフォルトではTypeScriptの型チェックを実行しません。
もし型チェックを実行したい場合は、deno check
コマンドまたは--check
オプションを使用する必要があります。
$ deno check main.ts
$ deno run --check main.ts
パーミッションシステム
Denoはパーミッションシステムを提供しています。
どういうことかというと、例えば、以下のような処理はデフォルトでは一切実行することができません:
- ファイルの読み書き
- ネットワークアクセス
- 環境変数の参照
- サブプロセスの実行
これらの処理を行うには、Denoを実行する際に明示的に権限を与える必要があります。
例えば、ファイルの読み込みを行いたいときは--allow-read
、ネットワークアクセスを行いたいときは--allow-net
オプションを指定するといった具合です。
$ deno run --allow-read --allow-net ./sample.ts
この仕組みにより、Denoでは高いセキュリティが期待できます。
生産性
Denoは開発の場面で必要な多くの機能をはじめから提供しています。
- フォーマッタ(
deno fmt
コマンド) - リンタ(
deno lint
コマンド) - テストランナ(
deno test
コマンド) - APIドキュメントの生成(
deno doc
コマンド) - バンドラ(
deno bundle
コマンド) - LSPサーバ(
deno lsp
コマンド)
大抵の作業はdeno
コマンドのみで完結するため、ツールの選定やセットアップ、学習などにかかるコストが軽減されます。
ブラウザ(Web標準)との互換性
DenoはWeb標準との互換性が強く意識されており、多くの機能がWeb標準をベースに実装されています。
例)
- HTTPリクエストを送信したいときはfetch APIを使用します。
- WebSocketサーバと通信する際はWebSocketオブジェクトを使用します。
- バイナリデータを扱いたいときはTyped Arrayを使用します。
- ストリーミング処理を行いたいときはStreams APIを使用します。
- マルチスレッドで処理したいときはWorkerオブジェクトを使用します。
ES Modulesベースのモジュールシステム
DenoではNode.jsで提供されていたCommonJS形式のモジュールはサポートされていません。
DenoはES Modulesを前提としており、ライブラリを利用したいときは、以下のようにimport
文のURLでダウンロード先を指定します。
import { bold, red } from "https://deno.land/std@0.93.0/fmt/colors.ts";
console.log(bold(red("Hello, Deno!")));
スクリプトを実行する際に、Denoはimport文で指定されたライブラリがローカルのファイルシステムにダウンロードされているか確認します。もしダウンロードされていなければ、Denoは自動でそれをダウンロードし、ローカルのファイルシステムへキャッシュします。
一度ダウンロードされたライブラリは削除しない限りローカルにキャッシュされ続けるため、2回目以降の読み込み時はダウンロード自体がスキップされます。
このように、Deno自身がモジュールマネージャのような機能を備えていることもあって、Node.jsにおけるpackage.json
やnpm
などの仕組みは存在しません。
npmパッケージのサポート
詳細についてはnpmパッケージを使用するのページでも解説いたしますが、Denoはnpmパッケージのサポートも提供しています。
大きな特徴として、Denoではnpmパッケージの利用のためにユーザーにnpm install
の実行やpackage.json
などを要求することはありません。
npmパッケージについてもdeno.land/xで公開されているサードパーティパッケージなどと同様に、Denoの実行時に自動的にダウンロードされ、ローカルにキャッシュされます。
もしDenoの公式のパッケージレジストリであるdeno.land/xに目的を満たすパッケージが見つからない場合は、npmパッケージの使用も検討してみるとよいかもしれません。
最新のJavaScript仕様に準拠
Denoの組み込みAPIや標準ライブラリであるdeno_stdは、Promise
やAsync Iterator
などのJavaScriptの最新機能を念頭に設計されています。
Node.jsで重要な役割を果たしていたStreamやEventEmitterなどのAPIは、Denoの本体には含まれません。(これらのAPIはNode.jsの互換レイヤーで提供されます)
Denoのユースケース
DenoはNode.jsと同様に、様々な用途で使用することができます。
例)
- スクリプティング
- CLIツールの開発 (
deno compile
コマンドでシングルバイナリ化できます) - バックエンドAPI (Oakなど)
- フロントエンド開発 (Aleph.js, Fresh, packupなど)
- Discordボット (Discordeno)