Next.jsのベストプラクティス

Next.jsのベストプラクティス
Next.js
2022年4月18日 更新

Next.js

Next.jsはモダンのフルスタック開発フレームワークです。

Reactをベースにしていて、フロントエンドを特化しています。

Next.jsの1番の特性としてはWebサーバーとしてHTMLページを動的に生成することです、代表的なのはSSR、SSGとISRです。

SSR: Server Side Rendering、所謂、サーバーでクライエントの内容(HTML)を動的に生成する。

SSG: Static Site Generator、所謂、サーバー事前にファイルを表示するものをビルドして、クライエントリクエスト来たら、ものを返します。

ISR: Incremental Static Regeneration、SSGと同じ、事前にファイルをビルドして生成していますが、こちらは、一定期間ごとで再ビルドする仕組みがあります。

環境

まずNext.jsのプロジェクトを開発する時、事前準備は大事と思います。

Create

Typescriptを例にします。

npx create-next-app --typescript {nextjs-app名}

cd {nextjs-app名}

npm run dev

上記終わったら、http://localhost:3000 で確認できると思います。

ESLint

.eslintrc.jsonを作成し、下記のように設定します。

{
  "extends": ["next", "next/core-web-vitals", "eslint:recommended"],
  "globals": {
    "React": "readonly"
  },
  "rules": {
    "no-unused-vars": [1, { "args": "after-used", "argsIgnorePattern": "^_" }],
    "no-unused-vars": 0, 
  }
}

目的:lintをチェックする。いわゆる、コーディング規約です。

Prettier

prettierは自動的にコードを見やすくなるように調整してくれます。

VSCodeのプラグインと組み合わせると尚便利です。

.prettierrcを作成、下記のように設定します。

{
  "trailingComma": "es5",
  "tabWidth": 2,
  "semi": true,
  "singleQuote": true
}

また、tsやjsファイルではないものを無視してくれる設定は.prettierignoreにお任せします。

例:

*.html
.yarn
.next
dist
node_modules

Hooks

コードをコミットする前に、自動的に走ってくれるHooksありました。

自分の場合、Gitでコミットするとき、lintやprettierを自動的に走ってみたい。

おすすめ:husky

package.jsonにコマンドを追加します。

...
  "scripts: {
    ...
    "prepare": "husky install"
  }

初期化完了後、下記のようにhookを追加できます。

npx husky add .husky/pre-commit "yarn lint"

補足:一般的なlintツールがありまして、

npx husky add .husky/commit-msg "npx --no -- commitlint --edit $1"

でこちらのlintをgitでコミットするとき、チェックしています。

VSCode

.vscode/settings.jsonで自動prettyします。

{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll": true,
    "source.organizeImports": true
  }
}

Debug

.vscode/settings.jsonでDebugルールを作成する。

{
    "version": "0.1.0",
    "configurations": [
      {
        "name": "Next.js: debug server-side",
        "type": "node-terminal",
        "request": "launch",
        "command": "npm run dev"
      },
      {
        "name": "Next.js: debug client-side",
        "type": "pwa-chrome",
        "request": "launch",
        "url": "<http://localhost:3000>"
      },
      {
        "name": "Next.js: debug full stack",
        "type": "node-terminal",
        "request": "launch",
        "command": "npm run dev",
        "console": "integratedTerminal",
        "serverReadyAction": {
          "pattern": "started server on .+, url: (https?://.+)",
          "uriFormat": "%s",
          "action": "debugWithChrome"
        }
      }
    ]
  }

補足:cross-envでチームメンバーの環境衝突を避けます。

{
  ...
  "scripts": {
    ...
    "dev": "cross-env NODE_OPTIONS='--inspect' next dev",
  },
}

Storybook

基本的にsrcは本体であることです。

その中身、自分的にこちらでいいかと思います。

- components   (UI必要なもの
- lib       (業務フロー、機能実装など
- pages      (ルーターやページ
- stories      (storybookの内容

Storybook本当に便利です、見た目がわかりやすいです、やっぱりはUIがUIで解決するですね。

Install

Webpack5をベースにしているので、インストールしましょう。

npx sb init --builder webpack5

package.jsonの更新も忘れなく。

{
  ...
  "resolutions": {
    "webpack": "^5"
  }
}

yarn installnpm installの後にstorybookも入ることができました。

設定

.storybook/main.jsファイル存在している。

module.exports = {
  stories: ['../**/*.stories.mdx', '../**/*.stories.@(js|jsx|ts|tsx)'],
	/** public ファイルは stotrybook 読めるようにします */
  staticDirs: ['../public'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/addon-interactions',
  ],
  framework: '@storybook/react',
  core: {
    builder: '@storybook/builder-webpack5',
  },
};

そして、.storybook/preview.jsでレンタリングの方法を変えてみよう。

import '../styles/globals.css';
import * as NextImage from 'next/image';

const BREAKPOINTS_INT = {
  xs: 375,
  sm: 600,
  md: 900,
  lg: 1200,
  xl: 1536,
};

const customViewports = Object.fromEntries(
  Object.entries(BREAKPOINTS_INT).map(([key, val], idx) => {
    console.log(val);
    return [
      key,
      {
        name: key,
        styles: {
          width: `${val}px`,
          height: `${(idx + 5) * 10}vh`,
        },
      },
    ];
  })
);

// Storybook が Next の <Image> を処理することができます
const OriginalNextImage = NextImage.default;

Object.defineProperty(NextImage, 'default', {
  configurable: true,
  value: (props) => <OriginalNextImage {...props} unoptimized />,
});

export const parameters = {
  actions: { argTypesRegex: '^on[A-Z].*' },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
  viewport: { viewports: customViewports },
};

最後に、yarn storybooknpm run storybookで確認できます。

やり方

Storybookで随時UIの状態確認できるので、各UIパールを作るにはTemplateの概念は入れるべきと思います。

さらに、componentsにLayoutを作り、レイアウトは自動的に適用するでしょうか。

補足: 基本的にpages/_document.tsxpages/_app.tsxをカスタマイズする必要があります。

Deploy

Next.jsを開発していたVercel社は最新の機能を対応しているので、Vercelのサービスを使ってデプロイした方がいいかもしれない。

また、そのほか、AWSNetlifyも対応していまして、どちらもやりやすいと思います。

さらに、自分は愛用しているCloudfareもNext.jsを対応していて、嬉しいです。

注意:各サービスの料金システムによって、計画的にサービスをデプロイしてください。