🪄

UnJS にどんなツールがあるのかすべて紹介してみた(後編)

2023/11/19に公開

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

UnJSとは何かという話と、Star数の上位30件の紹介は前の記事で書いていますので、まだ見ていない方は先にそちらからお読みください。

https://zenn.dev/ytr0903/articles/c6c42147ed29be

前回の記事では全75件あると書いたのですが、リポジトリ一覧をよく見ると UnJS 公式サイトUnJSのリポジトリを新規作成する際のテンプレート なども含まれていました。

そのため、UnJS 公式サイトのパッケージ一覧に掲載されているものを中心に絞って紹介します。

https://unjs.io/

前書き

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

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

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

なお、番号は単に記事を読みやすくするために振っているだけで、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 を入れてみましょう。

31~40

31. 🛣️pathe ── あらゆる環境で統一的に使えるファイルパスモジュール

https://github.com/unjs/pathe

resolve('../') のようなパス解決を行うモジュール。 node:path と同じようなことができますが、パスの区切りに使われる文字が、Windowsではスラッシュではなくバックスラッシュで書かれることがあり、どちらの書き方でも認識できるようになります。

第2引数でエイリアスを渡せる resolveAlias 関数なども提供されています。

ちなみに11/12時点で radix3 の Star数を抜いているので既に30位です。

32. 👂listhen ── HTTPリスナーを提供するパッケージ

https://github.com/unjs/listhen

npx listhen -w ./index.ts のようなコマンドによって、localhost:3000 などのポートから特定のファイルを実行させることができます。jiti によってTSファイルも直接実行できたり、空いているポート番号を自動で探したり、他の UnJS ライブラリによって提供されている機能もデフォルトで組み込まれています。

Nuxt 3 では主に開発サーバーの実行時に呼び出されており、nuxi dev コマンドのページにも listhen のオプションが全て使えることが記載されています。

33. mkdist ── Vueファイルに対応したミニマムなバンドラーツール

https://github.com/unjs/mkdist

mkdist は型定義ファイル生成機能を備えたミニマムなファイルバンドラです。

babeltsc といった既存のバンドラツールが、レガシーブラウザ互換を意識したトランスパイルを重点的にサポートしているのに対して、 mkdist はできる限り元のファイル構造や記法を維持したままファイルをコピーするため、 file-to-file transformer というフレーズが使われているようです。

また、当然ながら .vue ファイルを完全にサポートしているのも特徴です。

実際に Nuxt 3 でビルドされているサイトを開いて開発者ツールのネットワークタブを見てみると、 hogehoge.vue.xxxx.js という名前のファイルが読み込まれます。

これが「ファイル構造を維持したバンドラ」によるもので、実際にそのコンポーネントが使われるタイミングまでコードを呼び出さないためパフォーマンス上もメリットがあります。あと普通にデバッグしやすいです。

https://antfu.me/posts/publish-esm-and-cjs

mkdist については上記の Anthony Fu さんの記事も参考になるので、興味のある方はぜひ読んでみてください。

34. uqr —― QRコードを生成してSVG化もターミナル表示も

https://github.com/unjs/uqr

URLを渡すとQRコードを生成するライブラリ。 renderSVG() はイメージしやすいですが、 renderANSI()renderUnicode() でターミナルに表示するための文字列を生成できるというのが面白いポイント。

開発者ツールを開くとコンソールに採用情報が表示される遊び心あるサイトをたまに目にしますが、そんな用途でも使えるかもしれません。

35. 🕊️unenv ── 特定の実行環境に依存しないコードに変換

https://github.com/unjs/unenv

rollup や webpack などのビルドパイプラインの中に組み込むことで、特定の環境に依存しているコードを依存しないコードに変換してくれます。

node を指定すれば fetch() 関数を置き換えたり、 nodeless を指定すれば node.js に依存しているコードをモックやポリフィルに置き換えたりします。

36. 🧵scule —― 文字列をキャメルケースやパスカルケースに変換

https://github.com/unjs/scule

PascalCase、kebab-case、camelCase、snake_case など、文字列を様々な形式に変換してくれます。

わざわざライブラリを新たに入れるのも少し億劫になるくらいの処理なので、Nuxt を使っている場合に依存を増やすことなく手軽に使えるのが嬉しいです。

📄37. unpdf —― PDF.js を Node・ブラウザ以外の環境でも

https://github.com/unjs/unpdf

PDFを扱うためのライブラリ。Mozillaの提供している pdf.js をベースに、node.js に依存している箇所を置き換えることで Deno や Workers など他の環境でも動作するように再ビルドしたものとなっているようです。

PDF.js はブラウザ上で使う場合はプリビルドされた pdfjs-dist を使うことが推奨されていますが、unpdf はブラウザもサポート対象に含んでいるので、どちらであっても unpdf を使うことができるようです。

38. knitwork —― JavaScriptコードを動的に生成

https://github.com/unjs/knitwork

genImport genExport genInterface genTypeImport などの関数を通して、JavaScriptコードそのものの文字列を生成するツール。

READMEの usege を見れば何をするものか大体わかると思います。

import { genImport, genExport } from 'knitwork'

// import foo from "pkg"
console.log(genImport('pkg', 'foo'))

基本的にはまさに Nuxt のようなフレームワーク向けのツールですが、正規表現などと組み合わせて、意外とNuxt 2から3への移行時の処理を簡潔に書けたりするかもしれません。

39. rc9 —― 設定ファイルをオブジェクト的に読み書き

https://github.com/unjs/rc9

db.username=db username のような書き方になっている設定ファイルを、オブジェクトのように読み込んだり書き込んだりできます。

主に .config ファイルや .env ファイルで使えるでしょうか。

40. 🔌get-port-please —― 空いているポートを自動で探す

https://github.com/unjs/get-port-please

指定したポートが空いていない場合にランダムにポートを探しに行く機能。

指定したポートが空いていない場合に、2番目以降に探すポートを配列で指定する ports オプションもあり、nuxi dev では ports: Array.from({ length: 20 }, (_, i) => hmrPortDefault + 1 + i) という指定によって、ある程度までは規則性を持ったポートにフォールバックされるように調整されています。

get-port-please については、potato4d さんが Next.js でこのライブラリを使った記事を以前書いていますので、使用例が気になる方はこちらも読んでみてください。

https://d.potato4d.me/entry/20221114-get-port-please/

41~50

41. pkg-types —― tsconfig.jsonpackage.json の読み書き

https://github.com/unjs/pkg-types

そのディレクトリに存在する tsconfig, package.json, ロックファイルを操作することができます。

resolveTSConfig() でパスの特定、readTSConfig() でオブジェクト形式での読み取り、 writeTSConfig() で書き込み。

42. 🎨theme-colors —― テーマカラーからグラデーションを生成

https://github.com/unjs/theme-colors

getColors 関数にカラーコードかRGBを渡すと、keyが50~950の数字、valueが対応するカラーコードとなるオブジェクト形式で、色の濃淡を変えたカラーパターンを返してくれます。

43. serve-placeholder ―― 存在しない画像へのリクエストをサーバー処理させない

https://github.com/unjs/serve-placeholder

存在しない画像などのアセットにアクセスした際に一律で代わりの画像を返すサーバーミドルウェアライブラリ。

拡張子に応じて返すものを変えるので、404画像にアクセスされるたびにいちいち404のHTMLページを生成してSSRのコストがかかることを防げるようです。

44. node-fetch-native ―― node-fetch の便利なポリフィル

https://github.com/unjs/node-fetch-native

node-fetch ライブラリの V2 と V3 の差分を吸収しつつ、node.js自身がfetchサポートしていればそちらを使うようにしてくれるポリフィル的なライブラリ。node-fetch v3 へのアップデートに困っているプロダクトで役立ちそうです。

前編で紹介した ofetch を node.js 環境で動かす場合にこのライブラリが自動的に呼び出されています。

45. perfect-debounce ―― 重い処理の重複呼び出しを間引く

https://github.com/unjs/perfect-debounce

debounce() の第2引数に指定した秒数の間、その関数の実行を待機し、複数回呼ばれても1度しか実行されないように制御できます。

オプションの leading は、1回目の呼び出しで即時実行するかどうか、 trailing は指定した秒数を超えて中の関数処理が続いている間の呼び出しを引き続き間引くかどうかを決められます。

46. uncrypto ―― ブラウザとNodeのCrypto API を統一的に呼び出す

https://github.com/unjs/uncrypto

乱数生成やハッシュ化・暗号化、公開鍵の検証などを行う Web Crypto および Subtle Crypto へのアクセスを提供します。

ブラウザでは Web Crypto API、Node.js では Crypto Module(require('node:crypto'))で呼び出す必要がありますが、環境に応じて必要な方だけを読み込み、同じAPIでアクセスできるようになります。

47. 🔀httpxy —― node.js 向けの httpプロキシ

https://github.com/unjs/httpxy

http および websocket のプロキシサーバーを立ち上げるためのライブラリ。 node-http-proxy を TypeScript でフォークしたものとなっています。

48. 🥭mongoz ―— Node.jsでMongoDBサーバーを立ち上げ

https://github.com/unjs/mongoz

NoSQL である MongoDB サーバーを簡単に立ち上げられるライブラリ。 npx mongoz だけで MongoDB が立ち上がります。

立ち上がったら VSCode の MongoDB 拡張機能mongodb://localhost:27017 に接続できます。驚くほどの簡単さです。

49. ✏️jimp-compact ―— 定番画像操作ライブラリの軽量版

https://github.com/unjs/jimp-compact

JavaScript で画像を操作する場合の定番である jimp を、あらかじめバンドル・コンパイルしたパッケージ。オリジナルの jimp より27倍サイズが小さいとのことです。

https://github.com/unjs/cookie-es

cookie のパーサー・シリアライザーである cookie を、TypeScript・ESM対応させたもの。

Nuxt 3 で提供されているコンポーザブル useCookie の処理に組み込まれています。

51~53

51. items-promise —— 複数の非同期タスクの処理を簡潔に記述

https://github.com/unjs/items-promise

serialparallel という2つのAPIに、配列とその配列を引数として処理する関数を渡すことで、serialは直列、parallelは並列に処理を行います。

import { serial, parallel } from 'items-promise'

const fn = (async (num: number) => {
  await new Promise((resolve) => setTimeout(resolve, 1000))
  console.log(num)
})
await serial([1, 2], fn)
await parallel([1, 2], fn)

複数の非同期処理の直列実行は、for...ofreduce など、やや直感的でない書き方をする必要があるため、 serial を使うことで簡潔に書けるシチュエーションはありそうです。並列実行は Promise.all() を使えばよいと言えばそれまでですが、セットでより直感的になるとは言えそうです。

52. bundle-runner —— Webpack バンドルを隔離された環境で実行

https://github.com/unjs/bundle-runner

Webpack バンドルを砂場環境で実行するためのパッケージ。Nuxt の依存には直接含まれていません。

53. fs-memo —— node.js に持続的なメモオブジェクトを作成

https://github.com/unjs/fs-memo

node.js のファイルシステムを使った永続的なメモオブジェクトを作成・同期するライブラリ。node.js で localStorage の代わりに使うことがありそうです。

てっきり unstorageNode.js File System に使われていると思ったのですが、特に依存関係には含まれておらず、どこで使われているのかは不明でした。

おわりに

やや駆け足になってしまいましたが、一旦11月時点でUnJSサイトに載っているパッケージは全て紹介できたかと思います。今回紹介した中で個人的に一番よく使っているのは scule です。

やはり後半は Node.js 専用だったり特定のパッケージのフォークだったりと利用用途の限られるものも多かった印象ですが、 perfect-debounceitems-promise あたりは複雑なアプリケーション開発に活用できそうです。

前編・後編通してこの記事の存在によって、 UnJS と Vue/Nuxt コミュニティに興味を持った方が1人でもいたら嬉しいです!

Discussion