Next.jsのCustom Server(Express)を利用してTypeScriptファイル保存時にnodemonで再起動するための手順

Node.jsNext.js環境構築TypeScript
Next.jsのCustom Server(Express)を利用してTypeScriptファイル保存時にnodemonで再起動するための手順
Memo

Next.jsのCustom Server(Express)を利用してTypeScriptファイル保存時にnodemonで再起動するための手順をメモしました。

nodemon

nodemonとは?

nodemonとはオープンソースで開発されている、ソースを監視して自動でサーバーを再起動してくれるツールです。 nodeの代わりにnodemonを使ってコードを走らせると、コードの変更時にプロセスが自動で再起動するため開発を便利にサポートしてくれます。

nodemonの特徴

  • 監視するディレクトリ、拡張子を指定したり除外したりすることができる
  • ts-nodeを連携して利用することができTypeScriptのプロジェクトでも利用可能
  • Chokidarのポーリングを有効にして一部のネットワーク環境(マウントされたドライブなど)でも利用が可能

公式サイト

Github

やること

環境

  • yarn 1.22.10
  • Node 14.15.3
  • Next.js 10.2.3

ファイル操作で利用する Unix コマンドについて

基本的なディレクトリ作成やファイル操作は Unix コマンドを利用します。
Unix コマンドについて詳しくはこちらの記事を参考にしてください。

事前準備

Node.js 環境が必要

事前準備として Node.js が利用できる環境で実施します。
Node.js の環境の構築について詳しくはこちらの記事を参考にしてください。

yarn コマンドのインストール

事前準備として Yarn が利用できる環境で実施します。
Yarn コマンドのインストールについて詳しくはこちらの記事を参考にしてください。

CustomServerサンプルプロジェクトの作成

プロジェクトディレクトリを作成

~/custom-server-sampleというプロジェクトディレクトリを作成します。

terminal
$ mkdir ~/custom-server-sample

プロジェクトディレクトリへ移動

作成した~/ssl-sample ディレクトリへ移動します。

terminal
$ cd ~/custom-server-sample

yarn を初期化をして package.json を作成

yarn でプロジェクトの初期化を行います。
npm で実施する方は必要に応じて変更してください。

terminal
$ yarn init -y yarn init v1.22.10 warning The yes flag has been set. This will automatically answer yes to all questions, which may have security implications. success Saved package.json ✨ Done in 0.08s.

必要なパッケージのインストール

必要なパッケージ

各種のパッケージをインストールします。

  • next
  • react
  • react-dom
  • expres
  • nodemon
  • @types/express
  • typescript
  • @types/node
  • @types/react
  • @types/react-dom
  • ts-node

パッケージのインストール

yarn addコマンドで必要パッケージをインストールします。

terminal
$ yarn add next react react-dom express

開発に関連するパッケージのため -Dオプションを付与しています。

$ yarn add -D nodemon @types/express typescript @types/node @types/react @types/react-dom ts-node

インストールしたパッケージを確認

package.json を開きインストールされたパッケージを確認します。

  "dependencies": {
    "express": "^4.17.1",
    "next": "^11.0.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  },
  "devDependencies": {
    "@types/express": "^4.17.12",
    "@types/node": "^16.0.0",
    "@types/react": "^17.0.13",
    "@types/react-dom": "^17.0.8",
    "nodemon": "^2.0.9",
    "ts-node": "^10.0.0",
    "typescript": "^4.3.5"
  }

tsconfig.json を作成

プロジェクトルートへ tsconfig.json を作成します。

terminal
$ vi tsconfig.json

tsconfig.server.json の設定例

tsconfig.server.json
{ "compilerOptions": { "target": "es2020", "module": "commonjs", "lib": [ "es2020" ], "sourceMap": true, "outDir": "./dist", "rootDir": "./src", "strict": true, "moduleResolution": "node", "baseUrl": "src", "esModuleInterop": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": [ "src/**/*" ], "exclude": [ "dist", "node_modules" ], "compileOnSave": false }

ts-config のオプションはこちらの記事を参考にしてください

アプリケーションの構築

ソースディレクトリの作成

プロジェクトルートへsrcディレクトリを作成します。

terminal
$ mkdir src

serverディレクトリの作成

srcディリレクトリ内へserverディレクトリを作成します。

terminal
$ mkdir src/server

アプリケーションファイルの作成

作成したserverディレクトリへ index.ts を追加します。

terminal
$ vi src/server/index.ts

必要モジュールをインポート

import 文で nextexpress をインポートします。

src/server/index.ts
import express from "express"; import next from "next";

Next.jsの初期化

devは開発用途の環境のためとりあえずtrueへ設定します。 dirはpagesを配置するディレクトリのため同階層に設置する形で指定します。

src/server/index.ts
const nextApp = next({ dev: true, dir: "./" }); const handle = nextApp.getRequestHandler();

expressの初期化

nextApp.prepare()の中でexpressの初期化を実施します。

src/server/index.ts
nextApp.prepare().then(() => { const expressApp = express(); })

カスタムエンドポイント

APIなどのカスタムエンドポイントはここで設定します。

nextApp.prepare().then(() => {
  const expressApp = express();
  expressApp.use(express.json());
  expressApp.get("/api/hoge", (req: express.Request, res: express.Response): void => {
    res.json({
      result: true,
    });
  });
})

サーバー起動の設定

カスタムエンドポイント以外のリクエストをnextへ流すのと
サーバーの待ち受けポートの設定を行います。

src/server/index.ts
const port = 8080; nextApp.prepare().then(() => { expressApp.get("*", (req: any, res: express.Response): Promise<void> => { return handle(req, res); }); expressApp.listen(port, (err) => { if (err) throw err console.log(`> Ready on http://localhost:${port}`) }) })

トップページの作成

pagesディレクトリの作成

srcディリレクトリ内へpagesディレクトリを作成します。

terminal
$ mkdir src/pages

アプリケーションファイルの作成

作成したpagesディレクトリへ index.tsxを追加します。

terminal
$ vi src/pages/index.tsx

メッセージを表示

Hello!とメッセージを表示させます。

src/pages/index.tsx
export default function Home() { return ( <div> <h1>Hello!</h1> </div> ); }

nodemonの設定

nodemon.jsonを作成

プロジェクトルートへnodemon.jsonを作成します。

{
  "watch": ["src/server"],
  "project": "tsconfig.server.json",
  "exec": "ts-node src/server/index.ts",
  "ext": "js ts"
}

npm scripts へ起動コマンドの追加

実行するコマンドを追記します。

package.json

package.json
"scripts": { "dev": "nodemon" },

nodemonの動作の確認

アプリケーションを起動

yarn devコマンドを実行します。

terminal
$ yarn dev yarn run v1.22.10 $ nodemon [nodemon] 2.0.9 [nodemon] to restart at any time, enter `rs` [nodemon] watching path(s): src/server/**/* [nodemon] watching extensions: js,ts [nodemon] starting `ts-node src/server/index.ts` info - Using webpack 5. Reason: Enabled by default https://nextjs.org/docs/messages/webpack5 We detected TypeScript in your project and reconfigured your tsconfig.json file for you. Strict-mode is set to false by default. The following suggested values were added to your tsconfig.json. These values can be changed to fit your project's needs: - allowJs was set to true - noEmit was set to true The following mandatory changes were made to your tsconfig.json: - resolveJsonModule was set to true (to match webpack resolution) - isolatedModules was set to true (requirement for babel) - jsx was set to preserve (next.js implements its own optimized jsx transform) event - compiled successfully > Ready on http://localhost:8080

保存して再起動を確認

src/server/index.tsを保存するとnodeが再度実行されます。

[nodemon] restarting due to changes...
[nodemon] starting `ts-node src/server/index.ts`
info  - Using webpack 5. Reason: Enabled by default https://nextjs.org/docs/messages/webpack5
event - compiled successfully
> Ready on http://localhost:8080

終わりに

最後までご覧いただきありがとうございます。
この記事ではNext.jsのCustom Server(Express)を利用してTypeScriptファイル保存時にnodemonで再起動するための手順について紹介させていただきました。

これからも皆様の開発に役立つ情報を提供していきたいと考えています。
今後ともよろしくお願いいたします。