Closed12
Next.js のプロジェクトセットアップ
プロジェクトの前提
React: 18.x
ReactDOM: 18.x
Next.js: 12.x
導入するライブラリ等
- CSSModules (Next.js にビルトイン)
- TypeScript (4.8.2)
- ESLint (8.23.0)
- Prettier (2.7.1)
- Storybook
- jest
- testing-library
- msw
プロジェクトの作成
yarn create next-app --typescript [project-name]
プロジェクト直下に src
ディレクトリを作成
作成時に生成された pages
, styles
ディレクトリを src
ディレクトリ配下へ移動
Next.js ではデフォルトで対応しており、設定等の修正は不要
絶対パス指定の設定
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",
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["src/*"]
+ },
"incremental": true
},
ESLint, Prettier の導入
インストール
yarn add -D eslint-config-airbnb @typescript-eslint/eslint-plugin eslint-plugin-unused-imports prettier eslint-config-prettier
設定ファイル
.eslintrc.js
/** @type {import('@typescript-eslint/experimental-utils').TSESLint.Linter.Config} */
const config = {
extends: ['airbnb', 'plugin:@typescript-eslint/recommended', 'next/core-web-vitals', 'plugin:import/typescript', 'prettier'],
rules: {
'arrow-body-style': 'off',
'no-restricted-syntax': [
'error',
{
selector: 'TSEnumDeclaration',
message: 'DO NOT DECLARE ENUM',
},
],
'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal', ['parent', 'sibling'], 'object', 'type', 'index'],
'newlines-between': 'always',
pathGroupsExcludedImportTypes: ['builtin'],
alphabetize: { order: 'asc', caseInsensitive: true },
pathGroups: [{ pattern: '**/**.css', group: 'index', position: 'before' }],
},
],
'react/jsx-filename-extension': [1, { extensions: ['.jsx', '.tsx'] }],
'react/jsx-props-no-spreading': 'off',
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
},
};
module.exports = config;
.prettierrc.js
/** @type {import('prettier').Options} */
const config = {
useWidth: 2,
useTabs: false,
semi: true,
singleQuote: true,
bracketSameLine: false,
trailingComma: 'es5',
};
module.exports = config;
stylelint の導入
インストール
yarn add -D stylelint stylelint-config-prettier stylelint-config-recess-order stylelint-config-standard stylelint-order
設定ファイルの追加
stylelint.config.js
/** @type {import('stylelint').Configuration} */
const config = {
extends: ['stylelint-config-standard', 'stylelint-config-recess-order', 'stylelint-config-prettier'],
plugins: ['stylelint-order'],
};
module.exports = config;
npm scripts の追記
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
+ "stylelint": "stylelint **/*.css",
+ "fix": "prettier --write src/ && next lint --fix && yarn stylelint --fix",
+ "typecheck": "tsc -p . --noEmit"
},
husky および lint-staged の追加
インストール
yarn add -D husky lint-staged
設定ファイル
.husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
- npm test
+ yarn lint-staged
package.json
"scripts": {
...
- "typecheck": "tsc -p . --noEmit"
+ "typecheck": "tsc -p . --noEmit",
+ "prepare": "husky install"
},
...
+ "lint-staged": {
+ "*.{ts,tsx}": ["prettier --write", "eslint --fix", "bash -c tsc"],
+ "*.css": ["stylelint --fix"]
+ }
CSSModules を利用する時に型を付ける
typed-css-modules を利用する
yarn add -D typed-css-modules
yarn tcm -p /path/to/**/*.module.css
とすることで定義ファイルが作成される
テストライブラリの追加
インストール
yarn add -D jest ts-jest @types/jest eslint-plugin-jest eslint-plugin-jest-dom @testing-library/jest-dom @testing-library/react @testing-library/react-hooks @testing-library/user-event @types/testing-library__jest-dom
設定ファイル(ほぼ公式に記載のママ)
moduleNameMapper
は実際のディレクトリ構成にあわせて修正する
jest.config.js
const nextJest = require('next/jest');
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: './',
});
/** @type {import(‘@jest/types’).Config.InitialOptions} */
const customJestConfig = {
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
testEnvironment: 'jsdom',
moduleNameMapper: {
// Handle module aliases (this will be automatically configured for you soon)
'^@/(.*)$': '<rootDir>/src/$1',
},
};
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig);
jest.setup.js
// Optional: configure or set up a testing framework before each test.
// If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js`
// Used for __tests__/testing-library.js
// Learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom/extend-expect'
tsconfig.jest.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"jsx": "react"
}
}
ESLint の設定追記
.eslintrc.js
extends: [
'plugin:react/recommended',
'airbnb',
'plugin:@typescript-eslint/recommended',
'plugin:import/typescript',
'plugin:storybook/recommended',
+ 'plugin:jest/recommended',
+ 'plugin:jest-dom/recommended',
'prettier',
],
...
- plugins: ['react', '@typescript-eslint', 'react-hooks'],
+ plugins: ['react', '@typescript-eslint', 'react-hooks', 'jest', 'jest-dom'],
Storybook の追加
インストール
npx sb init
Storybook の ESLint プラグイン(eslint-plugin-storybook
)をインストールするかどうかを聞かれるのでインストールしておく。
Interactions の設定
関連ライブラリを追加
# storybook を testing-library でテストするためのアドオン
yarn add -D @storybook/testing-react
# CSF3.0 の play 関数等を利用するためのアドオン
yarn add -D @storybook/testing-library
TSConfig base の導入
一番制約がきつそうな strictest
を選ぶ
(next
というものもあったが strict: false
なので却下)
以下の内容が追加される
このスクラップは2023/04/08にクローズされました