🔭

UnJS にどんなツールがあるのか、上位30件すべて紹介してみた(前編)

2023/11/05に公開
2

タイトル通り、JavaScriptツール群「UnJS」にどんなライブラリが存在するのかをひたすら見てみよう! という記事です。

https://unjs.io/

本当は全て紹介しようと思ったのですが、全75個あり、1つの記事に入れるとあまりにも多すぎるので、この記事では2023年11月4日時点のStar数の順に沿って上位30個を紹介していきます。それ以降のリポジトリは別の記事で紹介していますので、気になった方はこの記事の後に読んでみてください。

https://zenn.dev/ytr0903/articles/6b50bf790c340b

UnJS とは

UnJSは、Nuxt 開発チームが中心となって開発・メンテナンスされている、あらゆるJavaScriptフレームワーク上で統一的に動作するユーティリティーツール・ライブラリ群です。

https://www.youtube.com/watch?v=8c5sNjdkEpU

UnJSというプロジェクトが何であるかについては、2022年11月に公開された講演映像「UnJS: Nuxt 3 behind the scenes by Pooya Parsa」を観て頂くのが最もわかりやすいと思います。Nuxt 3 正式リリース直後ということもあって、かなり詳細な背景が語られています。

ここでは上記映像の5分頃のスライドを引用します。

Goal: Make reusable, single purpose and perfect solutions and benefit everyone and keep Nuxt Framework maintainable as gets bigger and bigger

Nuxt 3 は、Vue 3 を基盤とした統合フレームワークですが、その機能のほとんどがモジュールとして個別に切り出されています。これによって一つ一つのツールのメンテナンス性を高め、同時にNuxt 以外のJavaScriptエコシステム全体にもその恩恵を受けられるようにすることを目標としています。

そのため、Nuxtのみ、Vueのみに限定されているわけではなく、それぞれのツール単体であらゆるJavaScript/TypeScriptプロジェクトに導入することができます。

UnJS は元々 Unified JavaScript Tools の略ですが、現在の公式サイトではそれに代わって「Unleash JavaScript's Potential(JavaScriptのポテンシャルを解き放つ)」というフレーズが掲げられています。これもまた端的に UnJS プロジェクトの価値を表現していると言えるでしょう。

https://speakerdeck.com/nozomuikuta/deep-dive-to-unjs-and-nuxt-3

先日の Vue Fes Japan 2023 でも UnJS についての発表がありました。UnJSの歴史やNuxt 3との関係などについて、より詳しく知りたい方はぜひご確認ください。

UnJS ツールを使うと何が良いのか?

個人的に UnJS として提供されているツールを積極的に使うことをお勧めしたい理由は、以下の4点です。

  • ブラウザ・サーバーなどあらゆる環境の実行を保証している
  • 確実かつ強力なTypeScriptサポート
  • Nuxtチームによってメンテナンスされている安心感
  • Nuxt 3 自体に含まれているため、インストール時間やビルドサイズの削減に繋がる

ちょっとした機能を埋めたい時に、数年メンテされていなかったりTypeScript対応していないライブラリしか見つからず、やむを得ず車輪の再発明に手を出してしまうことがありますが、UnJS に該当する機能が見つかればその選択を避けることができるでしょう。

特に、Deno・Bunの登場やWorkersの進化などによってJavaScriptの実行環境が多様化してきた今、UnJS の輝くシーンはますます増えてくるかもしれません。

基本的には Nuxt 3 のために整備されているツール群なので、ライブラリ製作者向けのツールが多いですが、普段の開発に使えそうなものも結構あるので、ざっと目を通すだけでも発見があるかと思います。

前書き

この記事は UnJS に存在する全ライブラリを紹介する記事であって、解説する記事ではありません。使い方についてはわかる範囲でしか記載しておらず、情報が古くなっている・間違っている可能性もあるので、興味を持ったツールについてぜひ実際のリポジトリを確認してみてください。

何となく「こういうツールがある」という存在だけを知っておくことで、いざという時に「そういえばアレが今使えるかも……?」と思い出す取っ掛かりになる、というのがこの記事の目標です。

もし記載に明確な間違いがありましたらぜひコメントなどでお知らせ頂けると助かります!

なお、番号は単に記事を読みやすくするために振っているだけで、UnJS公式がライブラリをナンバリングしているわけではないこともご留意ください。

0. unkit —― 使いやすい UnJS ライブラリの詰め合わせ

と、パッケージ紹介に入る前に、最後まで読むのが面倒な方のためにも最初に紹介しておきたいリポジトリを1つ載せておきます。

https://github.com/unjs/unkit

UnJSに含まれているライブラリのうち、単体で出番の多そうなツールがまとめられている詰め合わせ。

それぞれの名前を覚えなくても、サブパスによって全て unkit から呼び出せます。具体的にどのライブラリが含まれているかについては、トップページの表を引用します。

Subpath Packages
unkit/env unjs/std-env
unkit/esm unjs/mlly
unkit/fetch unjs/ohmyfetch
unkit/http unjs/h3, unjs/is-https
unkit/object unjs/defu, unjs/destr
unkit/promise unjs/items-promise
unkit/string unjs/scule
unkit/url unjs/ufo

UnJS のライブラリ多すぎて結局何を使えば良いのかわからないという方は、とりあえずこの unkit を入れてみましょう。

01~10

01. 🐨consola - console.logを美しく装飾

https://github.com/unjs/consola

console.log を装飾付きで表示できるラッパーライブラリ。

Nuxt や Nuxt CLI を利用していてコンソールに [WARN][ERROR] などが色付きで表示されることがありますが、それは consola を通して出力されているようです。

ブラウザでも使えました。ちゃんとエラーは console.error になっています。

02. Nitro - 全環境対応のWebサーバーを構築

https://github.com/unjs/nitro

Nuxt 3 のサーバーエンジンとなっているライブラリ。

各種デプロイ環境プリセット、デプロイ用に最適化されたアウトプット・コード分割、自動コード分割やホットリロードなどなど、そもそもこの nitro 自体が UnJS の各種ツールに依存している部分も多々あって、何が Nitro の機能かと説明するのも難しそうです。

理論上はNitroを使ってVue以外をベースとしたNuxt的な統合フレームワークを作れるようにデザインされているのだと思われます。

03. 😱ofetch - 全ての環境で動く fetch API ラッパー

https://github.com/unjs/ofetch

ブラウザ、node、worker で動く fetch ライブラリのラッパー。

ofetch を使うと、ブラウザ環境ではネイティブな fetch API がそのまま使われ、node 環境であれば自動で互換ライブラリを呼び出すので、環境を意識せずに使えます。

node.js のネイティブfetchサポートが普及するにつれてその重要度は下がりそうですが、ネイティブな fetch と比較して、TypeScriptで型引数を渡すだけでレスポンスの型を指定できる、第2引数のオプションでqueryをオブジェクトのまま渡せる、InterceptorsやParserのサポートなど、魅力的な点は多いです。

Nuxt 3では $fetch で簡単に呼び出せるヘルパーが提供されているほか、useFetch を使う際にも自動的にこの ofetch を経由します。Nuxtはグローバルな fetch を勝手にオーバーライドしたりしません。

04. unplugin - Vite, Webpack, esbuildなど全てで使えるプラグインを作れる

https://github.com/unjs/unplugin

様々なビルドツールに対応したプラグインを単一のAPIで作れるモジュール。

unplugin という名前は Nuxt ユーザーでなくとも、特に Vite を利用している場合に目にしたことがあるかもしれません。自動インポートを実現する unplugin-auto-import や、Nuxt 3 アップデートを完遂させるまでの期間に大変お世話になった unplugin-vue2-script-setup などがこれを通して提供されています。

凄すぎて正直自分自身で使うシチュエーションは見えていないのですが、ライブラリ製作者でなくてもビルド時のフックでちょっとした処理を記述したい時に使えるかもしれません。

現在はVite、Rollup、Webpack、esbuild、Rspack に対応。Viteチームが新たに開発中のRollup互換ツール Rolldown にも遠からず対応されることでしょう(※あくまで予想です)。

05. ⚡️h3 - ミニマムなHTTPフレームワークを実現

https://github.com/unjs/h3

こちらもNuxtおよびnitroの基本機能に含まれているので説明が難しいですが、Express や Koa などと同じHTTPサーバー構築のためのフレームワークです。

Nuxt 3 では server/ ディレクトリにファイルを配置することで API や server middleware を記述することができますが、ここに h3 が使われています。Nuxtのサーバー処理開発で何か困ったことがあったら、h3のドキュメントを見たり、h3リポジトリのissuesを調べたりすることで回答が見つかる場合が結構あります。

06. webpackbar - webpack のビルド進行状況を可視化

https://github.com/unjs/webpackbar

webpack のコンパイル中の進行状況を可視化してくれるライブラリ。複数同時に表示できるのでサーバーとクライアントの同時ビルドにも対応しています。

名前の通り webpack 用なので、Nuxt 3 でデフォルトの Vite を利用している場合は見る機会がなさそうです。

07. 🧀magicast - JS/TSファイルの読み書き

https://github.com/unjs/magicast

loadFilewriteFile などの関数を使って、JS/TSでexportされているモジュールを読み込んだり、編集してファイルを修正することができます。

08. 📦unbuild - rollupベースのJSビルドシステム

https://github.com/unjs/unbuild

Nuxt 3、というかViteではビルドにrollup、開発サーバーにesbuildが使われていますが、このビルド部分のラッパーライブラリ。このライブラリ自体が様々なUnJSツールに依存しているので、それらをまとめる役割を持っているように見えます。

09. 💾Unstorage - どんな環境でも動く key-value ストレージAPI

https://unstorage.unjs.io/

key-value形式かつ型定義・async/await対応のAPIを通して、様々なデータベースに統一的にアクセスできるようになるラッパーライブラリ。

Storageという名前からてっきりLocal Storage、IndexedDBなどのローカルDBのみが対象になると思っていたのですが、Node.js のローカルファイルにデータ保存できたり、Cloudflare Workers向けのCloudFlare KV、Capacitor(スマホアプリ)向けのCapacitor PreferencesPlanetScaleなど、様々なデータベース環境をサポートしています。

おそらく最初からUnstorageでなければならないシチュエーションがあるというよりは、統一されたAPIを通した操作に限定されることで、Unstorageを使っておけば後々Edge WorkersやCapacitorやSSRへの移植が楽になるというイメージだと思います。

10. jiti - TypeScriptをそのまま実行できるランタイム環境

https://github.com/unjs/jiti/

コマンドラインなどでTypeScriptファイルをそのまま実行できるライブラリ。 ts-node を使ったことがある方はイメージしやすいと思います。

私自身は最近ちょっとした手元のファイルの一括置換処理とかもTSで書いてしまうのですが、上述した magicast なども含めて npx jiti [ファイル名] でサクッと処理できるので割と愛用しています。

もっとも、BunはTypeScriptをそのまま実行できる ため、使うのは Node で開発している場合が主になりそうです。

11~20

11. 🖼️ipx - 画像のキャッシュ&サイズ最適化

https://github.com/unjs/ipx/

画像取得の際にミドルウェアとして噛ませることで、指定したディレクトリにキャッシュしておく処理と、その際にsharp をベースとした画像の最適化・フォーマットなどによってそもそもの画像サイズを減らす処理の両方をまとめて行ってくれます。

Nuxt公式ライブラリで、バージョン3.8から <NuxtImg/ > タグを書くだけで自動インストールになった Nuxt Image に使われています。README によると Netlify の画像処理にも使われているそうなので、意識せずにお世話になっている場合も多そうです。

12. 🚀destr - モダンな JSON.parse()

https://github.com/unjs/destr

凄い JSON.parse です。JSON.parse では正しいJSONフォーマットとして解釈できない文字列を渡すとエラーになりますが、destr では単なる文字列としてそのまま返してくれたりしながらなるべくエラーを避けてくれます。また、"true"1 などの文字列を無理にJSONとして解釈しようとしないので処理自体も高速になるとのこと。

ただしその代償として、完全なJSONをパースする際は若干JSON.parseより遅くなります。ドキュメントにも destr is better when input is not always a JSON string or from untrusted source like request body. と書いてあり、常にこれを使えば良いというものでもなさそうです。

13. 🔗ufo - 人間のためのURL操作ツール

https://github.com/unjs/ufo

ウェブアプリでURL文字列を扱う時に面倒な処理を自然に操作するためのツール。

半角スペースなどの一部文字のエンコード、ホスト名やクエリなどの取得、オブジェクトになっているクエリのURL化、末尾スラッシュ有無やHTTPSの統一……などを行うための関数がまとめて提供されています。

14. 🌊defu - オブジェクトのデフォルト値とのマージを簡単に行う

https://github.com/unjs/defu

第1引数にマージしたいオブジェクト、第2引数にデフォルト値のオブジェクトを渡すことで、第1引数に定義されていないものだけがデフォルト値を使うように上手くマージしてくれます。

import { defu } from "defu";

console.log(defu({ a: { b: 2 } }, { a: { b: 1, c: 3 } }));
// => { a: { b: 2, c: 3 } }

公式ページに載っているコード例が全てなのですが、これだけだと何に使うのかよくわからなくてNuxtのコードを見てみたところ、第1引数にユーザーがNuxt Config に指定した値、第2引数にデフォルトオブジェクトを書く、という使い方がされていました。

https://github.com/nuxt/nuxt/blob/main/packages/kit/src/template.ts#L124-L135

上記コードのように、大量かつ再帰的なプロパティ定義があるオブジェクトの処理でいちいち .reduce() を書くのはかなり面倒かつ非効率的なので、そういった場合に defu を上手く使えるとコードをかなり綺麗にできそうです。

15. 🚇untun - localhostをオンラインで確認

https://github.com/unjs/untun

Cloudflare Quick Tunnels を経由することで、localhostで実行中のウェブサイトをオンラインで確認できるようになります。

実際に試せていないのでセキュリティなど若干の心配はありますが、iOSなどでの動作を確認したい場合に便利そう。

16. 💅changelogen - リリースノートを綺麗に整理

https://github.com/unjs/changelogen

Conventional Commits ルールに従ってコミットしていれば、絵文字などを使いながら綺麗なリリースノートを作ってくれます。ランタイムでもビルドでもなく主にGitHub Actions向けのツール。

https://github.com/nuxt/nuxt/blob/main/.github/workflows/changelogensets.yml

実際に Nuxt の GitHub Actions を覗いてみると、リリースノート作成のコマンドが pnpm jiti ./scripts/update-changelog.ts となっています。

17. 🪝hookable - 任意のフックで関数実行を登録できる仕組み

https://github.com/unjs/hookable

特定の名前をコールすることで、その名前に紐づけられている処理が全て呼ばれるフックインスタンスを作成できるツール。async関数をフックすれば同期的にその終了を待ってくれます。

名前通り Nuxt の Lifecycle Hooks に使われているシステムで、例えば app:createdbuild:done といった特定のタイミングで、ユーザーやサードパーティライブラリが任意のロジックを実行できる拡張性が Nuxt 3 に備わっているのはこのライブラリのおかげのようです。

18. 🌆citty - CLI コマンドの引数や説明文を定義

https://github.com/unjs/citty

TypeScript で CLI コマンドを定義する際、コマンドの引数などを簡単に扱えるようになります。 当然 process.argv などを使えばアクセスはできますが、型サポートを受けられたり引数の必須化などを定義できたりします。類似のライブラリは多数ありますが、その中の優れた選択肢の1つになるでしょう。

19. ohash - オブジェクトのハッシュ処理に加えて、オブジェクトの深い差分比較も

https://github.com/unjs/ohash

オブジェクトを一意な文字列に整形した上でハッシュ値エンコードを行う……というのがメインの使い方に見えるのですが、その副産物なのか何なのか、オブジェクト同士の再帰的なプロパティ比較関数も提供されています。

この記事を書くまで完全に見落としてたのですが、これまで2つの異なるオブジェクトの中身を比較するためにインストールしていた deep-object-diff を除いてビルドサイズを圧縮できるのではないかとワクワクしています。

20. unimport - 型サポート付きの自動インポート

https://github.com/unjs/unimport

特定のディレクトリ・ルールでの自動インポートと型サポートを実現するライブラリ。

Viteで同様の機能を提供していたhttps://github.com/unplugin/unplugin-auto-import を、Nuxtにも取り入れるにあたって、Vite以外の環境でも動作するように汎用的・低レイヤー向けライブラリとして分離されたものです。

21~30

21. unhead - SPAでもSSRでも動作する <head> 定義

https://github.com/unjs/unhead

タイトルやメタタグなどのheadプロパティをJS/TSで定義するツール。Nuxt 3では useHead() を使って呼び出せます。

22. mlly - ESM のギャップを埋めるためのライブラリパス解決

https://github.com/unjs/mlly

パッケージ名を渡すと相対パスを返す関数を提供しています。自分なりに調べた限り、おそらく、Native ESM に対応していない、本当はパッケージ名ではなくファイルを指定しなければならない環境であっても、一貫してESM Module的な記法でライブラリをインポートするためのポリフィル……だと解釈したのですが、間違っていたらすみません。

少なくとも Nuxt 3 を使っているユーザー自身が意識する必要はほぼなさそうです。

23. 🌈nypm - npmyarnbunpnpm も同じコマンドでインストール

https://github.com/unjs/nypm

nypm inypm remove といったコマンドで、その環境に package-lock.json があれば npm を、 yarn.lock があれば yarn を使う……というように勝手に切り替えてくれます。

便利ではありますが個人的にはantfu氏が開発していてさらに文字数の短い ni の方が好きです。結局 run dev とかは nypm ではサポートしていないのもネック。それらはどのコマンドを使っても動けば関係ないのですが……。

24. 🐙UNGH - GitHub API への自由度の高いアクセス

https://github.com/unjs/ungh

GitHub上のリポジトリ・ユーザーに関する公開情報をトークンなしで取得できるライブラリ。

ライブラリというか https://ungh.cc/repos/nuxt/nuxt というように ungh.cc 以下のURLにアクセスして取得する方法しか紹介されていないので、サービスといった方が正しいかもしれません。

パブリックなリポジトリに限られるので業務で使うのはなかなか難しそうですが、個人ホームページに自身のGitHub情報を載せたい時なんかに便利に使えるかもしれません。

25. 🍦unctx - Vanilla JS で Composition API 的なロジックの再利用を

https://github.com/unjs/unctx

「Composition-API in Vanilla js」という説明文で意味を掴むのが難しいのですが、そもそもVue Composition API は React Hooks などと違ってそれ自体が特定のライフサイクルに限定されているわけではない(onMounted など一部のフックがsetupのタイミングでしか呼べないだけ)ので、その仕組みを他のライブラリでも使えるように定義した、というものに見えます。

In your awesome library: というコンテキストからして、Vue以外のライブラリフレームワークを作っている人向けなのでしょうか……? それとも ReactSvelte で使えたりする……?

ちょっと読んだだけではわからないので、詳しい方がいたらぜひコメント頂けるとありがたいです。

26. untyped - スキーマ定義から型定義とマークダウンを生成

https://github.com/unjs/untyped

untyped が指定するスキーマに沿って定義したオブジェクトを渡すと、型定義ファイルとマークダウンを生成してくれます。Nuxt 3 でコンフィグやコンポーサブルを更新するたびに型定義ファイルが動的に更新されていくのはおそらくこのライブラリの力でしょう。

関数の実体から型定義を生成することができるので、Vue に限らず自分でライブラリを作る場合に便利な場合が多そうです。

27. std-env - 実行環境に依存しない環境変数・情報の取得

https://github.com/unjs/std-env

isDevelopment, isMacOS, isCI, isBun など、そのJSコードが実行されている環境に関する情報を安定して取得することができるツール。わかりやすいようにフラグを紹介しましたが、providerInforuntimeInfo で名前などを取得することもできます。

さらに processenv の proxy も提供されています。 process.env にアクセスできるかどうかによって、プロダクションだけエラーになってしまうことがたまにありますが、そういった事故を回避できます。こういったライブラリを必要とするのが、まさにあらゆる環境での実行を想定されたNuxt 3 ならではと思えます。

28. ⚙️c12 - 設定(config)ファイルを賢くロード

https://github.com/unjs/c12

.config.ts.env などの設定ファイルのロードと、変更を検知しての自動再起動などを行うライブラリ。 $development プロパティを使った環境ごとのオーバーライドや、extends での設定テーマ引継ぎなど、Nuxt Config 独自の機能に見えるものが思ったより c12 で汎用定義されていることに驚きました。

29. ✨giget - Gitリポジトリのテンプレートをスマートに展開

https://github.com/unjs/giget

GitHub などのプロバイダに登録されているリポジトリやテンプレートをダウンロードするツール。

Nuxt 3 では nuxi init コマンドがこの giget を通じて実装されているようです。offlineforce-clean などのフラグも提供されていますが、基本的にはユーザーが使うというよりは、フレームワーク提供側がこれをカスタムして使う用途が想定されているように思います。

30. 🌳radix3 - 軽量高速な文字列解析によるルーティングシステム

https://github.com/unjs/radix3

あらかじめ登録されているファイルパスのパターンに対して、与えられた文字列がどのパターンに当てはまるかを高速に探索するシステム。ワイルドカードにも対応。上記のREADMEに例が載っているのでそれを見るのが一番速いです。

Nuxt のルーティングそのものは Vue Router によって実現されているはずなので、どこで使われてるのだろう? と思って調べたところ、ページごとにレンダリングルールを指定できる routeRules プロパティに使われていました。

https://nuxt.com/docs/guide/concepts/rendering#hybrid-rendering

おわりに

かなり駆け足ではありますが30件を紹介してみました。

個人的には jiti は既に使っていますが、defuufoohash あたりは普段の開発で使う機会がありそうです。untyped, Unstorage, changelogen あたりも使ってみたいところ。

上位30件だけ知っておけば十分……と言いたいところなのですが、個人的に一番紹介したかった scule がまだ出てきていなかったり、unpdfuqr という気になる名前があったりと、

UnJS には便利なライブラリがまだまだあるので、なるべく早めに続きを書きたいと思います。

この記事によって UnJS に興味を持った方が一人でも増えたら嬉しいです!

続き

https://zenn.dev/ytr0903/articles/6b50bf790c340b

Discussion