Next.js最速セットアップ

11 min read読了の目安(約10700字

はじめに

最近Next.jsが話題になることや、使われることが増えてきましたね。
個人的にも実務でも個人開発でも愛用しています。
そこでこの記事では、典型的なNext.jsプロジェクトのセットアップ方法についてまとめてみたいと思います。

全体の流れ

  1. Create Next App
  2. .prettierrcを追加
  3. 不要なファイルを削除
  4. srcディレクトリを追加
  5. TypeScript導入
  6. Chakra UI導入
  7. スナップショットテスト導入
  8. GitHub ActionsでCI導入
  9. Renovate導入

Create Next App

まずはCreate Next App[1]で雛形を作成しましょう。
ターミナルで以下のコマンドを入力します。

npx create-next-app <プロジェクト名>

必要であればこの段階でGitHubなどのリモートリポジトリと連携してください。(後にGitHub ActionsでCIを導入するところがあるので、導入したい方は連携しておいてください。)

またその後にデプロイまで行ってしまってもよいかもしれません。

ちなみにNext.jsを使うならデプロイ先はVercel[2]がおすすめです。
GUIでポチポチやるだけで簡単にNext.jsプロジェクトをデプロイでき、その後は特定のブランチ(デフォルトはmainブランチ)にpushすると自動的にデプロイされるため、CD環境も整備されます。
さらにPRごとに自動的にプレビュー環境を作成してくれるため、こちらも非常に便利です。

.prettierrcを追加

フォーマットツールのPrettierを動かすための設定ファイルである.prettierrcをルートディレクトリ直下に追加します。

.prettierrc
{
  "singleQuote": true,
  "semi": false
}

設定内容はお好みで変更・追加してください。
またこの記事ではVSCodeの使用を前提としています。VSCode用のPrettierプラグインをインストールしていない方はそちらもインストールしてください。

不要なファイルを削除

現段階でyarn devするとNext.jsのデフォルトページが表示されますが、このページは必要ないので諸々削除しておきましょう。
削除対象は以下です。

pages/_app.js
- import '../styles/globals.css'
-
function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}
pages/api/hello.js
ファイルごと削除
pages/index.js
- import Head from 'next/head'
- import styles from '../styles/Home.module.css'
-
export default function Home() {
  return (
-    <div className={styles.container}>
-      <Head>
-        <title>Create Next App</title>
-        <link rel="icon" href="/favicon.ico" />
-     </Head>
-
-      <main className={styles.main}>
-        <h1 className={styles.title}>
-          Welcome to <a href="https://nextjs.org">Next.js!</a>
-        </h1>
-
-        <p className={styles.description}>
-          Get started by editing{' '}
-          <code className={styles.code}>pages/index.js</code>
-        </p>
-
-        <div className={styles.grid}>
-          <a href="https://nextjs.org/docs" className={styles.card}>
-            <h3>Documentation &rarr;</h3>
-            <p>Find in-depth information about Next.js features and API.</p>
-          </a>
-
-          <a href="https://nextjs.org/learn" className={styles.card}>
-            <h3>Learn &rarr;</h3>
-            <p>Learn about Next.js in an interactive course with quizzes!</p>
-          </a>
-
-          <a
-            href="https://github.com/vercel/next.js/tree/master/examples"
-            className={styles.card}
-          >
-            <h3>Examples &rarr;</h3>
-            <p>Discover and deploy boilerplate example Next.js projects.</p>
-          </a>
-
-          <a
-            href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
-            className={styles.card}
-          >
-            <h3>Deploy &rarr;</h3>
-            <p>
-              Instantly deploy your Next.js site to a public URL with Vercel.
-            </p>
-          </a>
-        </div>
-      </main>
-
-      <footer className={styles.footer}>
-        <a
-          href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
-          target="_blank"
-          rel="noopener noreferrer"
-        >
-          Powered by{' '}
-          <img src="/vercel.svg" alt="Vercel Logo" className={styles.logo} - />
-        </a>
-      </footer>
+    <div>
+      <h1>Hello World!</h1>
    </div>
  )
}
public/favicon.ico
ファイルごと削除
代替ファイルがあれば差し替えでも可
public/vercel.svg
ファイルごと削除
styles/Home.module.css
ファイルごと削除
styles/globals.css
ファイルごと削除

srcディレクトリを追加

Next.jsはsrcディレクトリに対応しているので、srcディレクトリをルートディレクトリ直下に作成しpagesディレクトリをその中に移動しましょう。
ただしこれは好みもあると思うのでやらなくても問題ありませんが、これ以降の記事内のディレクトリ構成については適宜読み替えてください。

TypeScript導入

ここでTypeScriptを導入します。
Next.jsではプロジェクト内のファイルの拡張子をts、またはtsxにした状態でyarn devを実行すると、tsconfig.jsonなどの必要なファイルが自動生成されるようになっています。便利ですね。
まずはターミナルで以下のコマンドを入力して、TypeScript導入に必要なパッケージをインストールします。

yarn add --dev typescript @types/react @types/node

次にsrc/pages/_app.jssrc/pages/index.jsの拡張子をtsxにリネームし、yarn devを実行してください。

最後に一部ファイルを修正します。(tsconfig.jsonの設定内容はお好みで変更・追加してください。)

src/pages/_app.tsx
+ import { AppProps } from 'next/app'

+ export default function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}
tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
-    "strict": false,
+    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
-    "jsx": "preserve"
+    "jsx": "preserve",
+    "baseUrl": "./"
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

Chakra UI導入

Chakra UI[3]はUIコンポーネントライブラリです。
他に有名なUIコンポーネントライブラリいえばMaterial UIがありますね。
Chakra UIは実務で初めて使って以来お気に入りで個人開発でも愛用しています。
いくつかよいと思う点をあげると以下のような点があげられます。

  • Tailwind CSSインスパイアなユーティリティファーストのインターフェース
  • Pure TypeScriptなので補完もバッチリ
  • Stackコンポーネントのようなレイアウトが組みやすくなるコンポーネントの存在
  • デフォルトでもシンプルで癖のないデザイン
  • カスタマイズ性が非常に高く、デザインシステムの構築も可能であること

他にもあるのですが、もはやこれなしでスタイリングしたくないレベルでお気に入りです。
詳細を書きすぎると本題から外れるのでこの辺にしておきますが、おすすめなのでぜひ使ってみてください。

さて本題に戻ってChakra UIを導入していきましょう。
まずはターミナルで以下のコマンドを入力して、Chakra UI導入に必要なパッケージをインストールします。
公式のGetting Startedでは@chakra-ui/iconsは含まれておらず、インストールしなくても動作に問題はないのですが、よく使うため最初からインストールしています。

yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion @chakra-ui/icons

次にChakra Providerのセットアップを行います。

src/pages/_app.tsx
+ import { ChakraProvider } from '@chakra-ui/react'
import { AppProps } from 'next/app'

export default function MyApp({ Component, pageProps }: AppProps) {
-  return <Component {...pageProps} />
+  return (
+    <ChakraProvider>
+      <Component {...pageProps} />
+    </ChakraProvider>
+  )
}

最後にsrc/pages/index.tsxで実際にChakra UIを使用して動作確認を行います。yarn devしてきちんとスタイルが当たっていればOKです。

src/pages/index.tsx
+ import { Box, Heading } from '@chakra-ui/react'
+ import React from 'react'

+ export default function HomePage() {
  return (
-    <div>
-      <h1>Hello World!</h1>
-    </div>
+    <Box>
+      <Heading>Hello World!</Heading>
+    </Box>
  )
}

スナップショットテスト導入

フロントエンドのライブラリはアップデートが多いので、スナップショットテストを導入してライブラリアップデート時の安心感を手に入れておきましょう。

スナップショットテストを導入するためにJestとReact Testing Libraryを使用します。まずはターミナルで以下のコマンドを入力して、必要なパッケージをインストールします。

yarn add --dev jest @types/jest ts-jest @testing-library/react

次にテスト用のnpm scriptsをpackage.jsonに追加します。
yarn testはJestによるテスト実行用、yarn test:usはUI変更などでスナップショットに変更があった場合のスナップショット更新用です。

"scripts": {
    "dev": "next dev",
    "build": "next build",
-    "start": "next start"
+    "start": "next start",
+    "test": "jest",
+    "test:us": "jest --updateSnapshot"
  },
"dependencies": {
  "@chakra-ui/icons": "^1.0.6",

さらにJest用に諸々設定ファイルを追加します。

jest.config.json
+ module.exports = {
+  roots: ['<rootDir>/src'],
+  transform: {
+    '^.+\\.(ts|tsx)$': 'ts-jest',
+  },
+  // see https://github.com/zeit/next.js/issues/8663
+  globals: {
+    'ts-jest': {
+      tsconfig: '<rootDir>/tsconfig.jest.json',
+    },
+  },
+  // see https://stackoverflow.com/questions/50863312/jest-gives-cannot-find-module-when-importing-components-with-absolute-paths
+  moduleDirectories: ['node_modules', '<rootDir>'],
+ }
tsconfig.jest.json
+ {
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "jsx": "react"
+  }
+ }

設定内容はお好みで変更・追加してください。
ここではJestの設定の詳細について解説することは避けますが、必要最低限の設定をしているつもりです。
また設定しつつハマった設定についてはコメントに参考リンクを書いているので参考にしてみてください。

次にReact Testing LibraryのcustomRender[4]を定義します。
これはChakra UIでChakra Providerを使用している関係上必要になります。

src/lib/test-utils.tsx
+ import { ChakraProvider } from '@chakra-ui/react'
+ import { render } from '@testing-library/react'
+ import React from 'react'

+ const AllTheProviders = ({ children }: { children: JSX.Element }) => {
+  return <ChakraProvider>{children}</ChakraProvider>
+ }

+ const customRender = (ui: JSX.Element, options?: any) =>
+  render(ui, { wrapper: AllTheProviders, ...options })

+ export * from '@testing-library/react'
+ export { customRender as render }

これでスナップショットテストを書く準備が整いました。さっそく以下のようにsrc/pages/index.tsxのスナップショットテストを書いてみましょう。

src/__tests__/pages/index.test.tsx
+ import React from 'react'
+ import { render } from 'src/lib/test-utils'
+ import HomePage from 'src/pages'
+
+ test('ホームページ', () => {
+  const { container } = render(<HomePage />)
+  expect(container).toMatchSnapshot()
+ })

この状態でターミナルで以下のコマンドを入力して、テストを実行します。

yarn test

するとJestによるテストが実行され、src/__tests__/pages/__snapshots__/index.test.tsx.snapが自動生成されます。これでスナップショットテストは完了です。

今回はスナップショットテストのみを行っていますが、通常のロジックのテストも行えるので、テストが必要なロジックが出てきたらぜひテストを書いてみてください。

GitHub ActionsでCI導入

せっかくスナップショットテストを導入したので、CIでテストを実行できるようにしてみましょう。
今回はGitHub ActionsでCIを導入してみます。

以下の設定ファイルを追加してください。

.github/workflows/test.yml
+ name: test
+
+ on: push
+
+ jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-node@v2
+        with:
+          node-version: 14.x
+      - uses: actions/cache@v2
+        with:
+          path: ~/.cache/yarn
+          key: ${{ runner.os }}-yarn-${{ hashFiles(format('{0}{1}', github.workspace, '/yarn.lock')) }}
+          restore-keys: ${{ runner.os }}-yarn-
+      - run: yarn install --frozen-lockfile --prefer-offline
+      - run: npx tsc --noEmit
+      - run: yarn test

設定内容はお好みで変更・追加してください。
この設定ではnpx tsc --noEmitで型チェックを、yarn testで先ほど導入したJestによるテストを行うようにしています。

この状態でGitHubでPRを作成するとCIが走ることを確認できると思います。

Renovate導入

最後にRenovateを導入してライブラリのアップデートを自動通知してもらいましょう。
まずは公式ドキュメント[5]を参考にRenovateのGitHub Appをインストールしてください。

インストールが完了したら以下の設定ファイルを追加してください。

.github/renovate.json
+ {
+  "extends": ["config:base"],
+  "labels": ["dependencies"],
+  "packageRules": [
+    {
+      "depTypeList": ["devDependencies"],
+      "automerge": true
+    }
+  ],
+  "timezone": "Asia/Tokyo",
+  "schedule": ["every weekend"]
+ }

設定内容はお好みで変更・追加してください。
この設定ではdevDependenciesのライブラリについてはCIが通ったら自動的にマージされます。
またそれ以外のライブラリのアップデートについては週末に自動通知がくるようになっています。

おわりに

以上で典型的なNext.jsプロジェクトのセットアップは完了です。
ところどころ足りないものもあるかもしれませんが(es-lintとか…)、最低限のセットアップはできたかと思います。
少し長くなりましたが、参考になれば幸いです。
それではよいNext.jsライフを!

脚注
  1. https://nextjs.org/docs/api-reference/create-next-app ↩︎

  2. https://vercel.com/ ↩︎

  3. https://chakra-ui.com/ ↩︎

  4. https://testing-library.com/docs/react-testing-library/setup/ ↩︎

  5. https://docs.renovatebot.com/install-github-app/ ↩︎