💫

今すぐにNext.jsでフロントエンド開発 or Web制作を快適に始めたい方におすすめの簡単セットアップを紹介する

2022/12/02に公開
1

はじめに

株式会社LCLでフロントエンドエンジニアとして働いている「おとの」と申します。

今回は、今をときめくフロントエンドのフレームワーク「Next.js」を使って、個人もしくは複数人のチームで快適にフロントエンド開発を行いたい方にオススメのセットアップを紹介します。

本セットアップを行うメリットは以下の通りです。

  • (自動formatが有効になる等)開発速度が増す
  • (StylelintやEslintの静的解析により)不具合の発生や潜在的なエラーを防ぎやすくなる
  • コードの品質と一貫性を保つことができる

Next.jsを使いこなせれば、フロントエンド開発だけに限らず、ランディングページ(LP)など静的なWebサイトの実装を行うWeb制作にも有用です。

私自身、Webサイト1ページのコーディングが求められる際もNext.jsを使っています。本セットアップも簡単に終わるので、今すぐ始めたい方はぜひ読んでいただけると幸いです。

Visual Studio Codeのおすすめプラグインを紹介した記事もありますので、合わせてどうぞ。

https://zenn.dev/toono_f/articles/38fd6ce1cf82e5

本記事は初歩的な環境構築から紹介します。既に完了されている方は次々と読み進めてください🙆‍♂️

Node.jsのバージョン管理ツールの導入

まだ導入されていない方は、以下記事が参考になりそうです。数多あるバージョン管理ツールの中、セットアップ等が比較的容易なことから、今回はnodenvをオススメします。

https://zenn.dev/donchan922/articles/b08a66cf3cbbc5

Next.jsのセットアップ

  1. Next.jsプロジェクトを作成します。下記コマンドを実行してください。
npx create-next-app@latest
  1. 任意のプロジェクト名を入力します。初期値は「my-app」です。
? What is your project named? › my-app
  1. TypeScriptを導入するかどうかを聞かれます。今回は「Yes」を選択しましよう。
? Would you like to use TypeScript with this project? › No / Yes
  1. EsLintも導入するか聞かれます。こちらも「Yes」を選択しましょう。
? Would you like to use ESLint with this project? › No / Yes
  1. そうするとインストールが始まります。完了後、プロジェクトディレクトリに移動して以下コマンドを実行してください。開発サーバーを立ち上げられるはずです。
npm run dev

Welcome to Next.js!

ワクワクする画面が表示されました。ダークモードに対応してるのもGoodですね!!

各ファイルをsrcディレクトリに移動する

プロジェクトのルートディレクトリにsrcを作成して、pagesstylesをその配下に移動します。移動後は以下ディレクトリ構成になるはずです。Next.jsだとデフォルトで本構成をサポートしており、その他設定を修正することなく実現できます。

├── public
│   ├── favicon.ico
│   └── vercel.svg
├── src
│   ├── pages
│       ├── api
│           └── hello.ts
│       ├── _app.tsx
│       └── index.tsx
│   ├── styles
│       ├── globals.css
│	└── Home.module.css
├── .eslintrc.json
├── .gitignore
├── next.config.js
├── package-lock.json
├── package.json
├── tsconfig.json
├── README.md
└── next-env.d.ts

https://nextjs.org/docs/advanced-features/src-directory

srcディレクトリからの絶対パスでインポートできるようにする

tsconfig.jsonに以下記述を追加することで、import文がsrcディレクトリからの絶対パスで記述されるようになります。コードの可読性が増すのでオススメです。

tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
+   "baseUrl": ".",
+   "paths": {
+     "@/*": ["src/*"]
+   }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

静的HTMLとしてexportできるようにする

package.jsonに以下記述を追加します。npm run exportを実行すれば、ビルド時に静的HTMLとしてファイルを生成することができます。ファイルの納品やレンタルサーバーにアップする機会があるWeb制作を生業にする方にオススメの設定です。

package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
+   "export": "next build && next export",
  },
}

Prettier + Stylelint + ESLint の導入

Prettier + Stylelint + ESLintを導入することで、各プラグインの静的解析をもとに、実装ミスが引き起こす不具合の発生や潜在的なエラーの発見、各ファイルの自動フォーマットを可能にします。

下記コマンドを実行し、Prettier、Stylelint、ESLintをインストールします。EslintにはTypeScriptを、Stylelintにはscssにも対応させるためのプラグインを含んでいます。

npm install --save-dev prettier eslint-config-prettier stylelint stylelint-prettier stylelint-config-prettier stylelint-scss stylelint-config-recess-order stylelint-config-recommended-scss @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-import eslint-plugin-simple-import-sort eslint-plugin-unused-imports

各設定ファイルの追加

  1. prettier.config.jsを作成します。prettierにおけるフォーマットルールを設定することができます(下記は全て初期値の設定)
prettier.config.js
module.exports = {
  printWidth: 80, // 1行で表示する文字数
  tabWidth: 2, // インデントのサイズ
  useTabs: false, // インデントにスペースの代わりにタブを使うかどうか
  semi: true, // 文の後にセミコロンを付けるかどうか
  singleQuote: false, // 文字列をシングルクォートで囲むかどうか(falseだとダブルクォート)
  quoteProps: "as-needed", // オブジェクトのプロパティ名をクォートで囲むかどうか
  jsxSingleQuote: false, // JSX内のクォートをシングルクォートで囲むかどうか
  trailingComma: "es5", // 複数行のときの末尾のカンマを付けるかどうか
  bracketSpacing: true, // オブジェクトリテラルの{}内の前後にスペースを入れるかどうか
  bracketSameLine: false, // JSX内の要素の閉じタグを最後の行に含んで表示するか
  arrowParens: "always", // アロー関数の引数が1つのときにカッコで囲むかどうか
};

https://prettier.io/docs/en/options.html

  1. stylelint.config.js を作成します。Stylelintにおけるルールを設定することができます。CSSプロパティの自動ソートも実現できるようになります。
stylelint.config.js
module.exports = {
  plugin: ["stylelint-scss"],
  extends: [
    "stylelint-config-recommended-scss", // scssのための拡張ルール追加
    "stylelint-config-recess-order", // 視認性を考慮したcssプロパティの自動ソートを設定
    "stylelint-config-prettier", // Prettierとの競合ルールをOFFにする
  ],
};
  1. .eslintrc.json に以下記述を追加します。ESLintにおけるルールを設定することができます。js(ts)ファイル内のimport文の自動ソートも実現できるようになります。
.eslintrc.json
{
  "extends": [
    "next/core-web-vitals",
+   "eslint:recommended", // eslint推奨ルール設定
+   "plugin:@typescript-eslint/recommended", // typescript-eslintの推奨ルール設定
+   "prettier" // Prettierとの競合ルールをOFFにする(他の設定を上書きするため、最終行に記述する必要有り)
  ],
+ "plugins": [
+   "simple-import-sort", // import文の自動整列を実現
+   "import", // 上記プラグインを拡張(自動整列のルールを追加)
+   "unused-imports" // 未使用のimport文を削除
+ ],
+ "rules": {
+   "simple-import-sort/imports": "error", // importのsortルールを設定
+   "simple-import-sort/exports": "error", // exportのsortルールを設定
+   "import/first": "error", // すべてのimportがファイルの先頭にあることを確認
+   "import/newline-after-import": "error", // import後に改行があることを確認
+   "import/no-duplicates": "error", // 同じファイルのimportをマージ
+   "unused-imports/no-unused-imports": "error" // 未使用のimport文を削除
+ }
}
  1. package.jsonに以下記述を追加します。各コマンドを実行することで、それぞれのlintに基づいたフォーマットを行うことができます。npm run formatを実行すると、ESLint + Stylelint + prettierによるフォーマットを一括で行えます。
package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "export": "next build && next export",
+   "eslint:fix": "eslint src --ext .js,jsx,.ts,.tsx --fix",
+   "stylelint:fix": "stylelint src/**/*.{css,scss} --fix",
+   "prettier:fix": "prettier --check --write 'src/**/*.{js,jsx,ts,tsx,css,scss,md,mdx}'",
+   "format": "npm run eslint:fix && npm run stylelint:fix && npm run prettier:fix",
  },
}

Visual Studio Codeでの開発を快適にする

以下設定を進めることで、VsCodeでのファイルの保存時にもPrettier + Stylelint + ESLintに基づく自動フォーマットが行われるようになります。開発速度の時短にも繋がるのでオススメです。

  1. VsCodeで以下プラグインをそれぞれインストールしてください。プロジェクトでインストールしたパッケージの各機能を含んでいるプラグインになります。

https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode

https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint

https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint

  1. プロジェクトのルートディレクトリに.vscode/settings.jsonを作成後、以下記述を追加してください(もしくはVsCode本体のsettings.jsonを修正してください)
.vscode/settings.json
{
  // ファイル保存時のフォーマット処理を有効化する
  "editor.formatOnSave": true,

  // 各ファイルのフォーマッターを指定する
  "[css]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[scss]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },

  // Stylelintの対象を設定
  "stylelint.validate": ["css", "scss"],

  // ESLintの対象を設定
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ],

  // 保存時に実行される各コードアクションを有効化する
  "editor.codeActionsOnSave": {
    "source.fixAll.stylelint": true,
    "source.fixAll.eslint": true,
    "source.organizeImports": false // eslintでのimport順自動整列を実現するため無効
  },

  // VSCodeデフォルトのLintを無効にする(各Lintのルールで統一する際に設定)
  "css.validate": false,
  "scss.validate": false,
  "javascript.format.enable": false,
  "typescript.format.enable": false
}

ここまでの設定が終了すると、VsCodeでのファイル保存時にPrettier・Stylelint・ESLintを通したフォーマット処理が自動で行われるようになります。開発が快適に進められそうですね🔥

source.organizeImportsfalseに設定したのは、eslintでのimport文の自動ソートと競合しないようにするためです。trueになってしまっている場合、CSSのimport文読み込み順も変わってしまい、(CSSの優先度の兼ね合いから)画面の表示に影響が発生する可能性があります。

以下内容はおまけです。興味がある方は参考にしてみてください。

Storybookの導入

Storybookを導入することで、UIコンポーネントの管理やテストの実行を行いやすくなります。デザイナーとの連携にも役立つかもしれません。以下記事を参考にしてみてください。

https://zenn.dev/toono_f/articles/3aa990971975cb#storybookのインストール

「Storybookのインストール」の章から始めるとスムーズに進むと思います。(本記事は便宜上npmを採用したので)yarnをnpmに差し替えて読んでいただけると幸いです。

Tailwind CSSの導入

Tailwind CSSを導入すれば、汎用的に利用できるCSSを実装する手間を大きく削減できます。

CSS設計のFLOCSSにあるUtilityの役割を果たし、purge機能も搭載しています。Webサイトのコーディングを爆速で進めたい方(Web制作に携わっている人など)に特にオススメです。

https://tailwindcss.com/

  1. 下記コマンドを実行し、Tailwind CSSをセットアップします。Tailwind CSS以外にもcss(scss)を記述したい場合やStorybookを導入する際も考慮し、他プラグインも同時にインストールします。
npm install --save-dev tailwindcss postcss autoprefixer
  1. Tailwind CSSの設定を行うためのtailwind.config.jsを作成します。
npx tailwindcss init
  1. tailwind.config.jsに以下記述を追加します。src配下のpagesとcomponentsディレクトリ内にあるファイル(jsx、tsx)で未使用のCSSを削除するように設定できます。
tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
+   "./src/pages/**/*.{js,ts,jsx,tsx}",
+   "./src/components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};
  1. global.cssにTailwind CSSを読み込ませます。この時点でTailWindCSSを使えるようになります。サクッと簡単ですね。
src/styles/globals.css
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
  1. (Storybookを導入している場合)Tailwind CSSを読み込ませられるように修正します。
npm install --save-dev @storybook/addon-postcss
.storybook/main.js
const path = require("path");
const rootPath = path.resolve(__dirname, "../src/");

module.exports = {
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
    "@storybook/preset-scss",
    "storybook-addon-next-router",
+   {
+     name: "@storybook/addon-postcss",
+     options: {
+       postcssLoaderOptions: {
+         implementation: require("postcss"),
+       },
+     },
+   },
  ],
  framework: "@storybook/react",
  core: {
    builder: "@storybook/builder-webpack5",
  },
  staticDirs: ["../public"],
  webpackFinal: async (config, { configType }) => {
    config.resolve.alias["@"] = rootPath;
    return config;
  },
};

今回は以上になります。ここまで読んでいただき感謝です。

LCL Engineers

Discussion

おとのおとの

Next.js 13から初回インストール時に以下の質問が聞かれるようになったみたい。素敵。

✔ Would you like to use src/ directory with this project?
✔ Would you like to use experimental app/ directory with this project?