| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

Next.js

提供: MyMemoWiki
2024年10月5日 (土) 15:21時点におけるPiroto (トーク | 投稿記録)による版 (→‎サーバーコンポーネント)
ナビゲーションに移動 検索に移動

React | MUI |

概要

  • Reactは、あくまでUI部分のみ
  • 本格的なアプリ開発には周辺領域を担うためのフレームワークが必要
  • Reactベースのフレームワークとしてデファクトスタンダードと言える存在
  • 主なライブラリ
    • ファイルシステムベースの設定レスルーター
    • サーバーコンポーネント
    • データ取得用fetchメソッド
    • リソース組み込みの自動最適化
    • CSSフレームワーク、Tailwind CSSへの標準対応


導入

newdelhi:Workspaces piroto$ npx create-next-app@latest
Need to install the following packages:
create-next-app@14.2.14
Ok to proceed? (y) y

✔ What is your project named? … first-nextjs-app
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
Creating a new Next.js app in /Users/piroto/Workspaces/first-nextjs-app.

実行

開発

npm run dev

Start next js.png

本番ビルド+実行

npm run build
npm start

App Router

  • React Routerとは異なる独自のルーターを標準で提供
  • コンポーネントそのものはReactと変わらない

2種類のルーター

  • Pages Router : 旧来から提供されている
  • App Router : Next.js 13から導入された新しいルーター(推奨)

App Router

  • フォルダベースのルーター
  • ルート定義不要、フォルダ階層に準じてリクエストパスとコンポーネント(.jsファイル)との対応関係が決まる
  • page.jsはファイル名も固定でフォルダー構造だけでリクエストパスが決定される
アプリ共通の外枠
  • layout.js
  • <html>、<body> 要素が存在し、個々のページを埋め込むため chilrenプロパティを引用していることが条件

ルートパラメータ

  • [名前] : 単一パラメータ
  • [...名前] : キャッチオールセグメント
  • [[...名前]] : 省略可能なキャッチオールセグメント
App Routerのルートパラメータ
フォルダ階層 対応リクエスト パラメータ
/app/hoge/[id]/page.js /hoge/001 { id : '001' }
/app/foo/[...keys]/page.js /foo/aaa/bbb { keys: ['aaa', 'bbb'] }
/app/bar/[[...keys]]/page.js /bar {}
/bar/aaa/bbb { keys: ['aaa', 'bbb'] }

Tailwind CSS

  • https://tailwindcss.com/
  • ユーティリティファーストをコンセプトに開発されたCSSフレームワーク
  • ユーティリティを組み合わせてデザインを作るので独自のスタイルを作りやすく細かな調整もしやすいメリット
  • 標準のサイズ、カラーなどは用意されている

Cheat Sheet

  • Tailwind CSSによるスタイルを適用
import "./globals.css";
    :

<ul className="fle bg-blue-600 mb-4 pl-2">...</ul>

Prisma

  • JavaScriptアプリからデータベース操作を取り持つO/Rマッパー

インストール

  • 成功すると以下のファイルが生成される
    • .env : 環境変数ファイル、gitignore に追加する
    • prisma/schema.prisma : Prismaのスキーマファイル

sqliteでの構成例

$ npm install prisma --save-dev
 $ npx prisma init --datasource-provider sqlite
 warn You already have a .gitignore file. Don't forget to add `.env` in it to not commit any private information.

データモデルの定義

  • prisma/schema.prisma に追記
model reviews {
  id          String @id
  title       String
  author      String
  price       Int
  publlisher  String
  published   String
  image       String
  read        DateTime  @default(now())
  memo        String
}
  • DBに反映
$ npx prisma db push
  • Prisma Studio(Webベース管理ツール)で確認
$ npx prisma studio


  • Error: @prisma/client did not initialize yet. Please run "prisma generate" and try to import it again.
$ nps prisma generate
import { PrismaClient } from "@prisma/client";
  • Prisma Clientの利用
import { PrismaClient } from "@prisma/client";

サーバーアクション

  • Next.js内蔵の仕組み
  • ページコンポーネント、イベントハンドラー、<form<要素のaction属性などからサーバーコードを呼び出す仕組み
  • サーバーとのやりとりに際し、fetchなどの非同期通信コードの不要となり、例えばコンポーネントからデータベースを操作するにも直感的なコードを記述できる
  • 現時点ではα版

有効化

next.config.mjs

const nextConfig = {
    experimental: {
        serverActions: true
    }
};

サーバーコンポーネント

  • Next.jsの基本はサーバーコンポーネント
  • ファイルの先頭に、'use client'、'use server'ディレクティブを記述する

実装

ルートレイアウト

アプリ内のリンクにはLinkコンポーネントを利用

import Link from "next/link";

規定で以下のようなコンポーネントが用意されており、アプリ内リソースを効率的に利用できる

コンポーネント
コンポーネント 概要
<Link> リンクを生成
<Script> スクリプトのロード
<Image> 画像を表示

メタデータ

  • メタデータを定義しておくことで、個々のページに適切なヘッダーなどを埋め込める
  • 複数箇所で宣言された場合、シャローマージされる
export const metadata: Metadata = {
  title: "Reading Recorder",
  description: "自分が読んだ書籍の記録を残す",
};
  • generateMetadata関数を利用しデータベースなどから取得した結果を元に動的に生成も可能
export async function generateMetadata({ params, searchParams }) {
    :
    return {
        title : result.title,
            :
    }
}

フォント

  • Googleフォント(無償フォントのディレクトリサービス)を有効化
  • 具体的なフォントはGoogleフォントから自由に選択できるが一般的にはバリアブルフォント推奨(下例ではInconsolata)
  • フォントはファイルサイズが大きいので、subsetで利用する文字のみ取り出す
  • fnc.className でフォントを適用できる
import { Inconsolata } from 'next/font/google';
const fnt = Inconsolata({ subsets: ['latin'] });

  :
<body className={`${fnt.className}` }>

MUI

MUI

Tips

リモートホストからの画像表示を許可する

  • next.config.mjs
const nextConfig = {

    :

    images: {
        remotePatterns: [
            {
                hostname: 'books.google.com'
            } 
        ] 
    }
};