Open20

GitHub CodespacesでBun+Next.jsでアプリケーション作成

shunyashunya

まずはGitHub Codespacesで空のプロジェクトを作成する。
https://github.com/codespaces

shunyashunya

dindを使えるように以下コマンド実行後コンテナを再ビルド。

shell
npx tiged microsoft/vscode-dev-containers/containers/docker-in-docker/.devcontainer ./.devcontainer
shunyashunya

BunをダウンロードするようにDockerfileに以下追記。

.devcontainer/Dockerfile
# Download Bun
USER vscode
RUN curl -fsSL https://bun.sh/install | bash \
    && echo "export PATH=$PATH:$HOME/.bun/bin" >> $HOME/profile
USER root

https://github.com/shunya-fug/minimal-memo/commit/8bff4a9f46bb8e640f47ee0fee6eab49594f2520

shunyashunya

bun.shを実行したら自動的にPATHが通っているためRUNの2行目は不要。

.devcontainer/Dockerfile
 # Download Bun
 USER vscode
+RUN curl -fsSL https://bun.sh/install | bash
-RUN curl -fsSL https://bun.sh/install | bash \
-    && echo "export PATH=$PATH:$HOME/.bun/bin" >> $HOME/profile
 USER root
shunyashunya

見た目を整えるために一旦Daisy UIを使う。Tailwind CSSベースのコンポーネントライブラリ。
普通にインストールできた。

shell
bun add -d daisyui@latest

https://daisyui.com/

shunyashunya

Prismaの初期化をするためにbunx prisma initを実行するも、何も反応しない。
どうやらbunx prismaコマンドの実行にはNode.jsが必要らしい。(公式手順の一番上に書いてる)

Note — At the moment Prisma needs Node.js to be installed to run certain generation code. Make sure Node.js is installed in the environment where you're running bunx prisma commands.

Node.jsをインストールするようにDockerfileを修正し、コンテナを再ビルド。

.devcontainer/Dockerfile
 # ...

 RUN apt-get update \
     && /bin/bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" "true" "true" \
     # Use Docker script from script library to set things up
     && /bin/bash /tmp/library-scripts/docker-in-docker-debian.sh "${ENABLE_NONROOT_DOCKER}" "${USERNAME}" "${USE_MOBY}" "${DOCKER_VERSION}" \
+    # Download Node.js
+    && apt-get install -y nodejs npm \
+    && npm install n -g \
+    && n stable \
+    && apt-get purge -y nodejs npm \
     # Clean up
     && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts/

 # ...

https://github.com/shunya-fug/minimal-memo/commit/49d60125bd3e1f2f0169943aeb000b7750e22b86

shunyashunya

Node.jsをインストールしたので改めてbunx prisma initを実行するも、エラー発生。
公式手順ではbunx prisma init --datasource-provider sqliteと実行しているので、--datasource-provider postgresqlを追加すると問題なく初期化出来た。(Vercelでのデプロイを考えているためPostgreSQLを利用)

shell
bunx prisma init --datasource-provider postgresql

prisma initコマンドの引数等は以下リンク先参照。

https://www.prisma.io/docs/orm/reference/prisma-cli-reference#init

shunyashunya

テーブル名やカラム名をスネークケースにしたい。
Prismaで用意されている方法として、カラムには@map()、テーブルには@@map()を付けることで実際のテーブル名を変更できる。

ただ、単純に面倒なのと付け忘れが起こったりしそうなので以下の記事を参考にprisma-case-formatツールを使うことにする。

https://qiita.com/ebatan-developer/items/14031910f869b78b1439

https://github.com/iiian/prisma-case-format

Bunでのインストールは以下の通り。

shell
bun a -d prisma-case-format

以下、プロジェクトルート($CODESPACE_VSCODE_FOLDER/minimal-memo)でのコマンド実行。

shell
bun prisma-case-format --uses-next-auth -f prisma/schema.prisma

Auth.jsを利用している場合は、--uses-next-authオプションを付ける。

https://github.com/iiian/prisma-case-format?tab=readme-ov-file#with-nextauthjs

shunyashunya

Auth.js関連のテーブル、カラムはスネークケースにできないみたい。
複数の命名規則が混在するのは嫌な感じだけどどっちがいいのか...。

shunyashunya

以下のようにseed.tsを作成してデータを作成しようとしたところ、データが作成されない。

prisma/seed.ts
import { Prisma, PrismaClient, TagType } from "@prisma/client";

const prisma = new PrismaClient();

const tweetList: Prisma.TweetCreateInput[] = [
  // ...
];

const tagList: Prisma.TagCreateInput[] = [
  // ...
];

async function main() {
  await prisma.tweet.createMany({ data: tweetList });
  await prisma.tag.createMany({ data: tagList });
}

main()
  .catch((e) => {
    console.error(e);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });

どうやらbunを使うときはトップレベルawait構文で記述する必要があるらしい。

prisma/seed.ts
 // ...
 async function main() {
   await prisma.tweet.createMany({ data: tweetList });
   await prisma.tag.createMany({ data: tagList });
 }
 
-main()
+await main()
   .catch((e) => {
     console.error(e);
   })
   .finally(async () => {
     await prisma.$disconnect();
   });

https://github.com/prisma/prisma/issues/21324#issuecomment-1751945478

package.jsonには以下のように記述した。

package.json
{
  // ...
  "prisma": {
    "seed": "bun run prisma/seed.ts"
  },
  // ...
}