Next.jsを利用して自主開発アプリ制作を行うため、
をNext.js環境に導入したメモ。
利用したバージョン
- Next.js 11.1.2
- Chakra UI 1.6.7
- Storybook 6.3.8
Next.js + TypeScript + ESLint + Prettier環境を作る
create-next-app
によって一瞬でNext.jsの環境構築ができます。Next.jsのゼロコンフィグに慣れるとReact単体での開発がとても面倒になります……。
npx create-next-app project-name
yarn add -D typescript @types/react
pages
配下にある.jsファイルを.ts または .tsxファイルに変更してyarn dev
を叩くと、なんとtsconfig.json
の生成まで自動でやってくれます。
基本的な設定は自動生成されたもので十分ですが、私は以下の変更を加えました。
- strict モードにする
"strict": true,
- @で絶対パスインポートできるようにする
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
ESLint を追加
まずはパッケージを導入します。
yarn add -D eslint eslint-config-next
導入できたら、package.json
に以下のスクリプトを追加してコマンドを実行します。
- package.json
"lint": "next lint",
"lint:fix": "next lint --fix",
yarn lint
すると、これまた自動で.eslintrc.json
が生成されます。コンフィグはNext.js向けにカスタマイズされたルールeslint-config-next
が採用されているため、必要であれば設定を調整しておくとよいです。
prettier を追加
ここはいつもどおりの手順でOK。.eslintrc.json
を編集し、eslint-config-prettier
が読み込まれるようにしておきましょう。
yarn add -D prettier eslint-config-prettier
- .eslintrc.json
{
"extends": ["next/core-web-vitals", "prettier"]
}
- 上記の手順は公式を参考にした。
Chakra UI を導入する
Chakra UI は Emotion をベースにしたUIフレームワークで
- Emotionのお作法でTailwind CSSに近いUI設計が可能
- アニメーションライブラリとしてFramer Motionをサポートしており、凝った動きも可能
という特徴があるようです。私は使ったことがないので、この機会に学んでいきたいです。
導入方法は他のCSS in JS系ライブラリとほぼ同様で特筆すべき点はありませんが、app.tsx
のコンポーネントをChakraProvider
というコンポーネントで括るのを忘れずに。
公式での解説はこちら。
yarn add @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4
- pages/app.tsx
import { AppProps } from 'next/app';
import { ChakraProvider } from '@chakra-ui/react';
const MyApp = ({ Component, pageProps }: AppProps) => {
return (
<ChakraProvider>
<Component {...pageProps} />
</ChakraProvider>
);
}
export default MyApp;
Storybook を導入する
採用するパッケージによって設定が変わるため、少々初期設定が面倒なStorybook。
Chakra UI公式のGitHubに参考となるファイルがあるため、こちらをカスタマイズして進めていきます。
- preview.tsx
// 余計な記述を削除したのみ
import { ChakraProvider, extendTheme } from '@chakra-ui/react';
import { StoryContext } from '@storybook/react';
/**
* Add global context for RTL-LTR switching
*/
export const globalTypes = {
direction: {
name: 'Direction',
description: 'Direction for layout',
defaultValue: 'LTR',
toolbar: {
icon: 'globe',
items: ['LTR', 'RTL'],
},
},
};
const withChakra = (StoryFn: Function, context: StoryContext) => {
const { direction } = context.globals;
const dir = direction.toLowerCase();
return (
<ChakraProvider theme={extendTheme({ direction: dir })}>
<div dir={dir} id="story-wrapper" style={{ minHeight: '100vh' }}>
<StoryFn />
</div>
</ChakraProvider>
);
};
export const decorators = [withChakra];
- main.js
const path = require('path');
const toPath = (_path) => path.join(process.cwd(), _path);
module.exports = {
// Next.jsのディレクトリに合わせて変更
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
// addonsはデフォルトで導入済みのものを指定(必要に応じて書き換えてOK)
addons: [
'@storybook/addon-actions',
'@storybook/addon-essentials',
'@storybook/addon-links',
],
typescript: {
reactDocgen: false,
},
webpackFinal: async (config) => {
// TypeScriptの項目で行った「絶対パスインポート」をこちらでも有効化する
config.resolve.alias = {
...config.resolve.alias,
'@': path.resolve(__dirname, '../src'),
};
return {
...config,
resolve: {
...config.resolve,
alias: {
...config.resolve.alias,
'@emotion/core': toPath('node_modules/@emotion/react'),
'emotion-theming': toPath('node_modules/@emotion/react'),
},
},
};
},
};
おわりに
本記事では本当にただ導入しただけですが、今後は学習中のAtomic Designと組み合わせてアプリ制作を進めていきたいです。
制作の過程で他にも学びがあったら、別記事でまとめていこうと思います。