かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Next.js root ディレクトリをシンプルにしたい。

Next.js でプロジェクトを作ると root ディレクトリに routing をするための /pages が作られるのでコンポーネントなどのファイルを作ろうとすると root にディレクトリが増えてしまっていって見通しがあまりよろしくないので、react のプロジェクトのように /src ないにまとめていい感じにしたかったメモ

Next.js + TypeScript + ESLint + Preiiterでプロジェクトを作った状態

こんな感じのディレクトリ構成になってる

/
 |- /.vscode
 |- /node_modules
 |- /pages
 |- /public
 |- /styles
 |- .gitignore
 |- .eslintrc.js
 |- .prettierrc.json
 |- next.config.js
 |- package-lock.json
 |- package.json
 |- README.md
 |- tsconfig.json

/src 内にアプリ関係のファイルを移動させる

tsconfig.jsoncompilerOptions.baseUrl オプションでルートになるディレクトリが指定できる

{
  "compilerOptions": {
    "baseUrl": "src",
  }
}

これで /src ディレクトリがルートになるので、/pages ディレクトリなどをこの中に移動させてOKになる。
👇 ディレクトリ構成を変更

/
 |- /.vscode
 |- /node_modules
 |- /public
 |- /src
 |   |- /pages
 |   |- /styles
 |- .gitignore
 |- .eslintrc.js
 |- .prettierrc.json
 |- next.config.js
 |- package-lock.json
 |- package.json
 |- README.md
 |- tsconfig.json

この状態で npm run dev をして localhost:3000 で問題なく Next のアプリが起動すれば OK。
これで /components とかアプリに使うファイルを置くディレクトリを /src 内にまとめることができました ₍ ᐢ. ̫ .ᐢ ₎ ヤッタゼ

コンポーネントの import を楽にする (path alias の設定)

React, Next のアプリを作っているとディレクトリのネストや下層コンポーネントから上位のコンポーネントのインポートで相対パスを書くのが自動補完があるとは言え ../../../ みたいなのはあまり見通しがよろしくないです。
tsconfigcompilerOptions.paths オプションを使うとディレクトリへのパスのエイリアス (?) が作成できるみたいなので、色んなコンポーネントから呼び出すようなディレクトリを登録して import の見通しを良くしたいと思います。

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "src",
+   "paths": {
+     "~/components/*": ["components/*"],
+     "~/styles/*": ["styles/*"],
+     "~/public/*": ["../public/*"]
+   },
  }
}

compilerOptions.pathsbaseUrl を root にしてそこからの相対パスで指定する
これで import XXX from '~/components/XXX'/src/components/XXX, import from '~/public/XXX'/src/XXX を何処からでも import できるようになりました! utility や Atom に該当するようなファイルを置くディレクトリをここで指定しておくといい感じになりそうです。

Next ちょっとづつスタァライトしてきた感あるな (環境作ってばかりだけど)


[参考]

Next.js TypeScript + ESLint + Prettier の環境を作るのだ!

何回も作るのに都度調べるのめんどくなってきたからメモ

Next.js のプロジェクトを作る

今いるディレクトリにプロジェクトを作る

$ npx create-next-app --use-npm .

--use-npm オプションつけないと npm が無いって怒られる。忘れがち…

TypeScript 化

$ npm install --save-dev typescript @types/react @types/node
$ touch tsconfig.json

この状態で Next のプロジェクトを dev モードで起動すると自動的に tsconfig.json の中身が記述され、next-env.d.ts ファイルも作成される

$ npm run dev

ESLint の導入

Since version 11.0.0, Next.js provides an integrated ESLint experience out of the box. Add next lint as a script to package.json
cf. Basic Features: ESLint | Next.js

Next.js v11.0.0 からはプロジェクト内に ESLint が入っていて npx next lint で動作するらしい。

必要なパッケージのインストール

$ npm install --save-dev eslint eslint-config-next

ESLint を実行する npm script を追加

package.json

{
  "script": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
+   "lint": "next lint",
+   "lint:fix": "next lint --fix"
  },
}

Prettier を使うのと、独自のルールを追加したいので ESLint の設定ファイルを作る

$ touch .eslintrc.js

.eslintrc.js (cf. Basic Features: ESLint | Next.js)

module.exports = {
  extends: [
    'next',
    'next/core-web-vitals',
  ],
  rules: {
    'semi': 'error',
    'import/prefer-default-export': 'off',
    'newline-before-return': 'error',
    'no-console': 'warn',
    'no-var': 'error',
  },
};

npm run lint:fix で ESLint での修正が入れば OK

Prettier の導入

$ npm install --save-dev prettier eslint-config-prettier
$ touch .prettierrc.json

Prettier の設定 .prettierrc.json (お好みで)

{
  "printWidth": 80,
  "tabWidth": 2,
  "semi": true, // 末尾セミコロンあり
  "singleQuote": true, // シングルコーテーションを使う
  "jsxSingleQuote": true, // JSX もシングルコーテーションに
  "arrowParens": "always", // Arrow 関数の引数に () を付ける
  "endOfLine": "lf" // 改行コード LF
}

ESLint と Prettier がバッティングしないように連携させる

.eslintrc.js

module.exports = {
  extends: [
    'next',
    'next/core-web-vitals',
+   'prettier',
  ],
  rules: {

Prettier を実行する npm script を追加

package.json

{
  "script": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "lint:fix": "next lint --fix",
+   "format": "prettier --write --ignore-path .gitignore './**/*.{js,jsx,ts,tsx,json,css,scss}'"
  },
}

npm run format を実行して Prettier でのフォーマットが実行されれば OK

VS Code で保存時に ESLint, Prettier を実行してフォーマットする

$ mkdir .vscode
$ touch .vscode/settings.json

.vscode/settings.json

{
  "files.exclude": {
    "**/node_modules": true
  },
  "editor.tabSize": 2,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "[markdown]": {
    "files.trimTrailingWhitespace": false
  }
}

適当なファイルを開いて保存時にフォーマットが実行されればOK

所管

Next.js というフレームワークがお膳立てして用意してくれているおかげ素の TypeScript で環境作るよりめちゃめちゃ簡単でした!
でも毎回やるのめんどいからテンプレート化しておこうかな…というお気持ち


[参考]

正直 Next.js の本は何が良いのか何もわからん…

メイドラゴン放送されて嬉しい〜 トールかわいい〜

Next.js next/image で外部URLの画像を使いたいときにやること

プロトタイプを作っているときなど、ダミー画像で画像生成サービスを使うことがあります。
Next.js の組み込みコンポーネント next/image でダミー画像生成サービスの url を src に設定したらエラーになったので忘れないようにメモ。

next/image の src に外部ドメインを指定するとエラーになる

例えばダミー画像の Avatar を表示するコンポーネント

import { VFC } from "react";
import Image from 'next/image';

type AvatarProps = {
  alt?: string;
  width: number;
  height: number;
}

const dummyImage = 'https://placeimg.com/140/140/any';

export const Avatar: VFC = ({ alt, width, height }) => {
  return (
    <Image src={dummyImage} width={width} height={height} alt={alt} />
  );
};

=> Server Error
Error: Invalid src prop (https://placeimg.com/140/140/any) on `next/image`, hostname "placeimg.com" is not configured under images in your `next.config.js`
See more info: https://nextjs.org/docs/messages/next-image-unconfigured-host

エラーになります。

next.config.js に使用する外部ドメインを設定しておく必要がある

To enable Image Optimization for images hosted on an external website, use an absolute url for the Image src and specify which domains are allowed to be optimized. This is needed to ensure that external urls can't be abused. When loader is set to an external image service, this option is ignored.
cf. Basic Features: Image Optimization | Next.js

next/image が画像最適化を行うために外部ドメインの画像を使う場合はドメインを指定しておく必要がある。トノコト

next.config.js が無ければ作る。

$ touch next.config.js

👇

next.config.js

module.exports = {
  images: {
    domains: ['placeimg.com'],
  },
};

今回は https://placeimg.com/140/140/any を使いたいので domains には placeimg.com を指定する

設定ファイルなので反映させるにはサーバーを再起動させる必要がある。
ctl + C でサーバーを止めて npm run dev で再起動。
Avatar コンポーネントの画像が問題なく表示されていれば OK


[参考]

今季は かげきしょうじょ 観てます。オススメあったら教えてください!