※このエントリはDenoの技術的なメリデメというよりかは、どうして僕がDenoが好きなのかをただただ語るだけの記事になっております。技術的な話はこちらの記事が参考になります。
僕はDenoが好きです。どのくらい好きかと言われたら「エディタに組み込んじゃうくらい」好きです。
プログラムを書く人にとってエディタとはテキスト編集をする際の手足となるもので、これにDenoを組み込むという事は苦楽を共にし、プログラミングのお供もとい相棒にしていくという覚悟があると言えるのではないでしょうか。
この記事ではそんなDenoについての愛を綴っていきます。
「エディタに組み込んじゃうくらい」とは
余談です。あんまり興味ない方は読み飛ばしちゃってください。
僕はメインエディタとしてNeovimを使っています。これはVimから派生した比較的新しいVimなのですが、今では本家と結構違った仕様をしてたりします。
なのでVim/Neovim両対応プラグインを書くというのは結構厳しいのですが、denops.vimというプラグインエコシステムを用いてプラグインを書くと、なんとTypeScriptでVim/Neovim両対応なプラグインを書けます!
このエコシステムを用いたプラグインとして、
など(なんと全て同じ方が作っています)があり、僕のNeovimはこれらを用いて構築されています。なので事実上Denoでエディタ(のわりと重要な機能)が動いています。
Denoとの出会い
Denoとの出会いは(恐らく)高校2年、Node.jsでSvelteを書いたりしてちょっとフロントエンドに慣れてきた頃です。「Node.jsの後悔から生まれた」や「次世代のJavaScriptランタイム」といった謳い文句で紹介されていて、新しい物好きな僕は早速インストールしてみましたが、まぁ簡単なこと!
Node.jsをインストールする時はWindowsならインストーラー/winget(当時は無かった気がします)で、Linuxなら各々のパッケージマネージャーでインストールしていました。
Denoはなんと、全てのプラットフォームでコマンド一発インストールできます。また、self-update出来る機構が備わっているため、バージョンアップ/ダウンはdeno upgradeコマンド一発で可能です。なのでNode.jsみたいに、パッケージマネージャーでインストールしたNode.jsのバージョンが低いがために、新たにバージョン管理ツールをインストールする...みたいなことはありません。あれなかなか理不尽ですよね...
ですがプロジェクト毎のバージョン管理は出来ないため、ローカルにDenoを配置するかasdfの様なツールを使うことになると思います。
Denoの良いところ
ここからは僕がDenoの良いと思っているところ箇条書きで挙げ、それぞれ解説していきます。
パッケージマネージャーが無い
実行するプログラムの権限を絞れる
All in Oneになっている
標準ライブラリが至れり尽くせり
Node.jsとある程度互換性がある
公式が色々作っている
公式がデプロイ環境を公開している
Rustで書かれている
Web標準に準拠している
トランスパイルと実行がセット
Jupyter Notebookが使える
キャラクターがかわいい
パッケージマネージャーが無い
Denoにはパッケージマネージャーがありません。どういう事かと言うと、パッケージをESM形式かつURLでimportします。例えば
import { is } from "https://deno.land/x/[email protected]/mod.ts";
みたいな感じでimportします。
URL部分を見るとわかる通り、URLにバージョンが書かれているためURLを書き換えない限りバージョンが固定されることが保証されます。「パッケージアップデートしたら、よく分からないところで破壊的変更があってアプリが壊れちゃった...」みたいな事を防げるので気に入ってます。
また、import先のURLはアクセスするとJS/TSテキストが返ってくるものなら何でも良いため、
GitHubのPublicリポジトリのrawURL
Gistのraw URL
R2のPublic URL
などでライブラリを配信できます。もちろん公式でもパッケージレジストリがあり、deno.land/xがそれです。またnest.landというコミュニティベースのレジストリもあります。
これの良い所はパッケージを公開する場所が中央集権的でないという点です。Node.jsのパッケージレジストリは事実上npmjs.comですが、Denoではこれら全てで公開が可能なため、最悪どれかがダメになってしまっても別の場所で公開が可能です。
実行するプログラムの権限を絞れる
Node.jsで実行されるプログラムは基本実行するユーザーと同等の権限を持っています。つまり、実行するプログラムにファイルを破壊する処理があった場合は為す術もなく破壊されます。これは極論ですが、Node.jsでプログラムを実行するという事はそれらの可能性を孕んでいるという事をよく表していると思います。
Denoではデフォルトで実行する際プログラムになんの権限も与えません。もしプログラムがファイルを作成しようとした際は、逐一プロンプトが出てきてユーザーに許可するかどうか聞いてきます。
もちろんオプションで指定することも可能で、公式マニュアルに与えられる権限のリストが書かれています。身近なところだと
--allow-env
--allow-net
--allow-read
--allow-write
などがあります。また、最近のアップデートでは許可する範囲の指定も出来るようになりました。
この機能のちょっと変わった使い方として、既存のnpmパッケージをDenoで動かし、余分な権限を要求する怪しいパッケージをあぶり出すというものがあります。この活用方法はDenoのセキュリティの高さをよく表していると思います。
All in Oneになっている
ここ好き好きポイント高めです。
現代的な開発をするにあたり、
Tester
Formatter
Linter
の3つが必要だと思っているのですが、Denoはこれら全てを備えています。また、デフォルトで良い感じの設定を備えています。なので「linterはこれ入れて...formatterはこれにして...あとtestはどうしよう」みたいな事はありません。あるとすれば公式マニュアルを見るくらいです。
また、複数のツールを導入すると設定ファイルでプロジェクトルートがゴチャゴチャしてきますが、Denoの場合はdeno.jsonファイルに一本化出来るのでプロジェクトがとてもスッキリします。
標準ライブラリが至れり尽くせり
Denoは標準ライブラリがとても豊富です。これはGo言語にインスパイアされているらしいです。
Denoはライブラリの導入コストが他言語と比べて低いですが、それでも公式によって品質が保証されているライブラリがたくさん使えるのはありがたい限りです。
例えば、Markdownにメタ情報を付加できるFrontmatterをパースするためのライブラリformat_matterなんかがあったりします。つまり標準ライブラリだけで簡単なSSGがサクッと作れます。ちなみに自分もDenoでSSGを作ってたりします。Denoの良さを生かしたSSGにするべく鋭意開発中です。
公式が色々作っている
標準ライブラリでも触れましたが、Deno公式はDenoが大好きなので色々なツール・フレームワークを公開しています。Denoは書くのが楽しいので色々作っちゃうんでしょうね。わかり味マリアナ海溝...
Denoが公開しているプロジェクト(執筆時点)を紹介してみます。
Fresh
DenoとPreactで構築されたフルスタックWebフレームワークです。
Island Architectureを採用しておりクライアントへは最小限のHTMLしか送信しないため非常に高速なレンダリングが可能です。
Lume
Denoで書かれたSSGです。以下の3ファイルで動作します。Denoの設定ファイルが少ない特徴が生かされていてよき...
_config.ts
deno.json
import_map.json
プラグインを用いて構築されているため、ある程度自由に構成が可能です。逆に言うと、プラグインシステムから逸脱するようなコードは書けません。(当たり前)また、公式がNunjucks推しなのでJSXを使う場合は結構つらいです。そこが気にならなければindex.md一つでHTMLファイルを高速に生成できたりするのでとても便利です。
SaaSKit
DenoとFreshで構築されたSaaS(Herokuみたいなアレです)を構築するためのプラットフォームです。僕自身触ったことがないのであまり詳しくないのですが、ドキュメントにStripeについて言及されているためかなり本格的な作りになっているようです。自鯖が欲しいお年頃なので、もし自鯖を手に入れたらSaaSKitでデプロイできる環境を作ってみたい...
Node.jsとある程度互換性がある
Denoは以前はNode.jsとの互換性を重視しない方針でしたが、今はNode.jsパッケージを普通に動かせるレベルにまで互換性があります。例えば以下のコードは実行可能です。
"npm:npmのパッケージ名"のようにimport文を書くことでnpmパッケージから直接パッケージをimport出来ます。まれにエラーが発生することもありますが、esm.shを経由させることで割となんとかなります。
Node.jsのAPIが使いたくなったときも"node:モジュール名"と書くことでNode APIでコードを書くことができます。
次節で紹介しますが、DenoはDeno Deployを使うことでEdgeで実行できるため、これらの豊富なnpmパッケージをEdgeで動かせます。なんかもう凄すぎますね。
公式がデプロイ環境を公開している
Denoは公式でDeno Deployというデプロイ環境を公開しています。無料です。GCP上に構築されているらしいです。
Deno Deployの良さは
GitHub Appsによるシームレスなデプロイ
Edgeに展開されるため高速
CLIによるデプロイにも対応
ブラウザからスクリプトを書いて即デプロイ出来る
などスピードが速く簡単であることだと思います。Deno Deploy大好き。また、Denoの組み込みKVであるDeno KVも使えるため、Freshと組み合わせればデータを保存するアプリケーションがDenoとDeno Deployで完結します。
Rustで書かれている
言語そのものに直接影響するわけではないですが、個人的にはかなりポイント高いです。Rustは堅牢な言語なのでDenoにもそれなりの安定性を期待できますし、なによりRustプログラムをWasmにコンパイルしてDenoで実行することで親子丼スタックを実現できます。
Web標準に準拠している
Web標準。甘美な響ですね。なによりブラウザとサーバーサイドで同一のコードを使い回せるというのがとても良いです。僕は暇なときにDenoのRuntime APIを眺めているのですが、Web Storage APIなんかもあったりして興味深いです。
Denoでも使えるWeb APIとしては、
Fetch API
DOM API
Encoding API
などがあります。
トランスパイルと実行がセット
Denoではトランスパイルと実行が同時に行われます。どういう事かというと、
deno run main.ts
のように普通にTypeScriptコードが実行できます。内部ではSWCによるトランスパイルが走っています。(なので若干のオーバーヘッドがある)
また、DenoではJSX/TSXもそのまま実行可能なため、
deno run main.tsx
のような事も可能です。パッと見奇妙なので気に入ってます。
「トランスパイルとセット」ということはトランスパイルだけも出来るの?と思われた方もいるかも知れません。一応出来ます。ですが、非推奨です。
以前はdeno bundleというコマンドがありましたが、ブラウザ向けのバンドルやDeno向けのバンドルなどに対応させるのが困難であると判断されたため、近いうちに削除予定です。(と言いつつ今も利用可能です)
Jupyter Notebookが使える
なんとDenoではJupyter Nodebookが使えます!最近のアプデで導入されました。
DenoではTypeScriptがそのまま実行できるため、Jupyter NodebookでもTypeScriptをそのまま実行できます。またDenoはWeb GPU APIの対応を徐々に進めていて、もしサポートされた暁にはDenoで高度な機械学習が使えるようになります。機械学習でよく用いられているPythonは動的型付けで型関連のバグを起こしがちですが、TypeScriptで記述することで静的に型付けされたコードでAIを構築できるようになります。もしそのような未来が来たら面白いと思いませんか?
キャラクターがかわいい
かわいい事で定評があるGoのマスコットキャラクターGopherくんと並ぶほどのかわいさがあります。愛されていますね。
また、公式ではコミュニティが作ったDenoロゴのアートを紹介しているページがあります。Deno公式のこういう所好き。
最後に
ここまでDenoの良いと思っているところを書いてきました。DenoはNode.jsの反省点を踏まえて書かれているだけあって開発体験がとても良いです。この記事を読んでDenoに興味を持った方、ぜひお手元のマシンにDenoをインストールしてみてください。そこでは楽しいJavaScript/TypeScriptの世界があなたを待っています!
最後に、僕のDenoへの愛を叫ばせてください。
Deno~~~~~!!!未だになんて呼べばいいかよく分からないけど好きだ~~~~!!!
Ryan Dahlさん!!Denoを作ってくれてありがとう!!!どうか美味しいものとか食べてこれからも元気に開発頑張ってくださ~~~い!!
あとDeno Fest行けなくて悔し~~~~い!!!!次は絶対絶対行くからな~~~!!!待ってろよ~~~!!!!