🦕

Deno と JSR がもたらす OSS の民主化という妄想

2024/10/07に公開

はじめに

Deno 2.0 のリリースが目前に迫っているこのタイミングで、「Deno と JSR が OSS の民主化をもたらす」という期待を込めた妄想を書きます。

Deno が TypeScript をネイティブにサポートするということ

Deno の公式サイトを見ると、トップページの目立つところにどデカく

Native TypeScript support
The Deno runtime natively supports TypeScript ...以下略

と書いてある (2024年10月現在)。

個人的にはこれが Deno の一番の売りであり、現代のウェブプログラマーにとっても極めて重要なポイントだと思っているが、なんかあんまりこの嬉しさがすべて期待通りに伝わっていない感じもある。

Deno を使うと、npm install -D typescript は不要だし、tsconfig.json を用意しなくてもすぐに TypeScript でプログラムを書き始めることができる。つくったプログラムを実行するときも tsc して dist の中身を実行、などとする必要もない。

これは実際とても嬉しい。まず何かプログラムを書き始めたい、というモチベが高まっているときのオーバーヘッドやリードタイムの少なさというのはいつでも素晴らしいものであるし、実行の手数が減るのももちろん大歓迎である。

一方で、つまりこれが "Native TypeScript support" ということなんだな、とだけ捉えてしまうと、なんか微妙に本質から外れてしまっていってしまうという感覚がある。

要は、「Node.js でも ts-nodetsx を使えば TypeScript のコードを実行できるし、Vite (esbuild) とかを使えばトランスパイルを意識することもそんなになくない?」と感じてしまい、Deno が TypeScript をネイティブにサポートする、ということに対して、別にそれが何か?という気がしてきてしまうという。さっき公式サイトのトップページを引用したが、そこには同時に "Deno is the open-source JavaScript runtime" とも書いてあるし。

まあ自分も最初の印象はそれと似たようなのものだったのだが、割と長いこと Deno を使っていると印象がかなり変わってくるのでそれを伝えたい。

パッケージのソースコードが TypeScript である

結論ここで言いたいことはこれだけだったりする。Deno のパッケージは TypeScript で書かれていて、TypeScript で公開されている

つまりどういうことかというと、Deno のパッケージをインストールすると、そのパッケージのソースコードは TypeScript で書かれているということだ。

いや、つまりもなにもそのままで言い換えにも何にもなっていなかった。なので具体的に言うなら、IDE でパッケージが提供する API の定義にジャンプすると、そのまま TypeScript の実装に飛ぶ、ということ。これも当たり前の話のようだが、Node.js で開発していた人なら当然この嬉しさはわかるはず。

そう、型定義に飛べるのではなく、その API の本物の実装コードに飛んでその内容が見られるのである。

もちろん、例えば VS Code なら "TypeScript: Go to Source Definition" といったコマンドがあり、それを叩くと JavaScript のシンボルにジャンプできる…ようになっている…一応。しかし、実際にやってみるとわかるが、それが期待通りの結果になってくれることは、残念ながらほとんどない。

この辺は、特にバックエンドの案件で Node.js を採用したときにエンジニアから恨み言を言われることが多いポイントでもある。自分なんかは割と慣れちゃってるというか、JavaScript の時代を経て TypeScript に移行したきた経過をそのまま体験しているので、これはこういうもの。前よりとても良くなっているから文句言わないの。とか思ってしまうのだが、ふと正気に戻ったときに、「いや、ネイティブコードにコンパイルされるプログラミング言語だって今時当たり前にコードレベルでサクッと定義ジャンプやデバッグができるのに、なんで今俺はできないんだよ?」というモードになってしまう。

まあそれは置いておいても、この TypeScript 開発で特有の体験には、ライブラリなど、自分で書いたコードとそれ以外のコードとの距離感というものを強く感じてしまっていた。

コードの距離感という課題

コードの距離感というのは自分でもあまり口にしたことがない表現だが、実際に言語化するとそれが一番しっくりくる。で、自分はこのコードの距離感というのは割と深刻な課題だと思っている。

プロダクトコードとライブラリの違いなどない。自分のプロダクトコードで使っているコードはすべてプロダクトコードだろうが。

というのは、かつてある Rubyist から聞いた言葉なのだが、「確かにそうだな」と思って印象に残っていて、自分のコードに対する意識の土台の一つになっているものだ。そして、自分はこれをまさにコードの距離感の話だと理解している。

誰か他の人の作ったコードを自分のものと分け隔てなく同じコードだよね、と認識するには、それをすぐに触れる、弄れるという状態であることがとても大事だと思っている。もちろん、知識と経験があればどんなものでも弄ることはできるのだが、それが求められることはシンプルにハードルとなる。

インタプリタ言語であれば、ライブラリのコードであっても、単純にそれをテキストエディタで開いて書き変えて保存すれば、自分が書き換えたように動いてくれる。この距離感の近さこそがインタプリタ言語 = スクリプト言語の魅力ではなかったか。そして JavaScript も本来はそうではなかったか。JavaScript をもっと便利に扱おうとしていたら、いつの間にか複雑になり過ぎていて、他の人の書いたコードは、例えそれを毎日使っていたとしても、どこか遠い存在になってしまっていた。

結局、危惧してしまうのは OSS という文化の存続についてだ。OSS のコードを弄ってみる機会が減るということは、そのまま OSS コミュニティの衰退につながるのではないかという怖さがある。はい。「TypeScript が与えるコードの距離感というのは深刻な課題だ」とか言ってそれが一体何にとっての課題なのかここまで明確にしていなかったが、それは「OSS にとっての課題だ」と考える。非常にヤバイ。これは別に唐突に自由ソフトウェアの代弁者面をしてデカイ主語で大層なことを言いたいのではなく、仕事もプライベートも OSS とともに歩んできた一人の人間として、他の生き方も知らないしどうしよう、という切実なアレだ。まあすべてを AI が持っていく未来になるかもしれないが。

思いつくままに書いているが、OSS は GitHub によって民主化が一気に進んだということに異を唱える人はいないだろう。それまでソフトウェアにパッチを送るというのは、プログラマーというレアな存在、その中でもさらに限られたごく少数の人だけの特権 (?) だった。自分も含めて GitHub の登場が衝撃だった人は多いと思うが、当時のウェブプログラミング界は lightweight language と呼ばれたスクリプト言語の全盛期で、実際に GitHub 上でホストされていたコードも、そのほとんどが Ruby や Python、PHP そして JavaScript で書かれたものだった。GitHub が生まれ成功したことは、こういったプログラミング言語の特性に強く関係している、いや、親しみやすいスクリプト言語が流行っていたからこそ、GitHub のような OSS コミュニティの誕生は必然だったとまで思う。

TypeScript と雑にまとめると微妙だが、少なくともモダン JavaScript の世界では、ツールチェインの多様化・複雑化もあって、GitHub のリポジトリを見に行ってもまず読み始めるまでに理解しないといけないことが多くて諦めてしまうこともある。これ自体は具体的な問題として多くの人が共有しているところであって、例えば、Rome は残念ながら成らずだったようだが、志は Biome や Vite などにも引き継がれている。

Deno もこれらの DX に関する問題意識についてはかなり初期の段階から発信していた。もちろん彼らも商売であるから「Deno を使えばこんなに良いことがありますよ」という売り出し方としてそれを打ち出していたということだろうが、何にせよ私の感じていたこととは完全にリンクしており最高に共感できるものであり、第一印象からこれは最高に愛せるやつだという直感があった。そして、Deno のブログや YouTube チャンネルをずっと見ていると、機能面でも提案している内容面でも一貫してプログラマーにフレンドリーな環境を提供するという方向性がブレておらず、この直感はやはり間違っていなかったことがわかる。

そして、Deno Deploy, Deno KV を経て、私にとっては Deno がもたらす DX の最大のピースを埋めるものと感じている JSR がリリースされることとなる。

JSR で完成する TypeScript の DX

今年 (2024年) 3月、JSR のパブリックベータが公開された。

これに関しては、そのリリースのときのポストに大体言いたいことは書いてある。特に今書いているこの投稿の内容に関連する箇所としては以下になるだろう。

Modules are published to JSR as TypeScript source code. API documentation generation, type declarations for Node-like environments, and transpilation are all handled by JSR. Module authors can focus on writing TypeScript only.

It should be designed for TypeScript from first principles
It should be simple, fast, and provide an excellent developer experience

https://deno.com/blog/jsr_open_beta

このリリースが出た日に同僚の mottox2 から会社の Slack に「若杉さんしか興味なさそうですが」というありがたい前置き付きで「JSR というのが出ましたね。ライブラリー製作者には嬉しい機能が多そう」と投稿があって、そのときに「Deno からこれが出てきたのには納得感しかない」みたいな返答をしたのを覚えている。

何度も言及してきたように、Deno は TypeScript 中心のエコシステムの DX を追求するムーブを繰り返してきたと考えている。その DX には当然、誰でもパッケージを公開しやすくするというものも含まれていた。実際のところ Deno のことだけを考えたら、ウェブサービスとしての JSR の機能自体はごく初期段階から denoland/x によってほぼほぼ提供されていたので、これはその思想をさらに広げていくためのものだと思っている。

上記で参照したリリースのポストがでたときの HN や Reddit のコメントを読んでいたが、賛否あるしどっちかというと否が目立つという感じであった。それらの否定的な意見にも共感はできる。目立った批判的なコメントは以下のようなものだった。

  • また新しいパッケージレジストリを世の中に増やすのではなく、既存のものを改善すべき
    • つまり NPM を良くしていく方向に協力すべきだ
  • NPM が Microsoft によるクローズドソースで運用されているのが問題であれば、NPM に依存するスーパーセットを作っても意味がないのでは
    • Deno が運営するならベンダーロックインされる対象がシフトするだけで、根本的な問題解決にはならないのでは
    • というか、そもそもスーパーセットである、というのが看板に偽りがあるのでは
  • パッケージビルド (コンパイル/トランスパイル) の責務をパッケージレジストラが持つべきではないのでは
  • サプライチェーンアタック等に対するセキュリティが十分ではないのではないか

しかし、上記のような批判的な言説の大部分には、Deno の開発者が直接コメントを寄せていて、そしてその大半は、まあそこそこは納得感のあるものであった。例えば「MS / GitHub にとって NPM はコストセンター扱いになっており、改善に期待できないので仕方なかった」とか。

全部は書けないので、興味のある人はググって読んでみて欲しいのだが、当時 Deno の DevRel だった方の HN のポストだけは引用しておきたい。

For module authors, we're hoping JSR will be helpful in the following ways:

1.) You can develop and publish TypeScript source, and let JSR handle transpilation and generating .d.ts files for runtimes that don't natively support TypeScript. Especially nice if you are using Deno or Bun (that do natively support TypeScript), and don't have tsc in your workflow otherwise.
2.) JSR generates API docs for you on your package page based on your source code and comments.
3.) JSR has a great DX around publishing packages from GitHub Actions using OIDC (no juggling tokens)
4.) JSR automatically provides provenance for published versions of packages

For module consumers, it helps too:

1.) Compatible with both Deno and existing npm-based projects
2.) Package info and docs provided centralized on the jsr.io site
3.) Quality scores that encourage authors to make their packages fast and well documented
4.) Access to TypeScript source for packages (not just transpiled output)

モジュールの製作者にとって、そして利用者にとってのメリットがとてもよくまとまっていると思う。

「モジュールの製作者」の気分を味わうために、実際に試しに Deno でモジュールを開発して JSR に公開してみたが、これらの言葉に偽りない良い体験であった。

しかし何より、

  • JSR にパッケージを公開する、その行為自体が結構楽しいな

と感じたのだ。これがこの投稿のテーマとしてはとても大きい。上記で引用したコメントにあるものとも重複するが、簡単ないくつかのコマンドを実行することで以下が実現される。

  • より良いドキュメンテーションのための指摘がされる
  • パッケージのスコアが表示される (簡単に100点達成できてしまうが)
  • ウェブ上のキレイな UI でそれらの自分の書いたドキュメントやコードが公開される
  • OIDC で認証・認可する GitHub Actions が構成され、"bump up version" したコミットを push すればすぐに新バージョンが自動でリリースされる

自分の作ったものが公開されているのを見るのはいつだって楽しいものだ。また、象徴的な mod.ts というファイルにも現れているように、Deno がその実装にも使っている Rust コミュニティからの影響が完全にいい方向に機能しているようで、ツールチェインの利用で迷うポイントがほぼないというのも大きい。楽しくて、無駄に悩むことがない。そういうものなら誰だって使いたくなる。たぶん。

このように、Deno が提案する DX は JSR によって完成すると考えていて、そして、それは現在の TypeScript 開発にまつわる DX の課題を解決するものでもあり、そしてそれが誰でも参加できる民主化した OSS というものにつながる道なんじゃないかと妄想している、みなさん Deno おすすめですよ。という話でした。唐突に終わります。

Discussion