2022 | Next.js 12 + React 18 + Mantine + TailwindCSS で開発しやすい環境を構築する
Hi, It's Cray! :D
こんにちは Cray です!
今回は Next.js 12 と React 18 を中心に、
スタイルにはトレンドの Mantine と、細かな調整がしやすい Tailwind CSS を導入します!
パッケージマネージャーは高速な pnpm を使います。
さらに ESLint と Prettier を導入し、インポートを自動で整理します。
開発体験(Developer Experience)の高い環境構築を目指します✌🏻
Packages
今回導入するパッケージです😋
Dependencies
Package | Version |
---|---|
nextjs | 12.2.5 |
react | 18.2.0 |
react-dom | 18.2.0 |
@emotion/react | ^11.10.0 |
@emotion/server | ^11.10.0 |
@mantine/core | ^5.2.0 |
@mantine/hooks | ^5.2.0 |
@mantine/next | ^5.2.0 |
@tabler/icons | ^1.84.0 |
Dev Dependencies
Package | Version |
---|---|
@types/node | 18.7.8 |
@types/react | 18.0.17 |
@types/react-dom | 18.0.6 |
@typescript-eslint/eslint-plugin | ^5.33.1 |
@typescript-eslint/parser | ^5.33.1 |
autoprefixer | ^10.4.8 |
eslint | 8.22.0 |
eslint-config-next | 12.2.5 |
eslint-config-prettier | ^8.5.0 |
eslint-import-resolver-typescript | ^3.4.2 |
eslint-plugin-import | ^2.26.0 |
eslint-plugin-unused-imports | ^2.0.0 |
postcss | ^8.4.16 |
tailwindcss | ^3.1.8 |
typescript | 4.7.4 |
Guide
pnpm をインストール
いずれかの方法で pnpm をインストールします。
私は node、npm、yarn なども volta で管理しています。
volta intall pnpm
# or
npm install -g pnpm
# or
brew install pnpm
Next.js をセットアップする
1. Next のプロジェクトを生成
Next.js のプロジェクトを TypeScript でセットアップします
実行後、プロジェクト名を訊かれるので入力します。
(Tailwind CSS を同時にインストールするオプションもありますが、 ディレクトリ構成を変えるため、別途インストールします。)
pnpm create next-app --typescript
2. パスを修正
見通しがよくなったり eslint 導入時に指定がしやすくなるので、
生成されたファイルのパスを一部修正します。
src
ディレクトリを追加し、pages
styles
フォルダを移動します。
3. 起動を確認する
セットアップが完了したら、開発サーバーを起動し、アドレスからアプリを確認できます。
cd your-project
pnpm dev
http://localhost:3000
Prettier と ESLint をセットアップする
1. prettierrc
.prettierrc
を作成します。
行の文字数は120
、セミコロンは省略、タブサイズは2
、配列やオブジェクトの末尾のカンマをつける設定にしています。
touch .prettierrc
{
"printWidth": 120,
"semi": false,
"tabWidth": 2,
"trailingComma": "all"
}
2. Prettier のパッケージをインストール
同時に Tailwind CSS の整形用のパッケージもインストールしておきます。
pnpm add -D prettier prettier-plugin-tailwindcss
3. パスエイリアスを設定
絶対パスでインポートできるように、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"]
}
4. 自動整形用のコマンドを修正
package.json
のスクリプトを追加、修正しておきます。
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
- "lint": "next lint"
+ "lint": "next lint --dir src",
+ "lint:fix": "next lint --dir src --fix"
},
}
5. eslintrc
eslintrc の設定ファイルは json か js を選べますが、今回は管理がしやすい js にします。
.eslintrc.json
を削除し、かわりに .eslintrc.js
を作成します。
touch .eslintrc.js
ESLint で指定できるインポートの記述順序やルールを指定しています。
外部パッケージ、UI 系の外部パッケージ、コンポーネントの順に、 A to Z で並ぶようにしています。
必要に応じて変更してください。
module.exports = {
root: true,
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint", "@typescript-eslint", "import", "unused-imports"],
extends: [
"eslint:recommended",
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:import/warnings",
"prettier",
],
rules: {
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_", varsIgnorePattern: "^_" }],
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/no-use-before-define": "off",
"prefer-const": "warn",
"import/order": [
"warn",
{
"newlines-between": "always",
alphabetize: { order: "asc" },
groups: ["builtin", "external", "parent", "sibling", "index", "object", "type"],
pathGroupsExcludedImportTypes: ["builtin", "object"],
pathGroups: [
{ pattern: "{@mantine/**,@emotion/**,@tabler/**,@heroicons/**}", group: "parent", position: "before" },
],
},
],
"import/newline-after-import": "warn",
"unused-imports/no-unused-imports": "warn",
},
settings: {
"import/resolver": {
typescript: {
project: "./tsconfig.json",
},
},
},
}
4. VSCode の設定
VSCode で保存したときに、自動で prettier と eslint に従った整形が走るように、設定します。
今回はワークスペースに設定していますが、必要に応じてユーザーに設定してください。
mkdir .vscode && touch .vscode/settings.json
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.alwaysShowStatus": true
}
5. パッケージをインストール
pnpm add -D eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-prettier eslint-import-resolver-typescript eslint-plugin-import eslint-plugin-unused-imports
6. VSCode プラグインをインストール
以下のプラグインをインストールしておきます。
7. VSCode を再起動し、自動整形を確かめる
インストールが終わったら、VSCode を再起動します。
適当な tsx を保存したときに、自動整形されるようになっていれば OK です。
pnpm lint:fix
でまとめて整形することもできます。
これでスタイルを気にせず、快適にコードを書けるようになりました✌🏻
Tailwind CSS をセットアップする
1. Tailwind CSS をインストール
Tailwind CSS を PostCSS プラグインとしてインストールすると webpack、Rollup、Vite、Parcel などのビルドツールとシームレスに統合できます。
init すると tailwind.config.js
postcss.config.js
が生成されます。
pnpm add -D tailwindcss postcss autoprefixer
pnpm dlx tailwindcss init -p
2. Tailwind CSS のパスを構成する
Tailwind CSS を使用するファイルのパスを content
で指定します。
/** @type {import('tailwindcss').Config} */
module.exports = {
+ content: ["./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
+ corePlugins: {
+ preflight: false,
+ },
}
3. CSS に Tailwind ディレクティブを追加する
styles/global.css
の中身を以下に置き換えます。
おなじディレクトリにある Home.module.css
は使用しないので削除してください。
@tailwind base;
@tailwind components;
@tailwind utilities;
Mantine をセットアップする
1. Mantine 関連のパッケージをインストール
必要なパッケージをインストールします。
pnpm add @mantine/core @mantine/hooks @mantine/next @emotion/server @emotion/react @tabler/icons
2. Mantine の初期セットアップ
_document.tsx
_app.tsx
ファイルを以下に置き換えてください。
import Document, { Head, Html, Main, NextScript } from "next/document"
import { createGetInitialProps } from "@mantine/next"
const getInitialProps = createGetInitialProps()
export default class _Document extends Document {
static getInitialProps = getInitialProps
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
import "@/styles/globals.css"
import { NextPage } from "next"
import { AppProps } from "next/app"
import Head from "next/head"
import { useState } from "react"
import { ColorScheme, ColorSchemeProvider, MantineProvider } from "@mantine/core"
const App: NextPage<AppProps> = ({ Component, pageProps }) => {
const [colorScheme, setColorScheme] = useState<ColorScheme>("dark")
const toggleColorScheme = (value?: ColorScheme) =>
setColorScheme(value || (colorScheme === "dark" ? "light" : "dark"))
return (
<>
<Head>
<title>Next</title>
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
</Head>
<MantineProvider
withGlobalStyles
withNormalizeCSS
theme={{
colorScheme,
}}
>
<ColorSchemeProvider colorScheme={colorScheme} toggleColorScheme={toggleColorScheme}>
<Component {...pageProps} />
</ColorSchemeProvider>
</MantineProvider>
</>
)
}
export default App
Mantine + Tailwind CSS を使ったコンポーネントを設置する
Mantine + Tailwind CSS を使ったコンポーネントを設置して、動作を確かめます。
mkdir components && touch components/ColorSchemeToggle.tsx
import { FC } from "react"
import { useMantineColorScheme, ActionIcon, Group } from "@mantine/core"
import { IconSun, IconMoonStars } from "@tabler/icons"
const ColorSchemeToggle: FC = () => {
const { colorScheme, toggleColorScheme } = useMantineColorScheme()
return (
<Group position="center" my="xl">
<ActionIcon
onClick={() => toggleColorScheme()}
size="lg"
sx={(theme) => ({
backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.colors.gray[0],
color: theme.colorScheme === "dark" ? theme.colors.yellow[4] : theme.colors.blue[6],
})}
>
{colorScheme === "dark" ? <IconSun size={18} /> : <IconMoonStars size={18} />}
</ActionIcon>
</Group>
)
}
export default ColorSchemeToggle
index.tsx
を以下のように書き換えます。
import { NextPage } from "next"
import { Stack } from "@mantine/core"
import ColorSchemeToggle from "@/components/ColorSchemeToggle"
const Home: NextPage = () => {
return (
<div>
<Stack align="center" justify="center" spacing="lg" className="min-h-screen">
<h1 className="font-extrabold text-gray-600">Welcome to Mantine & Tailwind CSS!</h1>
<ColorSchemeToggle />
</Stack>
</div>
)
}
export default Home
サンプルでは、Mantine のテーマのカラースキーマを変更できるボタンを設定しています。
ボタンをトグルすると Dark Mode <-> Light Mode の切り替えができれば、 Mantine が機能しています。Welcome to..
の文字が太字で、グレーになっていれば Tailwind CSS が機能しています。
おつかれさまでした🍀
Tail 🐈
今回は、Nextjs を起点に Mantine と Tailwind CSS を組み合わせて、開発しやすい環境を構築してみました。
Mantine と Tailwind CSS はとても自由度が高く使いやすい組み合わせだと思うので、
ぜひ、それぞれのドキュメントをみて、色々なコンポーネントを試してみてください!
最後まで見ていただいてありがとうございました!
Bye! 👋
Refs
Discussion