空雲 Blog

Eye catchNext.js(12系)によるReact+TypeScript入門 1

publication: 2021/11/22
update:2024/02/20

Next.js(12系)に関して

Next.jsの12系の目玉機能はビルド速度のさらなる高速化です。Babelの代わりにRustで作られたswcを使うことにより、速度向上を図っています。しかしBabelプラグインを使う場合にはswcが無効になってしまうので、全ての場合において恩恵が受けられるわけではありません。現在Next.jsのコミュニティでは、主要なBabelプラグインの機能をswcに移植する作業が進んでおり、例えばTypeScriptのDecorator機能などは、以前はBabelプラグインの設定が必要でしたが、今ではなんの記述もいらずにそのままswcを通して利用可能になっています。

使用する主なライブラリ・フレームワーク

Node.js

JavaScriptを主体とするフレームワークです。このNode.jsを利用することによって、様々なアプリケーションを開発することが出来ます。また、npmというパッケージ管理システムを用いることによって、先人の開発したライブラリやフレームワークを容易に自分のアプリケーションに組み込むことが可能です。

TypeScript

JavaScriptのスーパーセットとして型の概念が導入されたプログラミング言語です。基本的には実行前にJavaScriptに変換してから使用することになります。TypeScriptによる型の概念は強力で、単純なエラーチェックだけで無く、プログラミングエディタと連携した入力補完がサポートされます。それによって得られる開発の効率化は圧倒的です。

React.js

仮想DOMを用いたUI構築用のライブラリです。TypeScriptとの相性が良く、SPA(SinglePageApplication)を効率的に開発できます。

Next.js

Reactベースのフレームワークです。主にフロントエンド開発で用いられますが、バックエンドAPIを作成することも可能です。導入が容易で、React.js単体で開発環境を構築するよりもNext.jsから使用した方が、初期設定などの手間が削減できます。また、開発時に使用するホットリロード(プログラム修正後のリロード)が強力で、修正確認が圧倒的な速度で行えます。

基本用語解説

ページ切り替えの種類

SPA(Single Page Application)

Webページの更新をHTMLデータをまるごと再送することなく、部分的な書き換えで行う方式です。仮想的にページを切り替えたように見せかけるだけであり、データ送受信時にUIの操作の中断が最小限で済むので、ユーザーの体験が向上します。

MPA (Multi Page Application)

昔ながらの方式です。データの送受信時にHTMLデータをまるごと切り替えます。この動作によってデータの送受信が終わるまでUIが中断されます

ページレンダリングの種類

CSR (Client Side Rendering)

特に細工せずにReact.jsをフレームワーク無しで使用すると、この方式になります。Next.jsにこのモードはありませんが、細工することでそれに近い状態にすることは可能です。

JavaScriptを呼び出す最小限のHTMLだけ返して、後はクライアント側でUIを構築します。

SSR (Server Side Rendering)

Next.jsの標準動作です。初期ページのHTMLをサーバ側で作成し、それ以降の動作をクライアントで行います。Next.jsがサーバ上で稼働している必要があります。

リモートからデータをとってくるような構造が必要な場合、サーバとクライアントの差異があるので、特に認証の有無によって挙動が異なるようなページを作成する場合は辛みが増えていきます。

SG (Static Generation)

Next.jsのエクスポート機能を利用して、静的なページを作成しておくことで利用出来ます。この時点でページの生成は済んでいるため、エクスポートしたコンテンツを一般的なWebサーバに載せておけばNext.jsを必要とせずに動作させることが出来ます。

ビルド時のレンダリングに使用しているデータの更新が発生すると、再ビルドが必要となります。逆にビルド時にそういったデータを除外して、擬似的にCSRのような状態を作り、再ビルドの必要性をなくすという方法もあります。

ISR (Incremental Static Regeneration)

必要に応じてSSGを行い、結果をキャッシュする方式です。ビルドの時間を短縮できます。この機能を利用するにはNext.jsがサーバ上で稼働している必要があります。

環境構築

開発に必要なアプリケーション

Node.js

https://nodejs.org/ja/

基本的にはTLS版を入れておけば問題ありません。

Visual Studio Code(推奨)

https://azure.microsoft.com/ja-jp/products/visual-studio-code/

TypeScriptの機能追加とともにVSCodeも更新されるのでおすすめしておきます。

Next.jsの環境構築

適当な場所にフォルダを作成しVSCodeで開いてください。

パッケージ管理ツールのインストール

1npm -g i yarn

パッケージ管理はnpmだけでも良いのですが、yarnを使って解説している記事が多いので、最初に入れておきましょう。

開発に必要なパッケージ

1yarn add next react react-dom
2yarn add -D typescript @types/node @types/react

-Dが付いていないものはビルド後の動作に必要なもので、付いているものはビルド時に必要になるものです。サーバーに

最初のプログラム

ファイルの作成

src/pages/index.tsx

1const Page = () => <div>今日は世界!</div>;
2export default Page;
3

実行

1yarn next

Next.jsを開発モードで起動します。
デフォルトではポート3000で待機状態になります。

確認

{"width":"642px","height":"329px"}

npmスクリプトのコマンドの作成

package.json

1{
2 "scripts": {
3 "dev": "next",
4 "start": "next start",
5 "build": "next buid",
6 "export": "next export"
7 },
8 "devDependencies": {
9
10 },
11 "dependencies": {
12
13 }
14}

以上のようにscriptsを設定しておくと、

  • 開発モードで起動
    yarn dev

  • buildしたプログラムを起動
    yarn start

  • プログラムのビルド
    yarn build

  • buildしたプログラムをSSG用に吐き出す
    yarn export

という形の短縮形で起動したり、VSCodeのnpmスクリプト欄からマウスクリックで実行できます。

tsconfig.jsonの設定変更

Next.jsを起動するとtsconfig.jsonが自動生成されます。その際に、変更を推奨する内容を紹介します。

初期設定

1{
2 "compilerOptions": {
3 "target": "es5",
4 "lib": [
5 "dom",
6 "dom.iterable",
7 "esnext"
8 ],
9 "allowJs": true,
10 "skipLibCheck": true,
11 "strict": false,
12 "forceConsistentCasingInFileNames": true,
13 "noEmit": true,
14 "esModuleInterop": true,
15 "module": "esnext",
16 "moduleResolution": "node",
17 "resolveJsonModule": true,
18 "isolatedModules": true,
19 "jsx": "preserve"
20 },
21 "include": [
22 "next-env.d.ts",
23 "**/*.ts",
24 "**/*.tsx"
25 ],
26 "exclude": [
27 "node_modules"
28 ]
29}

推奨変更内容

以下のように設定を変更します。これでTypeScriptの文法チェックが厳格になります。

1{
2 "compilerOptions": {
3 "target": "es5",
4 "lib": [
5 "dom",
6 "dom.iterable",
7 "esnext"
8 ],
9 "allowJs": true,
10 "skipLibCheck": true,
11 "strict": true, // ここを変更する
12 "forceConsistentCasingInFileNames": true,
13 "noEmit": true,
14 "esModuleInterop": true,
15 "module": "esnext",
16 "moduleResolution": "node",
17 "resolveJsonModule": true,
18 "isolatedModules": true,
19 "jsx": "preserve"
20 },
21 "include": [
22 "next-env.d.ts",
23 "**/*.ts",
24 "**/*.tsx"
25 ],
26 "exclude": [
27 "node_modules"
28 ]
29}