ちょっと話題の記事

WSL2環境でNext.jsに入門してみた

2022.10.29

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

しばたです。

ふとAWS謹製のCloudscapeを使ったサイトを作ってみたくなり、そのためにまずはReactとNext.jsを学んでみることにしました。

私は普段Windows環境を利用しておりWSL2上でNext.jsを実行するための環境を作ってみたのですが、これだけでも地味にハマったのでこの記事で共有したいと思います。

検証環境

本記事の内容は私の普段の開発機(Windows 10 Pro)のWSL2環境(Ubuntu 20.04)で試しています。
Ubuntu 22.04でなくて20.04なのは22.04環境を普段の業務で使っているため避けたのが理由です。本記事の内容でOS依存の部分は無いと思います。

  • ホスト側環境
    • 64 bit版 Windows 10 Professional 21H1
    • Visual Studio Code 1.72.2をインストール済み
  • WSL環境
    • Ubuntu 20.04
    • 新規に環境を作り最新のパッチを適用した状態
    • 記事を書く都合Bashのプロンプト表示(PS1)を少しだけカスタマイズしている

今回WSL環境は新規に作った直後の状態です。
WSL2自体の構築手順は割愛します。

Next.jsを実行するまで

WSL上でNode.jsを実行する手順は以下のドキュメントに記載されています。

本記事でも原則この手順に倣って環境を作ります。

1. nvmのインストール

まず最初にnvmをインストールします。
Microsoftのドキュメントではmasterブランチのインストールスクリプトを実行してますが、個人的に良くないと感じたので公式の手順に倣い最新バージョンのスクリプトを実行する様にしています。

# 本日時点での最新バージョンは Ver.0.39.2
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash

スクリプトがエラー無く完了していれば.bashrcに以下の設定が追記されています。

.bashrc

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

.bashrcを読み直してnvmのバージョンを確認します。

# nvmのバージョン確認
$ source ~/.bashrc
$ nvm --version
0.39.2

2. Node.jsのインストール

この状態ではまだNode.jsはインストールされてませんので、利用したいバージョンのNode.jsをインストールします。
今回は最新のLTSバージョンをインストールするためnvm install --ltsコマンドを実行します。

# 現在最新のLTSバージョンをインストール
nvm install --lts

結果はこんな感じでVer.18.12.0がインストールされました。

# インストール実行
$ nvm install --lts
Installing latest LTS version.
Downloading and installing node v18.12.0...
Downloading https://nodejs.org/dist/v18.12.0/node-v18.12.0-linux-x64.tar.xz...
################################################################################################################# 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v18.12.0 (npm v8.19.2)
Creating default alias: default -> lts/* (-> v18.12.0)

# 結果確認
$ which node
/home/shibata/.nvm/versions/node/v18.12.0/bin/node
$ node --version
v18.12.0

Next.jsチュートリアル

ここからは弊社若槻の記事を参考にNext.jsの公式チュートリアルを試していきます。

先に言っておくと、公式チュートリアルのNext.jsの想定バージョンが古かったため幾つかエラーがでました。
またWSL2環境固有の問題も出たのでその辺も解説します。

ソースコードの保存先

WSLを使って開発を行う場合、ソースコードをWSL内部に保存するかWindows側(/mnt/c/配下)に保存するか悩ましいですが、今回はWSL内部の~/src/に保存しています。
WindowsからWSL内部のファイルを扱う場合は\\wsl$隠し共有フォルダを使うと便利です。

(\\wsl$\WSL名\にアクセスするとWSL内部のファイルを参照できる)

また、今回は検証してませんがソースコードをWindows側に保存すると開発サーバーでホットリロードが利かないことがあるそうです。

Create a Next.js App

まずはチュートリアルにあるサンプルアプリを新規作成します。

# srcディレクトリを作成し移動
mkdir ~/src
cd ~/src

# 新規アプリケーション nextjs-blog を作成
npx create-next-app nextjs-blog --use-npm --example "https://github.com/vercel/next-learn/tree/master/basics/learn-starter"

通常であればエラー無く完了するはずですが、今回は以下の様な依存関係のエラーで終了してしまいました。

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: undefined@undefined
npm ERR! Found: react@17.0.2
npm ERR! node_modules/react
npm ERR!   react@"17.0.2" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^18.0.0-0" from next@13.0.0
npm ERR! node_modules/next
npm ERR!   next@"latest" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See /home/shibata/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/shibata/.npm/_logs/2022-10-29T05_39_15_323Z-debug-0.log

Aborting installation.
  npm install has failed.

調査したところサンプルアプリケーションのpackage.jsonが古いバージョンのReactを参照しているのが悪かった様で、依存するバージョンを更新してやります。

package.json

{
  // ・・・省略・・・

  "dependencies": {
    "next": "latest",
    "react": "17.0.2",
    "react-dom": "17.0.2"
  }
}

を以下の様に更新

package.json

{
  // ・・・省略・・・

  "dependencies": {
    "next": "latest",
    "react": "^18.0.0-0",
    "react-dom": "^18.0.0-0"
  }
}

package.jsonの更新後改めてnpm installしてやります。

# アプリケーションディレクトリ自体は出来ているので移動
$ cd nextjs-blog/

# 更新した依存関係で改めてnpm install
$ npm install

added 19 packages, and audited 20 packages in 7s

2 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

エラー無く完了すればアプリケーションのインストールは完了です。
今回はNext.js Ver.13.0.0がインストールされていました。

npm run devコマンドで開発サーバーを起動してみます。

npm run dev

これで http:// localhost:3000 にアクセスすればアプリケーションが表示される...はずなのですが、私の環境ではダメだったので http://"WSLのeth0のIPアドレス":3000 にアクセスしてやります。
(10/31追記 : 別PCのWSL2環境で試したら http://localhost:3000 でアプリケーションが表示されました)

(WSLのIPアドレスは都度変わります。上図の時は172.22.177.49でした)

一応公式にはWSL2ではlocalhost forwardingはデフォルト有効なハズなのですが、GitHubのIssueもそれなりにあり環境依存の問題が存在する模様です。

Navigate Between Pages

あとはチュートリアル通りにやっていく感じです。

チュートリアルの内容に一部現在のバージョンでは非推奨の記法が残っている様で、ここからはハマった点だけ触れていきます。

next/linkの仕様変更

Next.js 13からnext/linkの仕様が変わったそうで、Linkタグの中にaタグが入っているとエラーになるそうです。

Unhandled Runtime Error
Error: Invalid with <a> child. Please remove <a> or use <Link legacyBehavior>.
Learn more: https://nextjs.org/docs/messages/invalid-new-link-with-extra-anchor

チュートリアルの例にはまだaタグが残っているものがあったため、エラーが出た場合はタグを除外してやると良いです。

Assets, Metadata, and CSS

ここでもLinkタグの中にaタグが入っている例があるのでよしなに対処してやります。

一通り実装してやるとこんな感じになりました。

チュートリアル自体はまだまだ続きますが、本記事としてはここまでにしておきます。

最後に

以上となります。

これでNext.jsを完全に理解したので頑張って自分のサイトを作っていきたいと思います。