まえがき
この記事は「Nihon University Advent Calendar 2023」の5日目の記事です。
最近「パフォーマンスが速い」と色々なところで話題のBunですが、その凄さはパフォーマンスだけではなく、色々な機能を包含しているところにもあります。
その中でも、今回はBunのバンドラーやトランスパイラーを使って、素のReact環境を構築してみようと思います😃
完成したもの
最終的なDependencies
めちゃくちゃシンプルですね。
{
"devDependencies": {
"@types/react": "^18.2.42",
"@types/react-dom": "^18.2.17",
"@types/web": "^0.0.125",
"bun-types": "latest"
},
"peerDependencies": {
"typescript": "^5.0.0"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
リポジトリの初期化
Bunの環境構築
bun init
今回はソースコードのエントリポイントはsrc/index.tsx
としました。
Depsのインストール
bun add react react-dom @types/react @types/react-dom @types/web
必要なパッケージをインストールします。たったこれだけで一応Reactが動きます。
名前空間の設定
document
のようなブラウザの名前空間はBunには存在しないので、@types/web
をインストールして、tsconfig.json
の"types"に付け加える必要があります。
最低限のコードを書く
まず、以下のようにシンプルな形でスクリプトのエントリポイントを作ります。
なんのライブラリも導入せずに突然タグをぶち込んでいますが、大丈夫です。Bunのバンドラーは標準でJSXをサポートしています。
import { StrictMode } from "react"
import { createRoot } from "react-dom/client"
import { App } from "./App"
const rootElement = document.getElementById("root")! // これが取得できなければエラーで止まるべき
const root = createRoot(rootElement)
root.render(
<StrictMode>
<App />
</StrictMode>
)
<App />
の中身は、なんの変哲もないただのReactコンポーネントです。
今回は適当に以下のようにしておきましょう。
import { useState } from "react"
export const App = () => {
const [cnt, setCnt] = useState(0)
return (
<div>
<h1>bun!</h1>
<button onClick={() => setCnt((prev) => prev + 1)}>count: {cnt}</button>
</div>
)
}
はい、素晴らしいSPAの完成です!
試しにビルドしてみる
早速ビルドしてみましょう。
% bun build ./src/index.tsx --outdir ./build
Minifyされていなかったり、Development BuildのReactが出力されていたりしますが、後で修正しましょう。
動作チェック
build/index.html
を作成して、今ビルドしたindex.js
をアタッチしてみます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Bun-Minimal-React</title>
</head>
<body>
<div id="root"></div>
<noscript>
JavaScript is disabled! You need JavaScript to view this page.
</noscript>
<script src="index.js" defer></script>
</body>
</html>
build/index.html
をローカルサーバーなりファイルをダブルクリックなりで開いてみましょう。
しっかり動いていますね。なんてお手軽!!
Production Buildしてみよう
先ほどビルドした時の画面を見てみてください。
% bun build ./src/index.tsx --outdir ./build
./index.js 962.62 KB
[20ms] bundle 11 modules
ただのカウンター機能しか実装していないのにデカバンドルができていますね。これはいただけないので、ちっちゃいバンドルを作ります。
% NODE_ENV=production bun build ./src/index.tsx --outdir ./build --minify
./index.js 138.29 KB
[9ms] bundle 8 modules
ちっちゃくなりましたね。
ビルドもたったの9msで終わっています。速い!!
情報は少ないけど、ポテンシャルはあるぞ
実際に何かを作りたいとなったときは、CSSヘルパーの導入やルーティングの設定など色々やることは多いと思いますが、React自体を動作させるだけだったら、たったこれだけのコードで動きます。ビルドも高速なので、手順が確立されてきたら開発体験の向上にも繋がりそうです。
今回はBunのバンドラーやトランスパイラーを使ってみましたが、他にもSQLite3 ドライバやJest互換のテストエンジンなど、Bunにはさまざまなものが搭載されています。これらのエコシステムに乗っかれば、割となんでもできそうでワクワクしますね!!誰か記事待ってます!
おまけ:SPAのフレームワークっぽいのを作ろうとしてみた
今回の記事を作るにあたって、調査のためにBunのエコシステムにできるだけ乗っかったフレームワークを作ろうとしてみました。
作りかけなので微妙です。文献が少なくて右往左往しているので、改善提案とか良さげな記事とかあればぜひ教えてください。
Demo: https://avaice.github.io/bun-minimal-react/