続・ViteでTailwind+TypeScriptを用いたReact開発環境の構築
投稿日: 2024年10月20日
この記事は前回投稿のつづきで、Viteで構築したReact開発環境を、より快適にするための設定を解説します。開発サーバのポート番号の変更や、ESLintのカスタマイズ、Tailwind CSSのクラスの自動並び替えなどを取り上げます。
Viteで構築したプロジェクトは、デフォルト設定だと開発モード(npm run dev
で起動)のサーバが5173番ポートで起動します。このポート番号はvite.config.ts
から任意に設定することができます。第10章から使用するNext.jsでは、3000番ポートで開発サーバが起動するので、それにあわせて、ここでも3000番ポートで開発サーバが起動するように設定を変えてみます。
プロジェクトフォルダの直下にあるvite.config.ts
を、次のように変更してください。
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
server: {
port: 3000, // デフォルトのポートを3000に設定
strictPort: false,
open: true,
},
});
VSCodeのターミナルから npm run dev
を実行し、3000番ポートで開発サーバが起動することを確認してください。
またopen: true
を設定したことにより、ウェブブラウザも自動起動するようになっています。さらにstrictPort: false
の設定により、3000番ポートが他のアプリで既に使われている場合、3001での起動が試されます。同様に、3001がダメなら、3002、3003…と起動が試行されます。
ESLint 関連のカスタマイズ(設定変更)について簡単に説明しておきます。前回記事で作成したsrc/App.tsx
を開いて、以下のように const hoge = "Hoge";
という文を追加してみてください。
import { useState } from "react";
const App = () => {
const hoge = "Hoge"; // ■■■ 追記 ■■■
const [count, setCount] = useState(0);
const countUp = () => {
const newCount = count + 1;
setCount(newCount);
};
return (
<div className="mx-4 md:mx-auto mt-10 max-w-2xl">
<h1 className="font-bold text-2xl mb-4">TodoApp</h1>
<button
className="bg-blue-500 hover:bg-blue-700 text-white py-2 px-4 rounded-md"
onClick={countUp}
>
count is {count}
</button>
</div>
);
};
export default App;
すると、この文が次のように「エラー」の扱いになってしまいます🤮。
'hoge' is assigned a value but never used. eslint@typescript-eslint/no-unused-vars 'hoge' が宣言されていますが、その値が読み取られることはありません。ts(6133)
ただし、この状態でも開発モード(npm run dev
)で起動した開発サーバでは問題なくページが表示されます。これは、このエラーがESLintとしてのエラーであって、実行時エラーではないためです。
一方で、ビルド(npm run build
)をすると、明確なエラーとして処理が中断されてしまいます。当然、dist
フォルダにもビルドしたファイルが出力されません。
このように開発モードでの実行には問題がないものの、本番用にビルドすると失敗するということは多々あります。そのため、VSCodeでエラー(赤色波線)になっている箇所は放置せずに修正し、また定期的にnpm run build
を実行することをお勧めします。アプリが完成したぞ~😄と思っていたのに、大量のビルドエラーでデプロイに失敗すると精神的なダメージが大きいです😱😱😱。
・・・とはいえ「hoge
が宣言されていますが、その値が読み取られることはありません」のような軽微なコード規約違反がエラー扱いになると、開発途中では非常に不便です(特に個人開発という場面では)。例えば、npx create-next-app@latest
コマンドで作成されるNext.jsの開発環境では、変数の未使用は「エラー」ではなく「警告」という扱いになっています(警告レベルなのでビルドも可能です)。このように、Viteで構築されるデフォルト環境のESLintの設定は少し厳しいものになっています。
ということで、「変数の未使用」が「エラー」ではなく「警告」の扱いになるようにESLintの設定をカスタマイズしていきたいと思います。
まず、tsconfig.app.json
について、次のように変更します(変更するのはtsconfig.node.json
ではないので注意してください)。"noUnusedLocals"
と"noUnusedParameters"
の項目を変更してください。
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": false, /* 変更 */
"noUnusedParameters": false, /* 変更 */
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}
つづいてeslint.config.js
に、'@typescript-eslint/no-unused-vars': 'warn'
という設定を追加してください。追加時には、オブジェクトリテラルのフォーマットに従い、末尾にカンマを付け忘れないようにしてください。
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
export default tseslint.config(
{ ignores: ['dist'] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'@typescript-eslint/no-unused-vars': 'warn', // 追加
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
},
)
eslint.config.js
を変更して保存するときには、少し時間がかかることがあります(おそらく全てのコードが再チェックされるためだと思います)。
以上の設定を済ませると、src/App.tsx
のconst hoge = "Hoge";
のところが警告の扱い(赤色の波線から黄色の波線の表示)に変わっていることが確認できると思います。またnpm run build
を実行しても、エラーで中断されることなくビルドが完了すると思います。
このようにLint関連のカスタマイズはeslint.config.js
とtsconfig.app.json
でできることを知っておくと役立と思います。
Tailwindを使用する場合、次のようにJSXタグのclassName
属性に多数のユーティリティクラスを列挙することになります。
<h1 className="font-bold text-2xl mb-4">TodoApp</h1>
リンターであるESLintの設定とフォーマッターであるPrettierの設定をカスタマイズすることで、これらのクラスについて自動で並び替えすることが可能になります(コードの可読性と一貫性が向上します)。
まず、準備として、VSCodeの拡張機能であるPrettier(識別子:esbenp.prettier-vscode
)と、ESLint(識別子:dbaeumer.vscode-eslint
)をあらかじめインストールしておいてください。
そのうえで、次のようにprettier
とeslint-plugin-tailwindcss
という開発用のパッケージをプロジェクトにインストールします。
npm i -D prettier eslint-plugin-tailwindcss
つづいて eslint.config.js
を次のように変更してください。
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";
import tailwind from "eslint-plugin-tailwindcss"; // 追加
export default tseslint.config(
{ ignores: ["dist"] },
{
extends: [
js.configs.recommended,
...tseslint.configs.recommended,
...tailwind.configs["flat/recommended"], // 追加
],
files: ["**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
"@typescript-eslint/no-unused-vars": "warn",
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
},
}
);
さらに、プロジェクトフォルダの直下に.vscode
フォルダを作成して、そのなかにsettings.json
を新規作成し、次の内容を記述してください。
{
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"editor.formatOnType": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": ["source.fixAll.eslint"]
}
以上で設定が完了です。
VSCodeでsrc/App.tsx
を開くと、以下のようにclassName
属性に警告(黄色の波線)が表示されています。これはTailwindユーティリティクラスの「並び順がよくないよ」という警告です。
この警告状態のまま、保存操作をすると次のように自動でクラスの並び替えをしてくれます🦖