【第2回】Next.js × SQLite で始める個人アプリ開発入門

パスワード管理アプリ作成

こんにちは。前回は「なぜ自分でパスワード管理アプリを作ろうと思ったのか?」という動機や背景についてお話しました。
今回は、実際の開発にどのように取り組んだかをご紹介します。

【第1回】の記事は以下を参照してください。

【第1回】なぜ自分でパスワード管理アプリを作ったのか?〜40代エンジニアの試行錯誤〜

Next.js プロジェクトの作成

まず、作業用ディレクトリを作成し、Next.js プロジェクトを初期化します。

    
mkdir /var/www/private-desk
cd /var/www/private-desk
    
  

ここで、Next.js プロジェクトを作成します:

npx create-next-app@latest .

対話形式での質問には以下のように回答しました:

  • TypeScript:Yes
  • ESLint:Yes
  • Tailwind CSS:Yes
  • src/ ディレクトリを使う:Yes
  • App Router を使用:Yes(推奨)
  • Turbopack を使用:Yes
  • インポートエイリアス:@/*(デフォルト)No

これにより、最新構成の Next.js プロジェクトが完成します。

DevContainer の設定

開発環境を整えるために、VS Code の Dev Containers を利用しました。以下のファイルを .devcontainer フォルダに配置します。

.devcontainer/devcontainer.json

    
{
  "name": "private-desk",
  "build": {
    "dockerfile": "Dockerfile"
  },
  "workspaceFolder": "/app",
  "workspaceMount": "source=${localWorkspaceFolder},target=/app,type=bind,consistency=cached",
  "postCreateCommand": "npm install",
  "customizations": {
    "vscode": {
      "settings": {},
      "extensions": [
        "esbenp.prettier-vscode"
      ]
    }
  }
}
    
  

.devcontainer/Dockerfile

    

FROM node:20-alpine

# SQLite 関連のライブラリ
RUN apk add --no-cache bash git sqlite sqlite-dev

# 作業ディレクトリ
WORKDIR /app
    
  

SQLite の導入と設定

アプリのデータベースには better-sqlite3 を使用しました。高速でシンプルに扱えるのが魅力です。

    
npm install better-sqlite3
    
  

型エラーを防ぐため、型定義ファイルを以下のように作成します:

src/types/better-sqlite3.d.ts

    
// types/better-sqlite3.d.ts
declare module 'better-sqlite3';
    
  

src/lib/db.ts

    
import Database from 'better-sqlite3';
import path from 'path';
import fs from 'fs';

// データベースファイルのパスを解決
const dbPath = path.resolve(process.cwd(), 'data/database.sqlite');
const dbDir = path.dirname(dbPath);
if (!fs.existsSync(dbDir)) fs.mkdirSync(dbDir, { recursive: true });

const db = new Database(dbPath);

export function runSelect<T>(sql: string, params: (string | number | null)[] = []): T[] {
  const stmt = db.prepare(sql);
  return stmt.all(...params) as T[];
}

export function runGet<T>(sql: string, params: (string | number | null)[] = []): T | undefined {
  const stmt = db.prepare(sql);
  return stmt.get(...params) as T | undefined;
}

export function runExecute(sql: string, params: (string | number | null)[] = []): void {
  const stmt = db.prepare(sql);
  stmt.run(...params);
}

export default db;
    
  

パスワード管理テーブルの作成

テーブル作成用スクリプト:scripts/init-db.ts

    
import db from '../src/lib/db';

db.exec(`
  CREATE TABLE IF NOT EXISTS password_manager (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    site_name TEXT NOT NULL,
    site_url TEXT NOT NULL,
    login_id TEXT,
    password TEXT NOT NULL,
    email TEXT,
    memo TEXT,
    category TEXT,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
  );
`);

console.log('パスワード管理テーブルを作成しました');
    
  

実行:

    
npx tsx scripts/init-db.ts
    
  

次回予告:「画面の構築とパスワード表示機能の実装」

次回は、画面の構築とパスワードの表示機能について取り上げていきます。
今回と同様に、ゆるっと書いていきたいと思います。

まとめ・感想

この記事では、Next.js プロジェクトの立ち上げから、SQLite 導入、テーブル作成までの流れをご紹介しました。
環境構築というと少し面倒に感じるかもしれませんが、自分専用のアプリを作るという明確な目的があると、不思議と前向きに取り組めるものです。
特に、自分の手で構築した仕組みが正常に動作したときの達成感は大きく、「次は何を作ろう?」というモチベーションにもつながります。

コメント

0 件のコメント:

コメントを投稿

コメントをお待ちしています。