6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Nihon UniversityAdvent Calendar 2023

Day 5

素のReact with Bun

Last updated at Posted at 2023-12-05

まえがき

この記事は「Nihon University Advent Calendar 2023」の5日目の記事です。

最近「パフォーマンスが速い」と色々なところで話題のBunですが、その凄さはパフォーマンスだけではなく、色々な機能を包含しているところにもあります。

その中でも、今回はBunのバンドラーやトランスパイラーを使って、素のReact環境を構築してみようと思います😃

完成したもの

最終的なDependencies

めちゃくちゃシンプルですね。

package.json
{
  "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をサポートしています。

src/index.tsx
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コンポーネントです。
今回は適当に以下のようにしておきましょう。

src/App.tsx
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

やったー!完成した!
image.png

Minifyされていなかったり、Development BuildのReactが出力されていたりしますが、後で修正しましょう。

動作チェック

build/index.htmlを作成して、今ビルドしたindex.jsをアタッチしてみます。

build/index.html
<!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をローカルサーバーなりファイルをダブルクリックなりで開いてみましょう。

image.png

しっかり動いていますね。なんてお手軽!!

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/

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?