ロゴテキスト ロゴ

    Next.jsのプロジェクトを始める時にやっていること

    Next.jsのプロジェクトを始める時にやっていること

    Next.jsのプロジェクトを始める際にテンプレート的に行っていることを記載します。

    ざっくり以下の手順で進めます。

    1. 前準備
    2. Next.jsの初期化
    3. Prettierの設定
    4. ESLintの設定

    検証した環境

    1 Next.js 14.1.3
    2 pnpm 8.15.3
    3 volta 1.1.1
    4 prettier 3.2.5

    前準備

    GitHubの準備

    GitHubでプロジェクトを前もって作成します。

    ここではnextjs-baseという名前で作成しました。

    GitHubにプロジェクトを作成


    私はghqを使ってリポジトリ管理をしているのでghqを使ってcloneします

    ghq get git@github.com:yuki-takara/nextjs-base.git


    作成したリポジトリのフォルダでgit関連の初期化を行います

    # 作成したリポジトリのフォルダに移動
    cd {作成したリポジトリのフォルダ}
     
    # GitHub上に表示されている初期化のコマンドをそのままコピペ
    echo "# nextjs-base" >> README.md
    git init
    git add README.md
    git commit -m "first commit"
    git branch -M main
    git remote add origin git@github.com:yuki-takara/nextjs-base.git
    git push -u origin main

    first commitがコミット出来て、GitHub上に連携出来ていればOK!

    $ git log --oneline
    26eea93 (HEAD -> main, origin/main) first commit

    GitHubへの連携も完了

    nodeの設定

    せっかくなのでnodeのバージョン管理としてvoltaを利用してみます!



    voltaを使う上でpackage.jsonを用意します

    pnpm init

    pakage.jsonが作られるので最低限のものを残しつつ編集します

    package.json
    {
      "name": "nextjs-base",
      "version": "0.0.1",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "license": "ISC"
    }


    voltaの記述を追記、記述時点のLTSを記載しました

    package.json
    {
      "name": "nextjs-base",
      "version": "0.0.1",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "license": "ISC",
      "volta": {
        "node": "20.11.1"
      }
    }
    $ node -v
    v20.11.1

    package.jsonに記載したvoltaでのバージョンが使えるようになりました!

    Next.jsの初期化

    公式ページに従って作成します

    https://nextjs.org/docs/getting-started/installation


    pnpm dlx create-next-app@latest

    聞かれる質問は全てデフォルトのまま進めました

    ✔ What is your project named? … my-app
    ✔ Would you like to use TypeScript? … Yes
    ✔ Would you like to use ESLint? … Yes
    ✔ Would you like to use Tailwind CSS? … Yes
    ✔ Would you like to use `src/` directory? … Yes
    ✔ Would you like to use App Router? (recommended) …  Yes
    ✔ Would you like to customize the default import alias (@/*)? … No
    Next.jsの初期化を行う


    階層を深くする理由が特にないので、

    my-appとして作成した中身を隠しファイルも含めて移動します

    初期化コマンドで作成したフォルダの中身をルートフォルダに移動

    package.jsonも上書きされるのでnameやvoltaの記述を更新します

    package.json
    {
      "name": "nextjs-base",
      "version": "0.0.1",
      "private": true,
      "scripts": {
        "dev": "next dev",
        "build": "next build",
        "start": "next start",
        "lint": "next lint"
      },
      "dependencies": {
        "react": "^18",
        "react-dom": "^18",
        "next": "14.1.3"
      },
      "devDependencies": {
        "typescript": "^5",
        "@types/node": "^20",
        "@types/react": "^18",
        "@types/react-dom": "^18",
        "autoprefixer": "^10.0.1",
        "postcss": "^8",
        "tailwindcss": "^3.3.0",
        "eslint": "^8",
        "eslint-config-next": "14.1.3"
      },
      "volta": {
        "node": "20.11.1"
      }
    }

    dev環境が起動することを確認していきます

    $ pnpm run dev
     
    > nextjs-base@0.0.1 dev /Users/yuu/src/github.com/yuki-takara/nextjs-base
    > next dev
     
        Next.js 14.1.3
       - Local:        http://localhost:3000

    http://localhost:3000 にアクセスして開発環境が動作しました!

    開発環境の起動を確認

    Prettierの設定

    FormatterにPrettierを導入します


    Biome も話題に上がってますが、まだPrettierが一般的なイメージが強いためここではPrettierにしました。

    pnpm add -D prettier


    Prettierの設定ファイルは .prettierrc .prettierrc.js 等、様々な形式で用意が可能です。

    ここでは prettier.config.js として作成していきます

    prettier.config.js
    module.exports = {
      endOfLine: "lf",
      semi: false,
      singleQuote: true,
      printWidth: 100,
      arrowParens: 'avoid',
    }

    Prettierの設定は好みが出るところで私は↑のような設定することが多いです。


    「コメントが出来る」 という点で .js.yml のファイル種類を選ぶのが理想形なイメージがあり私は .prettierrc.js とする事が多かったのですが、

    海外の方のリポジトリを見る限り prettier.config.js とされている事が多いように感じました 📝



    Googleのコーディングガイドを参考にすると以下のようになるそうです

    (ChatGPT先生にお願いしたら作ってくれました。ありがた過ぎる。。)
    prettier.config.js
    module.exports = {
      // Googleスタイルガイドに従い、インデントには2つのスペースを使用
      tabWidth: 2,
      // セミコロンを省略せずに使用
      semi: true,
      // シングルクォートを使用
      singleQuote: true,
      // オブジェクトのプロパティのキーが必要な場合のみクォートを使用
      quoteProps: 'as-needed',
      // 配列やオブジェクトの要素の最後にもカンマを付ける(ES5で有効な場合のみ)
      trailingComma: 'es5',
      // 複数行の場合、配列の括弧内に改行を入れる
      bracketSpacing: true,
      // アロー関数のパラメータが1つのみの場合も括弧を付ける
      arrowParens: 'always',
      // HTMLやJSXの閉じタグを改行しない
      jsxBracketSameLine: false,
      // HTMLやJSXの属性にシングルクォートを使用
      jsxSingleQuote: true,
      // ファイルの末尾に改行を入れる
      endOfLine: 'lf',
    };


    最後にPrettierを全体的に実行して完了です!

    pnpmのlockファイルがYAMLなので拡張子を指定してみました
    pnpm dlx prettier --write "**/*.{ts,tsx,json,mjs,css}"
    Prettierをプロジェクト全体に実行

    ESLintの設定

    FormatterのPrettierでカバー出来ない部分はESLintで補ってもらいます



    ここでは以前書いた記事の中から2つを取り入れることにしました

    • eslint-config-prettier
    • eslint-plugin-unicorn

    少し前は airbnb を入れるのが主流だったイメージが強いのですが、

    最近はそんな事もなくなってきている感覚があったため↑に記載した2つにしました

    .eslintrc.json → .eslintrc.js

    Prettierと同じく.jsonだとコメントが出来ないため、

    ESLintの設定ファイルの拡張子を前もって .js に変更します

    .eslintrc.json
    {
      "extends": "next/core-web-vitals"
    }
    .eslintrc.js
    module.exports = {
      extends: 'next/core-web-vitals',
    }

    eslint-config-prettier

    PrettierとESLintの設定がバッティングしないようにします

    pnpm add -D eslint-config-prettier
    .eslintrc.js
    module.exports = {
      extends: ['next/core-web-vitals', 'prettier'],
    }

    設定を更新してLintで怒られないことを確認します

    $ pnpm run lint
    > next lint
     
     No ESLint warnings or errors

    eslint-plugin-unicorn

    公式ページ

    More than 100 powerful ESLint rules

    と書かれているように、ESLintをより強力にするルール集です!

    More than 100 powerful ESLint rules
    3.9k
    353
    JavaScript

    1度使ってみたらハマってしまってほぼ全てのプロジェクトに導入しています 😂



    pnpm add -D eslint-plugin-unicorn
    .eslintrc.js
    module.exports = {
      extends: ['next/core-web-vitals', 'plugin:unicorn/recommended', 'prettier'],
    }

    設定を更新してLintで怒られ、、ない?

    $ pnpm run lint
    > next lint
     
     No ESLint warnings or errors

    以前だとこの段階で怒られていた記憶があるものの

    これだとちゃんと適用出来ているか分からないのでちゃんと効いているか確認していきます


    eslint-plugin-unicorn は厳しいルールも多いため、

    適宜ルールの変更・停止等行ってプロジェクトに合わせていく必要が出てきます。


    プロジェクト途中で導入するとLintの対応だけでかなりの時間を使うケースも往々にして起こり得ます

    ESLint周りの修正

    SampleComponent というコンポーネントを追加し、page.tsxで読み込ませます

    src/components/SampleComponents.tsx
    'use client'
     
    import { useState } from 'react'
     
    export function SampleComponent() {
      const [val, setVal] = useState(0)
     
      return <div>{val}</div>
    }
    src/app/page.tsx
    import Image from 'next/image'
    import { SampleComponent } from '@/components/SampleComponent'
     
    export default function Home() {
      return (
        <main className="flex min-h-screen flex-col items-center justify-between p-24">
          <SampleComponent />
          ・・・


    これでESLintを実行してみるとバッチリ怒られます

    $ pnpm run lint
    > next lint
     
    ./src/components/SampleComponent.tsx
    1:1  Error: Filename is not in kebab case. Rename it to `sample-component.tsx`.  unicorn/filename-case
    6:10  Error: The variable `val` should be named `value`. A more descriptive name will do too.  unicorn/prevent-abbreviations
    6:15  Error: The variable `setVal` should be named `setValue`. A more descriptive name will do too.  unicorn/prevent-abbreviations
    • 1はファイル名をケバブケースにしよう
    • 2,3はもっと分かりやすい名前にしよう

    というものです。



    ファイル名はケバブケースではなくキャメルケースで書くことも多いためルール自体offにし、

    もう1つの指摘内容は修正していきます

    .eslintrc.js
    module.exports = {
      extends: ['next/core-web-vitals', 'plugin:unicorn/recommended', 'prettier'],
      rules: {
        // ケバブケース以外のファイル名も許容
        'unicorn/filename-case': 'off',
      },
    }
    src/components/SampleComponents.tsx
    'use client'
     
    import { useState } from 'react'
     
    export function SampleComponent() {
      const [value, setValue] = useState(0)
     
      return <div>{value}</div>
    }


    改めてESLintを実行してみると

    $ pnpm run lint
    > next lint
     
     No ESLint warnings or errors

    バッチリです!🙌




    余談

    アイキャッチは最近ChatGPT先生に作ってもらってまして、

    ボツ案としてこんなのも作ってくれました。

    ボツになったアイキャッチ向けの画像

    いちいち載せたくなるカッコ良さがあるんですよね 😂

    プロフィールの背景画像 プロフィール画像
    Yuki Takara
    都内でフリーランスのエンジニアをやってます。フロントとアプリ開発メインに幅広くやってます。