🐈

Bunをさわる。

2022/09/04に公開

はじめに

JavaScriptの実行環境といえば、DenoやCloudflare WorkerなどのWeb標準APIベースの環境にも様々なフレームワークが対応し、本番環境としても採用するサービスが増えてきました。
選択肢が増えてたことでJavaScriptの言語性能やTypeScriptの標準対応など、強みを生かした開発ができるようになった昨今です。
https://deno.land/
https://workers.cloudflare.com/

そんな中、JavaScript(TypeScript)の新たな実行環境が生まれました。

Bun.sh

https://bun.sh/
BunはDenoのようにNode.jsに依存しないバンドラ・トランスパイラ・タスクランナー・npmクライアントが含まれたJavaScript実行環境です。

zenn.dev内にもすでに記事にされている方がいらっしゃいますが、まだあまり広まっていない印象なので私も紹介してみることにしました。

Bun is designed as a drop-in replacement for your current JavaScript & TypeScript apps or scripts — on your local computer, server or on the edge. Bun natively implements hundreds of Node.js and Web APIs, including ~90% of Node-API functions (native modules), fs, path, Buffer and more.

説明を見ると、Edgeでの実行を想定しているのでDenoやWorkerのようなWeb標準APIからfsなどのNode.js APIまでの多くをパッケージ化しているようです。

今日はこのBun.shの紹介をしたく、記事を書くことに決めました。

かるく触ってみる

ここではBunの機能のほんの一部だけご紹介します。

インストール

https://github.com/oven-sh/bun#readme
現状のガイドをみる限りネイティブではmac OSを含むLinuxベースの環境でしか対応しておりません。
したがって、windowsでの実行にはDockerもしくはWSLを使用する必要がありそうです。

curl

curl -fsSL https://bun.sh/install | bash

Docker

docker pull jarredsumner/bun:edge
docker run --rm --init --ulimit memlock=-1:-1 jarredsumner/bun:edge

Bunでの実行

BunでのデフォルトのCLIにhttpサーバーが含まれています。このあたりのCLIツールの使い方はDenoと同じように使用できそうです。
試しにhttpサーバーをホストしてみます。

// JavaScript: http.js
export default {
  port: 3000,
  fetch(request) {
    return new Response("Hello World");
  }
};
// TypeScript: http.ts
export default {
  port: 3000,
  fetch(request: Request) {
    return new Response("Hello World");
  }
};
bun run http.js
# or
bun run http.ts

これで、portで指定したポート番号(今回は3000番)とfetch関数で記述したプログラムでhttpサーバーを立ち上げることができます。
簡単ですね!

npmパッケージを使う

npmのパッケージを使ったり、Node.jsモジュールを使ったりするには、依存関係のインストールをします。

標準パッケージの使用

外部パッケージを使用しなくてもNode.jsのpathfsstreamなどは標準対応しています。ですが、これをTypeScriptで使用するとなると型エラーが発生します。

import { resolve } from "path";
// ↑ここで`path`の型が存在しないためエラーが生じる

ですので、Bunに含まれている標準APIの型をインストールします。

bun init

package name (bun): # パッケージ名の入力
entry point (indes.ts) # エントリーポイントの入力

これによって、

  • index.ts
  • .gitignore
  • tsconfig.json
  • README.md
    が作成されます。
    なお、ここでのtsconfig.jsonはエディターの自動補完のみで使用されます。

これでNode.jsのパッケージが使用できるようになりました!

npmパッケージの使用

ここでnpmパッケージを利用してみましょう。
試しにlodashをインストールしてみます。

bun add lodash

ここでpackage.jsonが作成され、dependencieslodashがインストールされていることを確認できます。
そしてこれを実行した方は、その速度に驚くでしょう!!
ここで特に実感できますが、Bunの特徴はその実行の速度にもあります。インストールのみならず、スクリプト自体の実行もとても速いです。

タスクランナーを使用する

これはnpmyarnpnpmなどと同じように、package.jsonに記述したタスクを実行できます。

# devDependenciesにインストール
bun add -d rimraf
// package.json
{
  "scripts": {
    "clean": "rimraf http.ts"
  }
  "devDependencies": {
    "rimraf": "^3.0.2"
  }
}
bun clean

Reactを使用してみる

BunのhttpサーバーでReactを使用してみます。

bun add react react-dom
bun add -d @types/react @types/react-dom
// index.tsx
import { renderToReadableStream } from "react-dom/server";

const dt = new Intl.DateTimeFormat();

export default {
  port: 3000,
  async fetch(request: Request) {
    return new Response(
      await renderToReadableStream(
        <html>
	  <head>
	    <title>Hello World</title>
	  </head>
	  <body>
	    <h1>Hello from React!</h1>
	    <p>The date is {dt.format(new Date())}</p>
	  </body>
	</html>
      )
    );
  }
}

先程と同様、http://localhost:3000を開くとhtmlがレンダリングされていることがわかります。

デプロイ

現状ではBunに特化したデプロイ環境はありませんので、Dockerを使用できる実行環境やVPSで動かすのが現実的かと思われます。
Bunの開発元のoven.shでは、開発者のコメントと今後のロードマップなどが記載されており、そこでは将来的にBunに特化したedgeホスティングを立ち上げる予定のようです。
https://oven.sh/
denoと同じような流れをたどっていますが、Denoがパッケージをスクリプトから直接インストールしてくるのに対して、bunはNode.jsアプリケーションの構成をそのまま移植できるように作られています。

おわりに

ここまで簡単にBunについて紹介してきました。
Bunにはこの他にも、CLIでの実行に対しての引数をDockerのように設定ファイルで記述できるbunfig.tomlの機能や、組み込みのSQLiteモジュールなど、一応一通りのアプリケーション構築のためのユーティリティが揃っています。
この記事だけで紹介しきれないので今回は割愛しますが、興味がある方は是非試してみて下さい。

https://github.com/oven-sh/bun

以上、Bunのご紹介でした。
触ってみて楽しかったです。

Discussion