この記事では、Bunを使用してNext.jsアプリケーションを構築する手順を備忘録としてまとめていきます。また、Next.jsはV14に用いて、かつTypeScriptをベースに構築していきます。
先日Reactに関してもBunを用いて構築する手順についてまとめていますが、重複する部分も一部あります。
ただし、それぞれゴールが異なりますので、興味あれば読んでいただければと思います。
Bunについて
Bunは、JavaScript、TypeScriptのための新世代ランタイムおよびパッケージマネージャーです。2023年9月に安定版(v1.0.0)がリリースされました。
JavaScriptとTypeScriptプロジェクトの開発、テスト、実行、バンドルはすべてBunで対応可能。Bunは、バンドル、テストランナー、Node.js互換のパッケージマネージャを備えた、スピードを追求したオールインワンのJavaScriptランタイム&ツールキットです。
https://bun.sh
Bunは特に、開発効率と実行速度を重視する開発者に向けて設計されており、Node.jsに代わるランタイムとして開発されています。Bunを使用することで、プロジェクトのセットアップからデプロイメントまでの全工程がスムーズになり、開発サイクルを短縮できるため、多くの開発者にとって新たな選択肢となっています。
主な特長は以下の通りです。
- インストールから実行まで、非常に高速なパフォーマンスを提供。BunがRust言語で書かれ、最適化された実行エンジンを持っている
- GitHubリポジトリとシームレスに連携し、簡単に依存関係の管理やプロジェクトのセットアップが可能
- JavaScriptやTypeScriptのコードを即座にコンパイルし、自動的に依存関係を解決。これにより、開発プロセスが大幅に効率化
- TypeScriptにもデフォルトで対応
その他、詳しい情報は公式Docを参照
今回は新規プロジェクトに対して、ランタイム、パッケージマネージャーとして使用しますが、既存プロジェクトに対してもBunに切り替えて使用可能
Next.jsのAppRouterについて
Next.jsのバージョン13.4以降では、AppRouterが安定版として導入され、ルーティングの実装方法に大きな変化がありました。以下は主要な変更点です。
app/
フォルダの導入:app/
フォルダ配下に配置されたpage.tsx
ファイルがルートパスとして機能するpage.tsx
ファイルの特別な役割:app/
フォルダ内のpage.tsx
ファイルのみがルーティングの対象となる- ディレクトリ構造によるルートの自動生成: 例えば、
app/users/
フォルダ内にpage.tsx
を作成すると、自動的に/users
というルートパスが生成される layout.tsx
による自動ラッピング: 同じディレクトリ内にlayout.tsx
ファイルを配置すると、該当ディレクトリのpage.tsx
が自動的にそのレイアウトでラップされる- サーバーコンポーネントとクライアントコンポーネント: デフォルトでは、すべてのコンポーネントはサーバーコンポーネントとして扱われる。クライアントコンポーネントとして扱いたい場合は、ファイルの先頭に
use client
と記述する必要がある - ルーティングの制御: ディレクトリ名に特定の記号を使用することで、ルーティングの挙動を制御できる。例えば、括弧(
()
)、ブラケット([]
)、アットマーク(@
)、アンダースコア(_
)などが使われる。これらの記号は、動的ルーティング、オプショナルなパラメータ、レイアウトの指定、非ルーティングファイルの指定など、さまざまな目的で利用可能
他にも色々あるようですが、こちらの記事がわかりやすかったので貼っておきます。
実装の流れ
開発環境
- Next.js:
v14.1.0
- Bun:
v1.0.29
- React:
v18.2.0
- TypeScript:
v5.2.2
- OS:
MacOS Ventura
構築手順
Bunのインストール
公式Docの通りにインストールを実施します。
$ curl -fsSL <https://bun.sh/install> | bash
# 一度ターミナルを再起動
$ bun --version
1.0.29
他にもbrewコマンドやnpmコマンドなどでインストールが可能
# brewコマンドの場合
$ brew install oven-sh/bun/bun
# npmコマンドの場合
$ npm install -g bun
bun createコマンドでNext.jsアプリケーションを構築
bun create
コマンドでエコシステムを対象にテンプレートを使用できるため、今回も楽に構築していきます。
https://bun.sh/guides/ecosystem/nextjs
bun create next-app
でプロジェクトを作成をするため、下記コマンドを実行します。
インタラクティブ形式でプロジェクトをセットアップしていきますので、適宜設定を決定していきます。
$ bun create next-app
✔ What is your project named? … next-sample-app
✔ Would you like to use TypeScript? … Yes
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … No
✔ Would you like to use `src/` directory? … Yes
✔ Would you like to use App Router? (recommended) … Yes
✔ Would you like to customize the default import alias (@/*)? … Yes
✔ What import alias would you like configured? … @/*
Creating a new Next.js app in /Users/gorida/Github/next-sample-app.
Using bun.
Initializing project with template: app
Installing dependencies:
- react
- react-dom
- next
Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- eslint
- eslint-config-next
bun install v1.0.29 (a146856d)
+ @types/node@20.11.21
+ @types/react@18.2.60
+ @types/react-dom@18.2.19
+ eslint@8.57.0
+ eslint-config-next@14.1.0
+ typescript@5.3.3
+ next@14.1.0
+ react@18.2.0
+ react-dom@18.2.0
301 packages installed [2.05s]
Initialized a git repository.
構築後のディレクトリ構成は以下のようになります。
.
├── .next/
├── node_modules/
├── README.md
├── bun.lockb
├── next-env.d.ts
├── next.config.mjs
├── package.json
├── public
│ ├── next.svg
│ └── vercel.svg
├── src
│ └── app
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx
│ ├── page.module.css
│ └── page.tsx
└── tsconfig.json
ローカルサーバーの起動
package.json
に設定されているscriptsにて、dev
コマンドを実行すると開発用サーバーが起動します。bun
コマンドを用いて以下のコマンドを実行します。
$ bun run dev
next dev
▲ Next.js 14.1.0
- Local: http://localhost:3000
✓ Ready in 2.4s
○ Compiling / ...
✓ Compiled / in 4.5s (522 modules)
ここまでできたら土台となるプロジェクトの作成は完了です。
新規ページの追加
最後に、AppRouterの場合にどのようにページが追加できるのか確認しながら実装していきます。
ゴールとしては、http://localhost:3000/users
にアクセスした際に、ダミーのユーザー情報が一覧表示されるページを追加したいと思います。
流れとしては、
app/
配下にusers/
ディレクトリを作成し、page.tsx
を追加page.tsx
内にユーザー情報を取得するAPIに対してリクエストを送信する処理を追加- 同階層に
layout.tsx
を追加し、page.tsx
をラップ(※やらなくてもいい)
① app/
配下にusers/
ディレクトリを作成し、page.tsx
を追加
└── src
└── app
├── layout.tsx
├── page.tsx
└── users #ディレクトリを追加
└── page.tsx #ファイルを追加
② page.tsx
内にユーザー情報を取得するAPIに対してリクエストを送信する処理を追加
jsonplaceholderというダミーのJSONデータを返してくれるAPIツールを利用して、ユーザー情報を取得していきます。https://jsonplaceholder.typicode.com/users/
に対してリクエストを送信すると、10件分のユーザー情報を返してくれます。
また、getServerSideProps
とgetStaticProps
が廃止されたため、fetchメソッドを用いてAPIからデータを取得します。
page.tsx
type User = {
id: number;
name: string;
};
export default async function Home() {
const res = await fetch("https://jsonplaceholder.typicode.com/users/");
const users = (await res.json()) as User[]; //カスタムfetch関数を作成し、型定義できるようにするのが理想
return (
<>
{users.map((user) => (
<div key={user.id}>
<p>
{user.id}: {user.name}
</p>
</div>
))}
</>
);
}
③ 同階層にlayout.tsx
を追加し、page.tsx
をラップ
最後に、特に意味はないですが検証目的でlayout.tsxファイルを作成し、page.tsxをラップし、親子関係となるのかも確認します。
layout.tsx
export default function UsersLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div>
<h1>ユーザー一覧</h1>
{children}
</div>
);
}
動作確認
http://localhost:3000/usersにアクセスすると以下のようにユーザー情報が表示されるはずです。
これでページ追加の実装も無事に完了しました。
まとめ
今回は、Next.jsの環境構築をBunを使って行ってみました。また、AppRouterにおけるページ追加の方法も触れてみました。普段バックエンド開発が中心のため、フロントエンドの知識はまだまだ乏しいですが、いろいろ触って知識を増やしていければと思います。