Node.jsでDenoを動かす
が、動かせないわけでもないということを語ろうと思います
Node.jsとDenoの互換性
しかしRyanが1年半前に語ったところによればNode.jsは初期になんとなく採用した設計方針のいくつかに納得が行かず、ES2015以降モジュールシステムを獲得した最新のJavaScriptと、同じく人気が高まったTypeScriptを採用することによって、実質的にNode.jsを0から作り直す決断をしました こういった事情からしても、Node.jsとDenoは本当によく似ており、ソフトウェア開発の中における役割もほとんど同じものになっています
両者はJavaScriptランタイムとして最新のV8を採用しているので、JavaScriptとしての言語機能はほとんど同じ特徴を備えています
というよりは、V8は最新のECMAScriptに準拠しているのでブラウザのJS標準であるいくつかのAPIを除き、V8=JavaScriptと言っても過言ではないのが実情です
Node.jsとDenoはそのECMAScriptの標準の上に、独自にOSの機能をJavaScriptから使うためのAPIを実装しています
例えばOSのファイルシステムやネットワークに対するアクセスは、ECMAScriptおよびブラウザの標準には含まれていないため、通常のJavaScriptだけでは実現できない機能が多くあります
Node.jsでファイルを読み込むためには以下のようなコードになります
code:index.js
const fs = requrie("fs")
fs.readFile("./README.md", (err, file) => {
// fileを使う
});
Node.js v13から本採用されたECMA Modulesを使うとこう書くことが出来ます
code:index.mjs
import * as fs from "fs"
fs.readFile("./README.md", (err, file) => {
//
});
Denoではこう書くことになります
code:index.ts
try {
const file = awiat Deno.readFile("./README.md")
} catch (err) {
}
ここにNode.jsとDenoの大きな設計の隔たりが見えてきます
Node.js
CommonJS/ECMA Modulesという二種類の互換性のないモジュールシステムが共存
ランタイムとしてサポートするのはJavaScriptのみ
ECMAScriptを大きく拡張、ブラウザ標準と大きく離れたランタイム環境
APIはモジュールとして提供
非同期処理はコールバック
Deno
モジュールシステムはECMA Modules一種類
ランタイムとしてTypeScript/JavaScript両方をサポート
最小限の独自ランタイム拡張、ブラウザ標準に追従
APIはDenoグローバル変数に集約。それ以外の独自拡張はなし
非同期処理はasync / await
まとめると、Node.jsとDenoの間にはAPIレベルで相当な非互換性があるということです
Node.jsのコードはDenoでは動かないし、DenoのコードはNode.jsでは動かない(ブラウザのコードがそうであるように)
これがどういうことを意味するのか?
一つは、この世にまた一つ独自JavaScriptランタイムが誕生してしまったことだと言えます
Node.jsとブラウザという互換性のない二台巨塔のJavaScriptランタイムがある現状にまた一つ非互換のランタイムが生まれたことは、実は開発者にとっては好ましいことではありません
Node.jsとブラウザの互換性がない中、ブラウザのアプリ開発においてはNode.js形式(CommonJS)で記述されたプログラムをwebpackなどのバンドラーを使って強引にブラウザ形式に変換して動作させています
たった2つしかランタイムがなかったとしてもこのような面倒ごとが増えるのに、サーバーサイドにまた一つ選択肢が増えてしまったら、ただ現場には無用な混乱と分断をもたらすだけなのではないか?
そう考える人がいてもおかしくないと思います
特にサーバーサイドで後発のDenoは、10年かけて構築された過去最大規模のプログラミングコミュニティであるNode.jsを否定しその牙城を崩すことは難しいでしょう
またNode.jsで仕事をしているプログラマーもほとんど似たような新しいランタイムが出てきたところで、一部の熱狂的なアーリーアダプター以外は「へー、流行ったら教えて」くらいの乗り気であることは明らかです
そういう中でDenoがNode.jsとの共存を図る上では、両者の間に何らかの互換性をもたせるということが重要になってくると考えるのは自然です
しかし設計も実装も全く違う両者のコードにどのように互換性をもたせるのか?
Co-Polyfill
Node.jsとDenoにはJavaScript以外に互換性がないと語りましたが、お互いのコードをお互いのランタイムで動かすことは、実は不可能ではありません