電通総研 テックブログ

電通総研が運営する技術ブログ

Next.js + TypeScript + Docker + GitHub Actions の環境構築

こんにちは。Xイノベーション本部ソフトウェアデザインセンターの陳です。
この記事では Next.js + TypeScript + Docker + GitHub Actionsの環境構築の方法をまとめます。

セットアップ手順

以下のセットアップを行います。 1. create-next-appでNext.jsのプロジェクトを作成 2. 静的分析ツールESLintの設定 3. コードフォーマッターPrettierの設定 4. テストフレームワークのJest、React Testing Libraryの設定 5. Dockerfileの作成 6. GitHub Actionsを利用したビルド、テストの自動実行

バージョン

  • Next.js v12.3.0
  • TypeScript v4.8.3

create-next-appでNext.jsのプロジェクトを作成

create-next-appはNext.jsプロジェクトを自動生成するためのコマンドです。create-next-appを利用すると、Next.js + TypeScriptのプロジェクトのひな形を簡単に作成できます。公式ドキュメントはこちらです。

create-next-appを実行する

以下のコマンドを実行し、プロジェクトを自動生成します。

$ npx create-next-app {プロジェクト名} --ts

yarnを利用することもできます。

$ yarn create next-app {プロジェクト名} --typescript

--tsまた--typescriptを指定することで、TypeScriptを利用するプロジェクトが生成されます。TypeScriptの設定ファイルtsconfig.jsonも自動的に作成されます。

プロジェクトを動かしてみる

作成されたプロジェクトのディレクトリで以下のコマンドを実行すると、Next.jsプロジェクトを開発モードで起動できます。

$ yarn dev

localhost:3000にアクセスするとこちらの画面が表示されます。これでプロジェクトのひな形の作成が完了しました。

静的分析ツールESLintの設定

ESLintを実行する

Next.js v11.0.0からcreate-next-appでプロジェクトを作成すると、ESLintは自動的にインストールされます。
package.jsonScripts"lint": "next lint"がデフォルトで設定されています。以下のコマンドでESLintを実行できます。

$ yarn lint

ESLintのデフォルト構成

Next.jsのESLintのデフォルト構成では、eslint-config-nextの構成が自動的に設定されます。以下のルールセットがeslint-config-nextに含まれるため、インストール、設定する必要はありません。公式ドキュメントはこちらです。

  • eslint-plugin-react
  • eslint-plugin-react-hooks
  • eslint-plugin-next

ESLintの構成をカスタマイズする

.eslintrc.jsonを編集することで、構成をカスタマイズできます。.eslintrc.jsonはESLintに関する設定ファイルです。
以下のようにextendsに記述すれば、eslint:recommendedなど、他の構成を利用できます。またrulesでルールの変更や無効化の設定もできます。

//.eslintrc.json
{
  "extends": [
    "eslint:recommended",
    "next/core-web-vitals",
  ],
  "rules":{
     // 個別のルールを変更、無効にする場合はこちらに追加する
    "no-console": ["warn", { allow: ["warn", "error"] }],
    "sort-imports": "off",
    "import/order": ["error", { alphabetize: { order: "asc" } }],
    "import/no-named-as-default-member": "off",
  }  

コードフォーマッターPrettierの設定

Prettierをインストールする

以下のコマンドでPrettier本体、ESLintと併用する際に必要なライブラリーをインストールします。

$ yarn add -D prettier eslint-config-prettier

.eslintrc.jsonを編集する

.eslintrc.jsonを以下のように設定することで、ESLint と Prettier のコード整形が競合しないようになります。

//.eslintrc.json
{
  "extends": ["next/core-web-vitals", "prettier"],
}

.prettierrcを作成する

コード整形に関する設定をカスタマイズするには、ルートディレクトリで.prettierrcを作成します。 以下のようにカスタマイズ設定ができます。設定の詳細は公式ドキュメントを参照してください。

//.prettierrc
{
  "tabWidth": 2,
  "printWidth": 120,
  "trailingComma": "es5",
  "semi": false,
  "singleQuote": true
}

Prettierを実行する

Prettierを実行するには、package.jsonScriptsに以下のスクリプトを追加します。

//package.json
"scripts": {
  "format": "prettier --write --ignore-path .gitignore ."
}

以下のコマンドでPrettierを実行できます。

$ yarn format

テストフレームワークのJest、React Testing Libraryの設定

Jest、React Testing Libraryをインストールする

Next.jsの公式ドキュメントを参照し、JestおよびReact Testing Libraryをインストール、設定します。

$ yarn add -D jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom

jest.config.jsを作成する

ルートディレクトリでjestの設定ファイルjest.config.jsを作成します。

//jest.config.js
const nextJest = require('next/jest')

const createJestConfig = nextJest({
  dir: './',
})

const customJestConfig = {
  moduleDirectories: ['node_modules', '<rootDir>/'],
  testEnvironment: 'jest-environment-jsdom',
}

module.exports = createJestConfig(customJestConfig)

テストを実行してみる

テストを実行するには、package.jsonscriptsに以下のスクリプトを追加します。

//package.json
"scripts": {
  "test": "jest"
}

サンプルテストを追加します。ルートディレクトリにtestフォルダを作成し、testの配下にindex.test.tsxファイルを作成します。

//index.test.tsx
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
import Home from '../pages'

describe('Home', () => {
  it('renders a heading', () => {
    render(<Home />)
    const heading = screen.getByRole('heading', {
      name: /welcome to next\.js/i,
    })
    expect(heading).toBeInTheDocument()
  })
})

以下のコマンドでテストをします。

$ yarn test

テストが通ったことを確認できます。

Dockerfileの作成

Next.jsをDockerコンテナでデプロイするためのDockerfileのひな形を作成します。

Next.jsのstandaloneモードを有効にする

まず、next.config.jsの設定を修正し、standaloneモードを有効にします。

//next.config.js
const nextConfig = {
  output: 'standalone',
}

Next.js 12の最新バージョンではstandaloneモードを有効にすることで、ビルドサイズを大幅に削減できます。yarn buildにより、.next/standaloneフォルダーが作成され、node_modulesの依存関係を含めたデプロイで必要となる最小限なファイルのみがコピーされます。standaloneに作成されたsever.jsを実行すれば本番アプリケーションを実行できます。

Dockerfileを作成する

Next.jsの公式サンプルを参考しつつ、Distrolessで実行するマルチビルドのDockerfileを作成します。

FROM node:16 AS build
ADD . /app
WORKDIR /app
RUN yarn install --production=false
RUN yarn build

FROM gcr.io/distroless/nodejs:16
WORKDIR /app
COPY --from=build /app/next.config.js ./
COPY --from=build /app/public ./public
COPY --from=build /app/package.json ./package.json
COPY --from=build /app/.next/static ./.next/static
COPY --from=build /app/.next/standalone ./

CMD ["server.js"]

ローカルでDockerコンテナを実行してみる

以下のコマンドでコンテナをビルド、実行できます。

$ docker build -t {イメージ名} .
$ docker run -p 3000:3000 {イメージ名}

GitHub Actionsを利用したビルド、テストの自動実行

pushをトリガーにしてビルドおよびテストを自動実行するGitHub Actionsを作成します。 ルートディレクトリで.github/workflowsフォルダーを作成し、配下にbuild-and-test-on-push.ymlを作成します。

on:
  push:
    branches-ignore:
      - "main"
name: Build and Test on Push
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: docker build
        run: docker build .
  run-tests:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 16
      - name: Install Dependencies
        run: yarn install
      - name: Run test
        run: yarn run test

Dockerを利用しない場合は、yarn buildでビルドを実行できます。

まとめ

今回はNext.jsの環境構築の方法をまとめてみました。
環境構築のほとんどは公式ドキュメントを参考にスムーズにできました。create-next-appを利用すると手動で設定する部分が少なくなるので、便利かと思います。
また、CI環境の構築でDockerfileやGitHub Actionsの作成手順もまとめてみました。興味のある方はぜひ試してみてください。


私たちは同じチームで働いてくれる仲間を探しています。今回のエントリで紹介したような仕事に興味のある方、ご応募お待ちしています。 - ソリューションアーキテクト

執筆:@chen.xinying、レビュー:@handa.kentaShodoで執筆されました