1...2の...ポカン!
私は個人開発で小さなアプリを何度もこさえることがありますが、
その度に必要なパッケージをインストールしたり、設定ファイルを書くのは面倒です。
しかも、私の脳は1つ新しいことを学ぶと1つ前のものは忘れるという仕様なので、
その都度調べるということが起きてしまいます。
私の脳みそを改造できたらいいのですが、
そんなことできるはショッカーかダイジョーブ博士ぐらいです。
なので代替案としてテンプレを作っておいて、いつでもそれを使えるようにしておこう!
という目論見で開かれたのがこの会です。
参加者は私一人です。
それではいきましょう。
Nextにパッケージ何入れようかサミット
厳重な審査の結果、今回の雛形に選ばれたのは以下のパッケージです。
後の章でこれらの説明や、導入方法について記述します。
また、これら以外にもいくつかの細かいパッケージも必要になってきますが、ここでの記載は省きます。
パッケージ名 | 説明 | 備考 |
---|---|---|
Typescript | みんな大好きTypescript | |
ESLint | js/tsのファイルの書き方を監督してくれる人 | リント用 |
Prettier | コードを綺麗にしてくれる人 | 整形用 |
StyleLint | スタイルの書き方を監督してくれる人 | リント用 |
CommitLint | commit messageの書き方に口出ししてくる人 | リント用 |
Sass | cssをsass形式で描けるようにしてくれる人 | |
MaterialUI | コンポーネントの詰め合わせパックの人 | |
DependBot | パッケージのバージョンを新しくしてくれる人 | |
Jest | js/tsのテストをできるようにしてくれる人 | テスト用 |
StoryBook | 見た目のテストとかカタログ(jsDoc見た目版みたいな)を作る人 | テスト用 |
惜しくも今回含まれなかった方々
Redux
やRecoil
、ApploClient
とかの「データをメモリ保存する勢」や
firebase
とかaxios
とかの「非同期通信を簡単に実装します勢」も含めませんでした。
自分でサーバーを実装するか?
GraphQLを使うのか?
RESTだけでいくのか?
などの要因によって何をいれたいかは変わってくるので、ここら辺は雛形にいれなくてもいいかなと思ったからです。
また、tailwindcss
やstyled component
も含めませんでした。
個人的にCSS module
が好きなので、そちらを採用したいという結論がサミットでは出たためです。
ディレクトリ構成について
今回はAtomicデザイン
を採用します。
この構成について賛否両論ありますが、詳しい議論について私はあまり知らないので脳死でAtomicにしました。
ディレクトリはこんな感じにしています。
src
├── pages
│ ├── _app.tsx
│ ├── api
│ └── index.tsx
├── components
│ └── atoms
│ └── molecules
│ └── organisms
│ └── templates
└── styles
├── Home.module.css
└── globals.css
因みに、Nextはデフォルトでsrc
ディレクトリがないので、それを追加する必要があります。
(必要はない。私が追加したいだけ)
この先読むのが面倒くさい方へ
ここにコードがあるから、これをclone
して貰えばこのパッケージで開発を進めることができます。
StoryBook
の導入だけ私が試すとvulnerabilities
が出てしまって直せていないので、
StoryBook
込みのものはwidth_storybook
というブランチに取り分けてあります。
プロジェクトの作成
では実際にこれらを追加して行きましょう。
以下のコマンドでTypeScript
をデフォルトとするNext.jsのプロジェクトを作成します。
「すでに作成済みのプロジェクトにパッケージを追加したい」という人は飛ばして下さい。
npx create-next-app --typescript
実行したらプロジェクトの名前はどうするよ?
って聞かれると思うので、
いい感じの名前をつけておきましょう。
srcディレクトリの作成
プロジェクトが作成できたら、次にディレクトリ構造を整理しておきましょう。
前述の通り、Next.js
はデフォルトでsrc
ディレクトリが存在しないので作ってあげましょう。
と言ってもsrc
という名前のディレクトリを作って、その中にstyles
とかpages
とか入れるだけですね。components
というディレクトリも作っておくといいでしょう。
ディレクトリ構成についてはこれでOKです。
次にESLintの設定をして行きましょう。
ESLintの設定
Next.js
ではver.11
からデフォルトでESLint
が備えられるようになった
ので特にインストールする必要はありません。
なので、ESLint
の導入の手順は以下のようになります。
-
(インストール済だから不要)ESLint
のパッケージのインストール -
src
ディレクトリ配下もチェックするように設定 - 行末にセミコロン
;
がないとエラーになるように設定 -
import
文を絶対パスで記述するルールの追加 -
import
文の記述順をアルファベット順にする -
ESLint
の整形コマンドを登録しておく - (おまけ)VScodeのESLint拡張機能を追加する
src
ディレクトリ配下もチェックするように設定
lint
のコマンド実行時にデフォルトではsrc
ファイルディレクトリ配下は無視されます。
このままではsrc
が可哀想なので、仲間に入れてあげましょう。
package.json
のscripts
にある"lint"
の部分を以下のようにするだけです。
参考:Basic Features: ESLint | Next.js
"scripts": {
・・・
// 「--dir src」を追加
"lint": "next lint --dir src"
}
行末にセミコロン;
がないとエラーになるように設定
行末にセミコロンがなくても動きますが、「必ず全部つける」で統一しておいた方が
綺麗なのでセミコロンが無ければ、ESLintに怒ってもらうように設定します。
[ESLintのルール](https://eslint.org/docs/rules/](https://eslint.org/docs/rules/)
{
・・・
// 追記
"rules": {
// セミコロンない場合、エラー出力
"semi": ["error", "always"]
}
}
import
文を絶対パスで記述するルールの追加
import
文を記述する時に相対パスじゃなくて絶対パスで書きたいですよね。
ESLint
で絶対パスのimport
に制限するルールを追加するには
.eslintrc.json
に記述するだけでです。
"rules": {
"no-restricted-imports": [
"error",
{
"patterns": ["./", "../"]
}
]
}
ついでに、以下のように絶対パスを@/...
と書けるように設定しておきましょう。
import styles from '../styles/Home.module.css'; // こうじゃなくて
import styles from '@/styles/Home.module.css'; // こう
tsconfig.json
に以下のように記述してあげれば
@/...
をsrc/...
と解釈してくれるようになります。
"compilerOptions": {
・・・
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
importの順番をアルファベット順にする
些細なことですが、importの順番もアルファベット順だったら
気持ちいい気がするので、ESLint
にお願いしておきましょう。
.eslintrc.json
を以下のようにするだけです。
{
"extends": [
・・・
// 追記
"plugin:import/recommended",
"plugin:import/warnings"
],
"rules": {
・・・
// import の順番をルール化
"import/order": [
"error",
{
"alphabetize": {
"order": "asc"
}
}
]
}
}
ESLint
の整形コマンドを登録しておく
ESLint
に従ってコードを整形してくれるコマンドをpackage.json
に追加しておきましょう。
commit時に自動でチェック・修正してくれる設定は後述。 その際にここで定義したコマンドを呼ぶようにするので、 ここで登録しておくのがいいかも。
"scripts": {
・・・
// 以下を追加
"lint:fix": "eslint src --ext .js,jsx,.ts,.tsx --fix"
}
これでnpm run lint:fix
を実行すれば、綺麗に整形されるようになっているはずです。
(おまけ)VScodeのESLint拡張機能を追加する
VSCodeの場合は以下の拡張機能を入れるとリアルタイムでLintが適用され、
書き方が規則に則っていない場合には警告やエラーが表示されるようになります。
Prettier
の設定
Prettier
はコードを綺麗に整形してくれる人です。
同じくESLintも綺麗にする能力に長けていますが、
Prettier
先生にしかできない整形があったりするらしいので、この先生も入れます。
Prettier
導入の手順は以下の通り。
-
Prettier
に必要なパッケージをインストール -
Prettier
とESLint
が共存できるような設定の追加 - (おまけ) VScodeの
Prettier
の拡張機能を追加 - (おまけ)
Prettier
拡張機能用の設定を記述
Prettier
に必要なパッケージをインストール
さて、Prettier
をインストールして行きます。
因みにESLintとPrettierは基本仲良しですが、お互いのこだわりが異なる部分では
喧嘩するらしいので、喧嘩しないように気を遣ってくれるeslint-config-prettier
も入れておきます。
npm install -D prettier eslint-config-prettier
Prettier
とESLint
が共存できるような設定の追加
Perttier
とESLint
が喧嘩しないように、設定を追加して行きます。
.eslintrc.json
のextends
の部分にprettier
を加えてあげましょう。
"extends": ["next/core-web-vitals", "prettier"]
これだけです。
(おまけ) VScodeのPrettier
の拡張機能を追加
VScodeを使っている人は、Prettier
の拡張機能を導入しておくことで、
保存時に自動的に整形してくれるようになります。
(おまけ)Prettier
拡張機能用の設定を記述
VScodeのPrettier
拡張機能を入れたら、package.json
にその設定を書きます。
Prettier
における設定はVSCode上でも設定できます。
ですが、チーム開発する場合を考慮して、コードに残しておくのがいいと思います。
package.json
が汚くなるのがいやという人は
.prettierrc
という設定ファイルを別途書いてもいいです。
・・・
"prettier": {
"trailingComma": "all",
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"jsxSingleQuote": true,
"printWidth": 100
}
上記コードの各プロパティの説明
プロパティ名 | 説明 |
---|---|
trailingComma | 末尾のカンマあり |
tabWidth | tabの長さを定義 |
semi | セミコロンの有無 |
singleQuote | シングルクォーテーションに統一するか |
jsxSingleQuote | jsx もシングルクォーテーションに統一するか |
printWidth | 1行の最大文字数 |
Prettier
の設定はここまでです!
お疲れ様です!
Stylelintのインストール
Stylelint
とは、スタイル(css, scss, sass)の書き方をチェックし、整形してくれる人です。
Stylelint
を導入するステップは以下の通りです。
-
Stylelint
の必要パッケージをインストール -
Stylelint
の設定ファイルを記述する -
Stylelint
のチェックコマンド・修正コマンドを追加する - (おまけ)VScodeの拡張機能を追加する
Stylelint
のインストール
以下の3つをインストールします。
パッケージ名 | 説明 |
---|---|
Stylelint | スタイルファイルの構文解析エンジン |
stylelint-config-standard | Google's CSS Style Guide や Airbnb's Styleguide などを含むスタイルガイドラインのルール |
stylelint-order | CSS プロパティをアルファベット順に並べるためのルール |
コマンドは以下の通り。
npm install -D stylelint stylelint-config-standard stylelint-order
Stylelint
の設定ファイルを記述する
次に.stylelintrc.json
という名前でファイルを作成しましょう。
このファイルに以下の設定を記述します。
{
"plugins": ["stylelint-order"],
"extends": ["stylelint-config-standard"],
"rules": {
"at-rule-no-unknown": [
true,
{
"ignoreAtRules": ["tailwind", "apply", "variants", "responsive", "screen"]
}
],
"string-quotes": "single",
"order/properties-alphabetical-order": true
},
"ignoreFiles": ["**/node_modules/**"]
}
-
plugin
: 使用したいstylelint-order
のような外部パッケージを記述する場所 -
extends
: 使用したいルールのパッケージを記述する場所 -
rules
: lintのルールを記述する場所-
at-rule-no-unknown
: 使用を許可する「標準的ではない@-規則」を記述する場所 -
string-quotes
: 統一したいクォーテーションの種類を記述する場所 -
order/properties-alphabetical-order
: CSSプロパティをアルファベット順に並べる
-
-
ignoreFiles
: lintチェックの対象外とするファイルを記述する場所
Stylelint
のチェックコマンド・修正コマンドを追加する
StyleLint
はESLinnt
同様、コマンドを打たないとチェックや修正はしてくれないので、
あらかじめ、package.json
にそのコマンドを登録しておきましょう。
commit時に自動でチェック・修正してくれる設定は後述。 その際にここで定義したコマンドを呼ぶようにするので、 ここで登録しておくのがいいかも。
以下のコマンドを追加しておきましょう。
これでnpm run lint:style
でチェックし、
npm run lint:style:fix
で整形することができるようになります。
"scripts": {
...,
"lint:style": "stylelint '**/*.{css,scss,sass}'",
"lint:style:fix": "stylelint --fix '**/*.{css,scss,sass}'"
}
(おまけ)VScodeの拡張機能を追加する
Stylelint
という拡張機能を追加します。
これでリアルタイムにStyelint
に違反している箇所を炙り出すことができます。
これでStylelint
の導入は完了です!
お疲れ様です!
git commit
時に自動でESLint
とStyleLint
をチェックする
これまで、ESLint
やStyleLint
を導入してコマンドを実行すれば、
チェックや整形ができるようにしてきました。
ここでは、git commit
した時に自動でLintの整形・チェックを行なってくれるようにします。
その手順は以下の通りです。
-
lint-stage
とhusky
をインストールする。 -
git commit
時に実行したいコマンドを登録する。 - huskyに2で登録したコマンドを呼び出すように設定
lint-stage
とhusky
をインストールする
ここでは、git commit
された時を検知し、指定したコマンドを実行してくれる
便利なパッケージ達であるhusky
とlint-stage
をインストールしておきます。
パッケージ名 | 説明 |
---|---|
lint-stage | stageされたファイルだけをチェックする |
husky | commitを検知して特定のコマンドを実行させる |
インストールコマンドは以下の通りです。
npm install -D husky lint-stage
git commit
時に実行したいコマンドを登録する
git commit
したら
1. ESLint/StyleLintでコードを整形する
2. 整形した上で、各Lintに引っかかる構文がないか?をチェック
の2つが実行されるようにして行きたいと思います。
そのために、package.json
に以下のコマンドを追加しましょう。
"scripts": {
...,
"lint": "eslint src --ext .js,jsx,.ts,.tsx",
"lint:fix": "eslint src --ext .js,jsx,.ts,.tsx --fix",
"lint:style": "stylelint '**/*.{css,scss,sass}'",
"lint:style:fix": "stylelint --fix '**/*.{css,scss,sass}'",
// 以下を追加
"lint-staged": "lint-staged",
}
// 以下を追加
"lint-staged": {
"*.{js,ts,jsx,tsx}": [ //(js,ts系のファイルに対して実行するコマンド)
"npm run lint:fix",
"npm run lint"
],
"*.{css,scss}": [ //(スタイル系のファイルに対して実行するコマンド)
"npm run lint:style:fix",
"npm run lint:style"
]
},
husky
に上の節で登録したコマンドを呼び出すように設定
続いて、git commit
がコールされた時に実行して欲しいコマンドを登録しておきましょう。
まずは以下のコマンドを実行して下さい。
npx husky-init && npm install
すると.husky/pre-commit
というファイルができているはずです。
このファイルに先ほど作ったlint-stage
というコマンドを実行するように記述しましょう。
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run lint-staged // ここを追記
これで、git commit
を入力後すぐにリントの修正・チェックが走るようになりました。
お疲れ様です!
commitlintを導入する
commitlint
はコミットメッセージをチェックしてくれる方です。
自分の過去のコミットをみると、コメントが適当すぎでコードを見ないと
何しているか不明なことが多々ある私には必要なパッケージです。
とりわけ その他の詳細なルールなどはREADMEを見てもらうのが良さそうです。 https://github.com/conventional-changelog/commitlint/#what-is-commitlint 結構几帳面に見てくれます。一人で開発していると、ついつい「えいや!」で また、デフォルトのルールはAnglarチームの規約に則っているようなので、 https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commitsもう少し
commitlint
について知りたい人へ
commitlint
についてもう少し詳しく
commitlint
が許可するメッセージ例commitlint
を導入すると、git commit -m ...
の度に、
「コミットメッセージ」がちゃんとテンプレに沿って書かれているかな??
と見てくれます。commitlint
はデフォルトで以下のようなコミットメッセージだけを通します。title(scope): subject
// 空行
body
// 空行(省略可)
footer(省略可)
title
, scope
, subject
, body
, footer
とは何か?
param
説明
備考
title
新機能か?バグ修正か?という情報
決められた値しか受け付けない(後述)
scope
影響範囲
影響を受けたファイルやディレクトリなど
subject
何をしたのか?を一行でまとめた情報。要約的な。
body
なぜ、どのように、という詳しい情報を記述する。
数行で書いてOK
footer
チケット番号とか。備考を書くみたい。
なくてもOK
title
は以下の値しか受け付けないので、注意しましょう。
param
説明
build
ビルド関係
ci
CI関係
chore
雑事、タイポ修正とか軽微なものなど。
docs
ドキュメント更新/追加/修正
feat
新機能の追加
fix
バグフィックス
perf
パフォーマンス
refactor
リファクタリング
revert
コミット取り消し(git revert)
style
コードスタイル
test
テスト
その他のルール
自分でルールをカスタムできるみたいなので、お好きにどうぞ。
commitlint
に関する雑な感想
適当なメッセージを残してしまうことがあるのでその抑止力になっていい気がします。
特にこだわりがなければデフォルトのまま使っちゃっていいのかなと思います。
commitlint
導入のステップは以下の通りです。
-
commitlint
に必要なパッケージをインストール -
commitlint
の基本設定を記述 -
commitlint
を実行するコマンドを登録する -
commitlint
をcommit
メッセージ入力後に実行させるように設定
commitlint
に必要なパッケージをインストール
以下のコマンドでcommitlint
をインストールします。
npm install -D @commitlint/{cli,config-conventional}
以下のコマンドでインストールできます「
git commit
時に自動でESLint
とStyleLint
をチェックする」を読み飛ばした方へ
commitlint
単体では、「commit
された時に発動する!」という能力が使えないので
二人の助っ人も導入しましょう。lint-stage
さんとhusky
さんです。
パッケージ名
説明
lint-stage
stageされたファイルだけをチェックする
husky
commitを検知して特定のコマンドを実行させる
npm install -D husky lint-stage
commitlint
の基本設定を記述
commitlint
の設定をpackage.json
に記述します。
{
...,
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
}
}
なお、package.json
に書きたくない!という人は
.commitlintrc.json
というファイルを別途作成し、そこに記述してもOKです。
commitlint
を実行するコマンドを登録する
commitlint
を実行するコマンドをpackage.json
に定義しておきましょう。
"scripts": {
...,
// 追記
"commitmsg": "commitlint -e $GIT_PARAMS"
},
commitlint
をcommit
メッセージ入力後に実行させるように設定
ここまでcommitlint
のインストールと設定を行なってきました。
しかし、現状git commit
を実行してもcommitlint
は発動しません。
git commit
でメッセージを入力し終えた時に、
commitlint
が実行されるように設定して行きましょう。
「「
git commit
時に自動でESLint
とStyleLint
をチェックする」を読み飛ばした方へ
git commit
時に自動でESLint
とStyleLint
をチェックする」の章で
記載したコマンドを実行していないとこの先のコマンドを実行しても
上手く動作しないと思うので以下のコマンドを実行してから先に進んでください。npx husky-init && npm install
そのためには先ほどインストールしたhusky
を使います。
まずは以下のコマンドを実行してみましょう。
npx husky add .husky/commit-msg
.husky/commit-msg
というファイルができているはずです。
このファイルは「commitメッセージを記入後に実行されるコマンドを書くファイル」です。
このファイルにpackage.json
に登録したコマンドを`記載するだけで
commit
メッセージ入力後にcommitlint
が実行されるようになります。
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run commitmsg // ここを追記
これで、commit
メッセージ入力後にチェックしてくれるようになりました。
お疲れ様です!
(番外編)VScodeの自動保存で整形するようにする。
ESLint
やStyleLint
、Prettier
をVScodeで上手に活用するための
VScodeの設定をここに記述します。
VScodeを利用している人はsetting.json
に以下を記述しておくといいでしょう。
{
// デフォルトのフォーマッタを prettier に設定
"editor.defaultFormatter": "esbenp.prettier-vscode",
// ファイル保存時、prettier による自動フォーマット
"editor.formatOnSave": true,
// ファイル保存時、ESLint による自動フォーマット
"editor.codeActionsOnSave": {
"source.fixAll": true
},
// css, scss ファイルは Stylelint でフォーマットするため、Pretteir によるフォーマットを回避
"[css]": {
"editor.formatOnSave": false
},
"[scss]": {
"editor.formatOnSave": false
},
// VS Code の CSS, SCSS の Lint オフ
// Stylelint とのバッティング回避
"css.validate": false,
"scss.validate": false
}
sass
の導入
パッケージをインストールするだけです。楽ちん。
npm install -D sass
dependabot
の導入
dependabot
はプロジェクトで利用している依存ライブラリで
新しいバージョンが出たら自動でPRを作ってくれるという優れもの。
長い間npm audit
してなかったけど、気づいたら脆弱性がたっぷり
ということにならないためにも、自動で管理してくれるdependabot
を導入しておくのは
いい選択肢なのではないでしょうか。
また、作成されたPRを条件付きの自動マージすることもできるので、
その設定方法についても記して行きます。
導入もシンプルなので、早速やって行きましょう。
dependabot
の導入手順
dependabot
に関してはパッケージを入れるではなく、
GitHubで設定するという方法で導入することになります。
導入は至って簡単。何よりもこのGif動画が一番分かりやすい。
一応画像でも示しておく。
1. GitHubへ飛んで、画面上部にあるinisights
のタブへ。
(おまけ)dependabot
で作成されたPRを自動マージしよう
.github/workflows/
のディレクトリ配下に以下のファイルを作成することで、
GitHub Actions で自動でdependabot
により作られたPRをマージしてくれます。
今回はパッチバージョンの更新だけ自動マージするように設定しましょう。
パッチバージョンとは
ver. 1.12.09 ← バージョン番号の右端。
name: Dependabot auto-merge
on: pull_request # PRが上がったら実行するで
permissions:
pull-requests: write
contents: write
jobs:
dependabot:
runs-on: ubuntu-latest # ubuntuで実行するよ
if: ${{ github.actor == 'dependabot[bot]' }} # PRあげたのがdependabotの時じゃないと実行しない
steps:
- name: Dependabot metadata
id: metadata # このstepを`metadata`って名前で参照できるようにしとこ
uses: dependabot/fetch-metadata@v1.1.1 # Dependabotが作成したPRから依存関係の情報を取得!
with:
github-token: '${{ secrets.GITHUB_TOKEN }}'
- name: Enable auto-merge for Dependabot PRs
if: ${{ steps.metadata.outputs.update-type == 'version-update:semver-patch' }} # パッチversionの更新じゃないなら処理しない。
run: gh pr merge --auto --merge "$PR_URL" # mergeするよ
env:
PR_URL: ${{github.event.pull_request.html_url}}
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
参考
- dependabot/fetch-metadata@v1.1.1とは
- GitHub Actionsのワークフロー構文
MaterialUIの導入
新しくアプリを作成する度、モーダルやボタンを一から自分で実装するのは
面倒なのですでに作成されているコンポーネントを使いまわせたらいいのになぁ
そんな欲望の末に生み出されたモンスターがMaterialUIです。(違う)
基本的なコンポーネントの集まりで、必要に応じて自分でスタイルを変更できるので、
「あ、こいつ 既存のコンポーネント使いまわしてるのバレバレw」ともなりません。
似たようなものにChakuraUIというものもあるみたいで、
こちらはコンポーネント数は少ないけどよりカスタム性に特化したライブラリのようです。
こちらも興味あるのですが、今回は私が使い慣れているMateriaUIを入れていこうと思います。
MaterialUI
のインストール
以下のコマンドでインストールしましょう。
npm install @mui/material @emotion/react @emotion/styled @mui/icons-material
MaterialUI
のスタイルを上書きした時に、上書いたCSSを優先する
自分で新たに追加したCSSよりもMaterialUIの持つスタイル情報が優先されて、
思ったように表示されないなんてことがあります。
そのようなことを防ぐために、上書きしたCSSを優先してね!という設定を行う必要があります。
やり方は簡単です。
pages
ディレクトリの下にある_app.tsx
を以下のように書き換えましょう。
import '@/styles/globals.css';
import React from 'react';
import type { AppProps } from 'next/app';
import { StyledEngineProvider } from '@mui/material/styles'; // 追加
function MyApp({ Component, pageProps }: AppProps) {
return (
<StyledEngineProvider injectFirst> // 追加
<Component {...pageProps} />
</StyledEngineProvider> // 追加
);
}
export default MyApp;
<Component {...pageProps} />
を<StyledEngineProvider>
というタグで囲っているだけですね。
これをするだけで、全てのコンポーネントで
カスタムCSSを優先するというルールが適用されることになります。
(おまけ)theme
の設定
MaterialUI
にあるコンポーネントはデフォルトで
色や文字サイズが適当な値に設定されています。
例えば、デフォルトでButton
コンポーネントはこんな色です。
前述した通り、スタイルは自分で上書きできるのですが、
全てのコンポーネントで使用しているデフォルトの色を変更してあげれば、
わざわざ上書き用のCSSを書く必要が無くなるので嬉しい訳です。
そのような時に使えるのがtheme
という訳です。
theme
はデフォルトの値が詰まっている箱みたいなもので、
この箱の値を変更してあげることで、全てのコンポーネントでそれが適用されます。
それでは実際にデフォルト値を変更してみます。
まずは好きな場所にtheme.ts
というファイルを作りましょう。
私はstyles
ディレクトリ直下に作ることにします。
import { createTheme } from '@mui/material/styles';
// Create a theme instance.
const theme = createTheme({
palette: {
primary: { // ベースカラーを真っ黒にしちゃおう。
main: '#000000'
}
}
});
export default theme;
次にこの定義したtheme
が全てのコンポーネントで適用されるようにしておきましょう。
_app.tsx
に以下を追加して下さい。
import '@/styles/globals.css';
import { StyledEngineProvider, ThemeProvider } from '@mui/material/styles'; // ThemeProvider を追加
import type { AppProps } from 'next/app';
import React from 'react';
import theme from '@/styles/theme'; // 追加
function MyApp({ Component, pageProps }: AppProps) {
return (
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}> //追加
<Component {...pageProps} />
</ThemeProvider> // 追加
</StyledEngineProvider>
);
}
これだけです。
すると先ほどのボタンは真っ黒になっていると思います。
他にもテキストの大きさなども変えることができるので、必要ろあらばいじってみて下さい。
Jest
の導入
言わずと知れたテストライブラリです。
私の個人開発だとテストは後回しになりがちですが、
いつか書きたいとい気持ちも込めて入れておきます。
結局やらないのであれば消すだけでOKなので...。
ここで紹介する導入ステップは以下の通りです。
Jest
のインストール- Jestの設定
- 仮テストの作成
Jest
のインストール
以下のコマンドを実行しましょう
npm install -D jest @testing-library/react @types/jest @testing-library/jest-dom @testing-library/dom babel-jest @testing-library/user-event jest-css-modules
色々インストールしていますが、ざっくり言うと
「Jest
で必要になるパッケージ諸々」+「テストでCSSファイルが悪さしないようにモック化するパッケージ」
をインストールしています。
Jestの設定
.babelrc
を作成する
.babelrc
という名前でファイルを作成し、以下を記入して下さい。
これは、Jest
に対して、「Next.js
のプロジェクトにテストするよ」と伝えるために必要みたいです。
{
"presets": ["next/babel"]
}
package.json
に設定を追加する
package.json
に以下の設定を追加しておきましょう。
コメントの部分は削除して下さい。
"jest": {
"testPathIgnorePatterns": [ // テストの対象外となるディレクトリを記載
"<rootDir>/.next/",
"<rootDir>/node_modules/"
],
"moduleNameMapper": {
"\\.(scss)|(css)$": "<rootDir>/node_modules/jest-css-modules", // styleファイルに関しては`jest-css-modles`を使ってモックしますよ!
"^@/(.*)$": "<rootDir>/src/$1" // import文が@で始まっていたら、それはsrcを示しているんだよ!
}
}
package.json
にテスト実行用のコマンドを追加
package.json
のscript
に以下のコマンドを追加しておきましょう。
"scripts": {
...,
"test": "jest --env=jsdom --verbose"
}
オプションは「テストファイルに対してテストが通ったかどうか?」ではなく、
「テストファイル内の全てのテストケースの結果を表示する」ために必要なものになります。
仮テストの作成
設定がうまくいっているかを確認するために、仮の簡単なテストを書いておきましょう。
まずは___tests___
というディレクトリをルートに作成しましょう。
その中に仮のテストファイルHome.test.tsx
というファイルを作成し、以下をコピペして下さい。
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import Home from '@/pages/index';
it('Should render hello text ', () => {
render(<Home />);
expect(screen.getByText('Next.js Template')).toBeInTheDocument();
});
Jest
の話もしだすと長くなってしまうので、ざっくり説明すると、
<Home>
コンポーネントの中にNext.js Template
という文字列が
あるかどうかを確認するよ!というテストコードになります。
新しく作ったNext.js
のプロジェクトにはindex.tsx
という名前のファイルが
あると思いますが、その中にHome
コンポーネントが定義されているはずです。
その中にNext.js Template
という文字列を含めておきましょう。
私は以下みたいな感じにしておきます。
...
<main className={styles.main}>
<h1 className={styles.title}>
Next.js Template /* ←ここに追加しました */
</h1>
<p className={styles.description}>
Get started by editing <code className={styles.code}>pages/index.tsx</code>
</p>
...
これでnpm run test
を実行してみて下さい。テスト通るはずです。
逆にNext.js Template
の文字を削除してテストすると
エラーが表示されると思います。
これでJestの導入は完了です!
お疲れ様でした!
StoryBookの導入
StoryBook
。それは、デザイナーとの意思疎通を容易にするべく
作成したコンポーネントのデザインを確認できるカタログを自動で生成してくれる人。
「個人開発で一人でやっているから、オイラは関係ないや。グヘヘェ」
と私は思いました。
ですがこいつは見た目のテスト
をするためにも役立つ優れものだとか。
規模が大きくなり、1つのコンポーネントを複数の場所で使っていると
いつの間にかスタイルおかしくなっている!なんてことがあります。
それを防ぐことができるというのは嬉しいもの。
導入の手順は以下の通りです。
StoryBook
のインストールStoryBook
の設定変更- カタログを作ってみる
Chromatic
のインストール- GitHub Actions の設定
StoryBook
のインストール
とっても簡単です。以下のコマンドを実行するだけ!
npx sb init --builder webpack5
こちらを実行すると以下が行われます。
- パッケージのインストール
- コマンドのエイリアスを
package.json
に登録 -
.storybook
ディレクトリと設定ファイルの作成 -
stories
ディレクトリとサンプルファイルの作成
StoryBook
の設定変更
設定を少しだけいじります。
.storybook
というディレクトリの中に.main.js
というファイルがあるはずです。
こちらに以下を追記してあげてください。
const path = require('path'); // 追加
module.exports = {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
core: {
builder: 'webpack5',
},
// ここから
webpackFinal: async (config) => {
config.resolve.alias = {
...config.resolve.alias,
'@': path.resolve(__dirname, '../src'),
};
return config;
}
// ここまで追加
};
これは、import
文が@/...
というように@
から始まっている場合でも
パスを認識できるようにするための設定です。
カタログを作ってみる
カタログを作ってみましょう。
既存のindex.tsx
で定義されているHome
コンポーネントをカタログに登録してみましょう。
まずはstories
ディレクトリの中にhome.stories.tsx
というファイルを作成し、
以下をコピペしてあげてください。
import Home from '@/pages/index';
const home = {
title: 'Pages/Home',
component: Home,
};
export const HomePage = () => <Home />;
export default home;
続いてカタログをローカルサーバーで表示させるために以下のコマンドを実行します。
npm run storybook
そしてlocalhost:6006を見てみると、
画像のようにHome
コンポーネントがカタログに表示されいるのが確認できるでしょう。
デフォルトでは、サンプルのファイルが存在しているので、画像とは違ってHomeコンポーネント以外も表示されていると思います。この画像ではそれを消した状態のものです。
ここまででひとまずStoryBook
のカタログ機能に入門することができました。
やったね☆
Chromatic
のインストール
この説ではChromatic
と呼ばれるものをインストールします。
これはStoryBookと連携して、コンポーネントの見た目の変化を検知し、
比較検証を簡単にできるようにするツールです。
まずはChromatic公式へ飛んでGet Started now
をクリック!
そのまま案内に従ってポチポチしていくと以下のような画面に行くと思うので、
自分のリポジトリを選択してさらに進みます。
少し進むと画面に表示されている2つのコマンドを実行してくれよな!
と言われると思います。以下の2つのコマンドです。
npm install --save-dev chromatic
npx chromatic --project-token=プロジェクトごとの固有の値
素直に実行してみましょう。しばらく待つと画面遷移し、以下のような画面になると思います。
すると今度は、「スタイルの違い検知してみせるから何かstyleいじってみろよ!」
と言われます。いじってやりましょう。なんでもいいのですが、
Home.module.css
をいじってみることにします。
.main {
align-items: center;
display: flex;
flex: 1;
flex-direction: column;
justify-content: center;
min-height: 100vh;
padding: 8rem 0; /* 変化させてみる 4rem -> 8rem */
}
そして再度、以下のコマンドを実行します。
npx chromatic --project-token=プロジェクトごとの固有の値
すると、Chromatic
が変更を検知してみやすく表示してくれます。
以下のような感じです。素敵です。
GitHub Actions の設定
これまでStoryBook
&Chromatic
のカッコ良いところを見てきました。
でも私の理想的なフローは以下なので、もう少し設定を頑張ります。
- GitHubでPR出した時に自動でチェック
- 意図していない時に変更が検知されたら、それをチェックする。
- 問題なければapproveしてmerge !
そのためにはGitHub Actionsでワークフローを作成する必要があります。
以下を.github/workflows/
の直下に作成しましょう!
name: Chromatic
on:
push: # pushされたら実行するよ
branches: # ブランチ名が以下じゃなければ実行しないよ
- with_storybook # ここは適宜変更して下さい
jobs:
build:
runs-on: ubuntu-latest # ubuntu環境で実行します
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- run: npm ci
- uses: chromaui/action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
このファイルで定義されているCHROMATIC_PROJECT_TOKEN
という変数の値は、
GitHubに自分で定義する必要があります。
簡単にできるので、以下の手順で進めていきましょう!
まずはGitHubのSetting
タブへ移動して下さい。
続いて、画面左側にあるSecrets
をクリック!
さらにさらに、New repository secret
をクリック。
Name
にCHROMATIC_PROJECT_TOKEN
と入力し、
value
に自分のトークンを入力してください。
これで準備は完了です!
先ほど作ったchromatic-ui-test.yml
で定義したブランチ名でpushすれば、
ChromaticUI
のチェックが実行されていることが確認できるはずです。
お疲れ様です!これでUIテストを行う環境もできました!
最後に
長かったですね。お疲れ様です。
この記事の通りに実行して行ってもnode
やnpm
,yarn
の
バージョンの違いやOSの違いなどでエラーが出てしまって「まぢムリ」
となってしまうこともあるかもしれません。
私はよくそういうことあります。
エラーが出て、先人の奮闘記からコードをコピペしたけど
やっぱり直らん。ということが。
いつになったら英語の公式ドキュメントに臆さない
キラキラスーパーエンジニアになれるのかは不明です。
今は個人開発などで色々奮闘しているので、
よかったら他の記事も見たりTwitterをフォローしてみましょう。