Next.js v12.2 + TypeScript + Emotion 環境構築 忘備録
Next.jsが12.2になってEmotionを利用するのに@emotion/babel-plugin
の設定が不要になったりなど、地味に嬉しいアップデートがあったので改めて環境構築忘備録を残したいと思います。
今回利用している主なパッケージとバージョンは下記です。
package | version |
---|---|
next | 12.2.2 |
react | 18.2.0 |
typescript | 4.7.4 |
@emotion/react | 11.9.3 |
eslint | 8.19.0 |
stylelint | 14.9.1 |
prettier | 2.7.1 |
husky | 8.0.1 |
作成した環境は、GitHubリポジトリにて公開しています。参考になれば幸いです。
🏭 Next.js(TypeScript)
yarn create next-app --typescript
上記コマンドを実行してNext.js環境を作成します。
対話式で、プロジェクト名を聞かれるので答えます。
この状態で、もうすでにNext.js環境の作成が完了しました。
表示を確認したい場合は、yarn dev
を実行してください。
src
フォルダの作成
このコマンドで作成したプロジェクトは、Next.jsの主要ソースがプロジェクトルートに展開されてしまうので、src
フォルダを作成してファイルを移動します。
mkdir src
mv pages src/pages
mv styles src/styles
ailas設定
コンポーネントなどのファイルをimportする際に相対パスではなく、絶対パスで指定できるようにtsconfig.json
を編集します。
{
"compilerOptions": {
+ "baseUrl": "./",
+ "paths": {
+ "@/*": [ "./src/*" ],
+ "/*": [ "*" ]
+ },
"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
},
"include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx" ],
"exclude": [ "node_modules" ]
}
💅 Emotion
Next.jsがEmotionをサポートしてくれたのでEmotionで環境構築をします。
yarn add @emotion/react
上記コマンドでパッケージを追加します。
css
属性を扱えるようにするために、tsconfig.json
を編集します。
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": [ "./src/*" ],
"/*": [ "*" ]
},
"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",
+ "jsxImportSource": "@emotion/react",
"incremental": true
},
"include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx" ],
"exclude": [ "node_modules" ]
}
vscodeを利用しているのであれば、こちらの拡張機能を追加するとスタイリングしやすくなるかと思います。
Emotionを利用してsrc/pages/index.tsx
をスタイリングしたサンプルを記載しますので参考になればと思います。
スタイリングサンプル
import { css } from '@emotion/react'
import type { NextPage } from 'next'
import Head from 'next/head'
import Image from 'next/image'
const Home: NextPage = () => {
return (
<div
css={css`
padding: 0 2rem;
`}
>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main
css={css`
display: flex;
min-height: 100vh;
flex: 1;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 4rem 0;
`}
>
<h1
css={css`
margin: 0;
font-size: 4rem;
line-height: 1.15;
text-align: center;
`}
>
Welcome to{' '}
<a
href="https://nextjs.org"
css={css`
color: #0070f3;
text-decoration: none;
&:hover,
&:focus,
&:active {
text-decoration: underline;
}
`}
>
Next.js!
</a>
</h1>
<p
css={css`
margin: 4rem 0;
font-size: 1.5rem;
line-height: 1.5;
text-align: center;
`}
>
Get started by editing{' '}
<code
css={css`
padding: 0.75rem;
background: #fafafa;
border-radius: 5px;
font-family: Menlo, Monaco, 'Lucida Console', 'Liberation Mono',
'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New',
monospace;
font-size: 1.1rem;
`}
>
pages/index.tsx
</code>
</p>
<div
css={css`
display: flex;
max-width: 800px;
flex-wrap: wrap;
align-items: center;
justify-content: center;
@media (max-width: 600px) {
width: 100%;
flex-direction: column;
}
`}
>
<Card href="https://nextjs.org/docs">
<h2>Documentation →</h2>
<p>Find in-depth information about Next.js features and API.</p>
</Card>
<Card href="https://nextjs.org/learn">
<h2>Learn →</h2>
<p>Learn about Next.js in an interactive course with quizzes!</p>
</Card>
<Card href="https://github.com/vercel/next.js/tree/canary/examples">
<h2>Examples →</h2>
<p>Discover and deploy boilerplate example Next.js projects.</p>
</Card>
<Card href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app">
<h2>Deploy →</h2>
<p>
Instantly deploy your Next.js site to a public URL with Vercel.
</p>
</Card>
</div>
</main>
<footer
css={css`
display: flex;
flex: 1;
align-items: center;
justify-content: center;
padding: 2rem 0;
border-top: 1px solid #eaeaea;
`}
>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
css={css`
display: flex;
flex-grow: 1;
align-items: center;
justify-content: center;
`}
>
Powered by{' '}
<span
css={css`
height: 1em;
margin-left: 0.5rem;
`}
>
<Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
</span>
</a>
</footer>
</div>
)
}
export default Home
export const Card: React.FC<JSX.IntrinsicElements['a']> = ({
children,
...props
}) => (
<a
{...props}
css={css`
max-width: 300px;
padding: 1.5rem;
border: 1px solid #eaeaea;
margin: 1rem;
border-radius: 10px;
color: inherit;
text-align: left;
text-decoration: none;
transition: color 0.15s ease, border-color 0.15s ease;
&:hover,
&:focus,
&:active {
border-color: #0070f3;
color: #0070f3;
}
h2 {
margin: 0 0 1rem;
font-size: 1.5rem;
}
p {
margin: 0;
font-size: 1.25rem;
line-height: 1.5;
}
`}
>
{children}
</a>
)
📙 Prettier
formatterとしてPrettierを導入します。
yarn add -D prettier
上記コマンドでパッケージをインストールします。
package.json
のnpm scriptsに下記を追加します。
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
+ "prettier": "prettier --config .prettierrc.json --ignore-path .gitignore './**/*.{ts,tsx,json,md}'",
+ "format": "yarn prettier --write"
}
}
vscodeでファイルを保存時にPrettierの設定を適応する
今回は、vscodeのワークフロー設定を例に紹介します。.vecode/settings.json
を作成(編集)します。
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"prettier.configPath": ".prettierrc.json"
}
🔖 ESLint
必要なパッケージと今回設定するプラグインなどをインストールします。
yarn add -D eslint eslint-config-google eslint-config-next eslint-config-prettier @typescript-eslint/eslint-plugin
既存で.eslintrc.json
が存在すると思いますが、今回は.eslintrc.js
を利用したいので削除します。
rm .eslintrc.json
.eslintrc.js
には下記を追加します。
module.exports = {
env: {
es2021: true,
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'next/core-web-vitals',
'google',
'prettier',
],
rules: {
'require-jsdoc': ['off'], // 必要に応じて変更してください。
'import/order': ['error', { alphabetize: { order: 'asc' } }],
'@next/next/no-img-element': ['off'],
},
}
vscodeでファイルを保存時にESLintの設定を適応する
.vecode/settings.json
を編集します。
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
+ "editor.codeActionsOnSave": {
+ "source.fixAll.eslint": true
+ },
"prettier.configPath": ".prettierrc.json"
}
🎨 Stylelint
必要なパッケージと今回設定するプラグインなどをインストールします。
yarn add -D stylelint stylelint-config-idiomatic-order stylelint-config-prettier stylelint-config-standard stylelint-prettier @stylelint/postcss-css-in-js
設定ファイルとして.stylelintrc.js
を作成します。
module.exports = {
extends: [
'stylelint-config-standard',
'stylelint-config-idiomatic-order',
'stylelint-prettier/recommended',
],
overrides: [
{
files: ['src/**/*.{ts,tsx}'],
customSyntax: '@stylelint/postcss-css-in-js',
},
],
rules: {
'string-quotes': ['single'],
},
}
package.json
にnpm scriptsを追加します。
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
+ "stylelint": "stylelint --ignore-path .gitignore './src/**/*.{css,scss,ts,tsx}'",
"prettier": "prettier --config .prettierrc.json --ignore-path .gitignore './**/*.{ts,tsx,json,md}'",
"format": "yarn prettier --write"
}
}
vscodeでファイルを保存時にStylelintの設定を適応する
.vecode/settings.json
を編集します。
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
- "source.fixAll.eslint": true
+ "source.fixAll.eslint": true,
+ "source.fixAll.stylelint": true
},
"prettier.configPath": ".prettierrc.json"
}
🛠 typecheck(tsc)
Linterだけでは、Typescriptの型定義が正しいか判定されないのでtsc
を利用して、チェックできるようにします。
npm scripts にコマンドを追加します。
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"stylelint": "stylelint --ignore-path .gitignore './src/**/*.{css,scss,ts,tsx}'",
+ "typecheck": "tsc",
"prettier": "prettier --config .prettierrc.json --ignore-path .gitignore './**/*.{ts,tsx,json,md}'",
"format": "yarn prettier --write"
}
}
🐶 husky
コードをコミットする際に今まで設定してきた、Linterなどを実行して、コード品質を担保するためにhuskyを導入します。
npx husky-init && yarn
公式で推奨されている方法でインストールします。
インストールが完了するとプロジェクトに.husky
フォルダが作成されているかと思います。
その中のpre-commit
を編集します。
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
- npm test
+ yarn typecheck
+ yarn lint
+ yarn stylelint
+ yarn prettier -l
fix
コマンドの追加
♻️ huskyにより、コミットができなかった場合など、手作業でソースコードを直すのは大変です。
機械的に治せる部分を一括で修正をかけられるように npm scripts を追加します。
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"stylelint": "stylelint --ignore-path .gitignore './src/**/*.{css,scss,ts,tsx}'",
+ "fix": "yarn lint --fix && yarn stylelint --fix && yarn format",
"typecheck": "tsc",
"prettier": "prettier --config .prettierrc.json --ignore-path .gitignore './**/*.{ts,tsx,json,md}'",
"format": "yarn prettier --write",
"prepare": "husky install"
}
}
これにより、yarn fix
が実行可能になりました。
最後に
この構成をベースにホスティング環境や開発要件によって色々カスタマイズしていけると思います。
かくいう私もここを起点に色々これからリポジトリを組み立てていこうと思います。
Twitterでフロントエンド周りのこと呟いたりしてます。
よければ絡んでくださいー。
Discussion