---
# System prepended metadata

title: next.jsを駆け足で学ぶ

---

参考
https://nextjs.org/ > What's in Next.js?等
本：next.js超入門
https://raccoon-a.backlog.jp/alias/wiki/1075710934 > Next.jsの基礎知識

# next.jsを駆け足で学ぶ
https://nextjs.org/ にnext.jsの特徴が紹介されています。
実際案件に着手したときに早い段階で触れそうな特徴を今回のMU会では可能な限り翻訳してまとめました。今回はnext.jsって何者？を広く浅く知れたらいいなと考えています。
next.jsはreactのフレームワークなので一部reactの話も含まれますが、
reactの深堀はしません。

---ここからMU会では本の内容を省略せず読み上げます---
### そもそもreactとは？
reactの登場でwebアプリ開発に革命をもたらしました。
- jsxで書ける
- 仮想DOMの存在
    - htmlの要素にjsでアクセス（DOM）を操作するとその都度webページが書き換えられるため、操作箇所が増えると動作に影響がでる
    - 仮想DOMはメモリ内にだけ存在するDOM、まず仮想DOMでwebページの更新をする。すべて更新が完了したら仮想DOMをwebページに適応する。これによって表示の更新が一度で済むようになる。


## next.jsはなぜ誕生した？？
現在のWEB開発では「バックエンドからフロントエンドへ」の考え方が主流だからです。
フロントエンドにreactを使いバックエンドまですべて一体化して開発できるフレームワークをつくるという考え方が発生し、next.jsがつくられました。

Reactは強力なフレームワークですが、主にUI関連の処理に特化しており、背後でのデータ処理やルーティングなどの基本的なWebアプリの機能を提供しません。そのため、Next.jsのようなフレームワークが必要とされました。


フレームワークとは
フロントエンドでリアルタイムに変化する処理をつくるのは難易度が高い。
そのため、webアプリの基本的な仕組みが組み込まれており、システムをもっている（ライブラリはもっていない）、フレームワークの指示に従えばアプリ全体のシステムがつくれてしまう、フレームワークを使って実装することが多い。
---ここまで---

## next.jsの特徴について
https://nextjs.org/ > What's in Next.jsには以下の特徴が記載されています。
現在のバージョンはv14.3(https://github.com/vercel/next.js/releases） です。
- ★Built-in Optimizations
- ★Dynamic HTML Streaming
- ★React Server Components
- ★Data Fetching
- ★CSS Support
- Client and Server Rendering
- Server Actions
- Route Handlers
- Advanced Routing & Nested Layouts
- Middleware

※v13のときと特徴の欄が変わっているような気がするので、学習するときは
https://nextjs.org/docs から学んだ方がよさそうです。（特徴からだとあっちこっちにリンクとばされてわけが分からなくなる..）

### Built-in Optimizations
URL：https://nextjs.org/docs/app/building-your-application/optimizing/images

この章ではImage Optimization（画像最適化）について記載されています。
next.jsではimageコンポーネントを利用することを推奨しています。

imgタグではなく、imageコンポーネントを使うべき理由：
- 最適なファイル形式に変換する（webp、AVIFなど）
- 適切なタイミングで画像をダウンロードさせる（lazy loading機能が標準でついている）
- アスペクト比を認識しているためレイアウトシフトを防ぐことができる

使い方
```
import Image from 'next/image'
import profilePic from './me.png'

export default function Page() {
  return (
    <Image
      src={profilePic}
      alt="Picture of the author"
      // width={500} automatically provided
      // height={500} automatically provided
      // blurDataURL="data:..." automatically provided
      // placeholder="blur" // Optional blur-up while loading
    />
  )
}
```
`import Image from 'next/image' `を宣言すると`<Image>` タグが使えるようになります。
importした場合、widthとheigthを明示的に指定する必要はありません。（内部画像の場合は）
また、widthとheigthはアスペクト比を理解するためなので実際の表示に影響はありません。

デモ：
~~https://nextjs.org/docs/app/building-your-application/optimizing/images#responsive-image-with-aspect-ratio~~　（削除済み）
- サイズが可変しており、width、heigthの指定は無視されている
- chromeで見るとAVIFになっている

補足：
`picutreタグ`を使う場合は`getImageProps()`を利用します。
https://nextjs.org/docs/app/api-reference/components/image#getimageprops

### Dynamic HTML Streaming
URL：https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming#example

Next.jsでは`<Suspense>`タグを使ったストリーミングがサポートされています。

代表的なレンダリングと比較すると、

- クライアントサイドレンダリング
    - vueで作成したSDのページ

- サーバーサイドレンダリング
    - htmlがすべて生成されているのでクライアント側で即座に表示される。SDとか

- ストリーミング
    - コンポーネントごとにレンダリングをするので早い
        - 準備ができたコンポーネントから順次表示されるので画面が真っ白になる期間が少ない
    - https://zenn.dev/tm35/articles/0a64177c0a41bd#suspense-%E3%82%92%E4%BD%BF%E3%81%86%E3%81%A8
        - 上記の記事わかりやすいです。

デモ > 3番目：
https://react.dev/reference/react/Suspense#revealing-nested-content-as-it-loads
`<Suspense>`を囲ったかたまり毎に表示されます。
`<Suspense>`内に複数のコンポーネントがある場合は、それらのレンダリングがすべて完了しないと表示されません。

### React Server Components
URL:https://nextjs.org/docs/app/building-your-application/rendering

React Server Componentsはサーバー側だけでレンダリングするreactの技術です。
現在のnext.jsで開発する場合（App router）、React Server Componentsが適応されています。
端的に言うと、コンポーネントを作成するとき、
サーバーコンポーネントまたは、クライアントコンポーネントのどちらかに分類する必要があります。
いつも通りコンポーネントを作成すると、それはサーバーコンポーネントとして扱われます。
もしクライアントコンポーネントを作成したい場合は、`use client`をファイル上部に記載するだけです。

名の通りサーバーコンポーネントはサーバー側でのみ実行されます。
クライアントコンポーネントはサーバー側でレンダリングされた後クライアント側でもレンダリングされます。

以前は、このように分類されていなかったのですべてのコンポーネントがサーバーとクライアントでレンダリングされていました。
（つまり、全てのコンポーネントはクライアントコンポーネントとして扱われていました。）

これが生まれた背景として、
今まではサーバーとクライアントを実装する言語やフレームワークは異なっていましたが、
reactを使えばサーバーサイドとクライアントサイドを実装する言語（js）とフレームワーク（next.js）を同じものをつかって実装することができるようになりました。
ただその代わりに、実装者が境界線を引く必要が出来ました。
どこまでをクライアント処理（クライアントコンポーネント）、サーバーサイドの処理（サーバーコンポーネント）とするのかとか等です。

例：
https://nextjs.org/docs/app/building-your-application/rendering#request-response-lifecycle
以下はユーザがページにアクセス/フォームをsubmitするなどの一連の流れで発生するステップだが、この軸に基づき境界線を自ら引く
（多分今まではこの境界線を引くのは開発さんが普段やっていてバックエンドはjavaなどで開発されていた。）

#### サーバーコンポーネントにするメリット
- データストアに近いところで処理されるので、データを取得する時間が短くなります。クライアントサイドからのリクエストを減らしレンダリング時間を短縮するのでパフォーマンスを改善できます
- セキュリティ（api keyなどを使う場合）改善
- サーバーサイドでhtmlを生成します
    - 静的な部分はビルド時に生成されて、動的な部分はリクエストを受けてから実行されます。初期のバージョンでは空のhtmlをいったん返していましたが現在はhtmlを全部生成してクライアントに送っています。
- クライアントサイドの処理を減らせるので、ユーザーの環境（遅いインターネットやパワフルではないデバイス）に左右されにくいです。
- サーバーサイドでhtmlを生成されるのでボットやクローラーに認識されやすいです。
- ストリーミングで処理することができます。
    - コンポーネントごとに、優先度の高いものから処理をしてクライアントサイドに表示されます。

詳細：https://nextjs.org/docs/app/building-your-application/rendering/server-components#benefits-of-server-rendering

#### クライアントコンポーネントのメリット
- use state, effects, event listenersを処理するときに使うことができ、UIの更新・ユーザーへのフィードバックを即座に処理することができる
    - サーバーコンポーネントで上記の処理をしようとするとエラーになります。
- browser APIsを使うことができる

#### サーバーコンポーネント vs クライアントコンポーネントの使い分け
下記の表を参考に、どの処理をするによってサーバーまたはクライアントコンポーネントで作成するかを決めます。

境界線：
https://nextjs.org/docs/app/building-your-application/rendering/composition-patterns#when-to-use-server-and-client-components

#### 他重要な事
サードパーティーのライブラリを使う場合：
まだサーバーコンポーネントとかに対応していないので
読み込み時には`use client`を宣言してあげる必要がありそうです。

上位のコンポーネントはクライアントコンポーネントにしない：
`use client`をつけたファイル以下はすべてクライアントコンポーネントになります。
そのためpaidの親ファイルたちは`use client`をつけていません。
一般的になるべくクライアントコンポーネントは下層にもっていくように設計する事を推奨しています。
理由としては、クライアントコンポーネントの中でサーバーコンポーネントを基本的にimportすることができない事＆レンダリングする方向としてサーバーコンポーネント、その次にクライアントコンポーネントとなっているためその逆の処理が出来ないからです。
もしどうしてもクライアントコンポーネントにサーバーコンポーネントをimportしたい場合は、
下記の方法でchildとして設計してください。
https://nextjs.org/docs/app/building-your-application/rendering/composition-patterns#supported-pattern-passing-server-components-to-client-components-as-props

~~

コンポーネント間でfetchを使い同じデータを共有することが可能（キャッシュを使い）なので、propsなどでバケツリレーをする必要がない。
サーバーサイドで処理すべき内容をクライアントサイドコンポーネントに記載することはできるがそれを防ぐために以下でデバッグも可能
```
npm install server-only
```
※例えば、公開してはいけないプライベート変数など書くと、ビルド時にからの文字列になり安全ではあるが意図しない挙動になるため
※この逆のデバッグもあり、windowオブジェクトにアクセスするようなコードをサーバーコンポーネントに記載していた場合エラーが出るようにすることも可能
（paidの環境をみてみる）

~~


### Data Fetching
URL：https://nextjs.org/docs/app/building-your-application/data-fetching

この章ではfetch（cashの有効化）とRevalidation（更新）について記載されています。

fetch：
サーバーコンポーネント内にfetch処理をすることを推奨しています。
next.jsではfetchが使えて、デフォルトでcashされます。
例：管理画面のAパネルコンポーネントで企業情報apiたたいて企業番号を取得→ヘッダーコンポーネントで企業情報apiたたく（キャッシュされているので再度リクエストが飛ばない）
※キャッシュを無効化したい場合は設定追加すれば可能

もし、クライアントコンポーネントでもfetchを使いたい場合は
Route Handlersを使うことを推奨しています。
※Route HandlersのGETメソッドはキャッシュされるがPOSTはキャッシュされない
https://nextjs.org/docs/app/building-your-application/routing/route-handlers#caching

Revalidation
fetchを使うと自動でキャッシュされてしまうため、
それを捨てて更新するための処理も用意されています。
- 時間指定
- キャッシュを削除したいタイミングに処理を書く

使い方：
https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#revalidating-data

revalidateTagを使ってキャッシュ削除の処理（日本語）：
https://qiita.com/TechForGood/items/86027f9d4952bd6d959f#4-1-revalidate%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3


キャッシュ有効期間について：
https://nextjs.org/docs/app/building-your-application/caching#duration-3


### CSS Support
URL：https://nextjs.org/docs/app/building-your-application/styling

CSS Module、グローバルcss、Tailwind CSS（テールウィンド）、CSS-in-JSがサポートされています。
その中で、CSS Moduleとグローバルcssについて記載します。

#### CSS Module
CSS Modulesが標準サポートされています。
`.module.css`、`.module.sass`、`.module.scss`で作成すれば認識されます。

sass・scssを使う場合は下記が必要です。
sassの変数もCSS Modulesファイル内で使えます。

インストールコマンド
```
npm install --save-dev sass
```

ファイルに読み込む時
```
import styles from './styles.module.css'
```

#### グローバルcss（共通であてたいスタイル）
どのファイルにもimport...で読み込むことは可能です。

ルートのファイルに読み込む時（app/layout.tsx）は
ファイルつくって下記を書くだけでよさそう。
外部ファイルも同じです。
```
import './global.css'
```

※サードパーティのcssを使う場合、
npm packageでinstallまたは、ファイルをDLしておく必要があります。
`<link rel="stylesheet" />`は使えません。

## next.jsの環境を用意してみる
reactの開発も、nextの開発もどちらもnode.jsを使う。
nodeをインストール（たしか最低18か20である必要があります。）

①下記のコマンド実行
`npx create-next-app@latest` （現在）

②paidと同じような環境をつくる（typescript、app/src構造）
![image](https://hackmd.io/_uploads/B1fF4idf0.png)

大まかなフォルダ構成
```
.nextフォルダ
- next.js関連のファイルがまとめられている
node_modules
- プロジェクトで使うパッケージがまとめられている
public
- 公開されるファイルがある
src
- next.jsのプログラム（jsファイル）がまとめてある
```

※npx→node.jsに用意されているコマンドプログラム。
パッケージを実行するための専用コマンドで、create-next-appというパッケージを実行している

### 新規ページ作成するには
1. page.tsx作成
- `src/app` 以下に `page.tsx` を作成。これで`/about` にアクセスできます。
    - page.tsxには表示するページを定義するものを書きます。これがないと動きません。
2. layout.tsx作成
- もし、aboutディレクトリ以下ではレイアウトを変えたい場合、
`about/layout.tsx`を作成します。
    - layout.tsxにはページのベースとなるレイアウトを定義します。必要に応じて作成してください。作成しない場合は上の階層にあるlayout.tsxにpage.tsxの内容を反映します。

## paidの環境を見てみる
上記で基礎は見たので時間あればざっと比較


### まとめ
今まではサーバーサイドの処理（java）とクライアント側の処理（vue）でそれぞれ別の言語で作成していたが機能が沢山ある（ありすぎて理解しきれない）next.jsを使えば
すべてnext.js（とreact）でサイトを作成することもできそう。
強い可能性を感じました。


