実用的なVite + React + TypeScriptの開発環境の作り方

非実用的なVite + React + TypeScriptの開発環境が多い

ReactでWebサイトなどを開発する場合はVite + React + TypeScriptで開発環境を作成することが多いですが、実用的な開発環境が作られていないケースがあります。

この記事では高速かつ開発しやすいVite + React + TypeScriptの開発環境の作り方について説明します。

npmではなくpnpmを使用する

「npm create vite@latest」コマンドが使用されるケースが多いですが、高速かつ開発しやすい環境を構築するなら「pnpm create vite@latest」コマンドを使用したほうが良いです。

pnpmとは「Performant npm」の略で、高速で効率的なNode.jsのパッケージマネージャーです。

Performantには「高性能の、効率の良い」という意味があり、その名の通りnpmの上位互換です。

pnpmは高速なインストール、ディスク容量節約、依存関係の厳格管理などの特徴があるためnpmよりも優れています。

Next.jsの公式サイトのインストール手順の説明ではpnpmでのインストールがデフォルトになっています。

pnpmを使用するには事前にインストールが必要です。

brew install pnpm

インストール | pnpm

Vite + React + TypeScript 開発環境をインストール

Vite + React + TypeScript 開発環境をインストールするには以下のコマンドを実行するだけです。my-reactの部分はプロジェクトフォルダ名なので、任意の名前に変更可能です。

pnpm create vite@latest my-react --template react-ts

react-tsをreact-swc-tsにするとReact + TypeScriptをSWCでビルドする構成にできますが、Reactのメモ化を自動化するReact Compilerが使えなくなるので、SWCでインストールしてはいけません。

pnpm create vite@latestが完了したら、以下のコマンドを続けて実行することで、プロジェクトフォルダ(my-react)に移動して、パッケージのインストールが実行されます。

cd my-react
pnpm install

もし、パッケージのインストール後に以下の警告が表示されたら、「pnpm approve-builds」を実行したあとにEnterキーを押してesbuildのビルドスクリプトを承認してください。

Warning

Ignored build scripts: esbuild.                                        
Run "pnpm approve-builds" to pick which dependencies should be allowed 
to run scripts.

この警告はpnpmが安全のためにスクリプト実行をブロックするという警告ですが、esbuildは安全なので承認して問題ありません。

pnpm approve-builds

一度承認すれば、pnpm-workspace.yamlというファイルが作成されて、今後同じ警告は出ません。

pnpm-workspace.yaml
ignoredBuiltDependencies:
  - esbuild

package.jsonのpackageManagerを設定する

package.jsonのpackageManagerは、そのプロジェクトがどのパッケージマネージャ(npm / pnpm / yarn など)のバージョンを使うべきかを宣言するものです。

以下のように設定すると推奨パッケージマネージャがわかりやすくなり、npm installやyarn installを実行すると警告が表示されて、間違えてpnpm install以外のコマンドでインストールされることを防げます。

JSON
{
  "name": "my-react",
  "private": true,
  "version": "0.0.0",
  "packageManager": "pnpm@10.17.1",
  // 略
}

ESLint Stylisticでフォーマットする

インストールした開発環境にはESLintが含まれていますが、コードフォーマッターのPrettierは含まれていません。

しかし、現在ではPrettierを使用するのは好ましくないため、コードフォーマットはESLint Stylisticをインストールして行います。

ESLint Stylisticは以下のコマンドでインストールできます。

pnpm add -D @stylistic/eslint-plugin

インストールしたら、eslint.config.jsでstylisticを推奨設定(recommended)で読み込みます。

推奨設定の @stylistic/arrow-parens と @stylistic/jsx-one-expression-per-line のルールはReactとの相性が悪いので、変更して以下のような設定にします。

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 { defineConfig, globalIgnores } from 'eslint/config'
import stylistic from '@stylistic/eslint-plugin'

export default defineConfig([
  globalIgnores(['dist']),
  {
    files: ['**/*.{ts,tsx}'],
    extends: [
      js.configs.recommended,
      tseslint.configs.recommended,
      stylistic.configs.recommended,
      reactHooks.configs['recommended-latest'],
      reactRefresh.configs.vite,
    ],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
    plugins: {
      '@stylistic': stylistic,
    },
    rules: {
      '@stylistic/arrow-parens': ['error', 'always'],
      '@stylistic/jsx-one-expression-per-line': 'off',
    },
  },
])

この状態でインデントが不正、ダブルクォーテーション、セミコロンありのコードを上書き保存したら、VS CodeにESLintの拡張機能をインストールしていて、自動フォーマットがオンになっていれば以下のように自動フォーマットされます。

JavaScript
  const foo = "bar"
console.log(foo);

JavaScript
const foo = 'bar'
console.log(foo)

React Compilerをインストールする

React Compilerとはコンポーネントのコードを解析して、自動的にメモ化や最適化を行います。

これにより、memo、useMemo、useCallbackを手書きで追加して最適化する必要がなくなります。

React Compilerには以下の4つの特徴があります。

  1. React.memo、useMemo、useCallbackを書かなくても、コンパイラが依存関係を解析して不要な再レンダリングを防ぐ。
  2. コンポーネントの props や state の参照を静的に解析し、「どの値に依存しているか」を自動的に特定する。
  3. 差分検出やpropsの依存関係をもとに効率的にレンダリングされる。
  4. React.memoを書いていた場合もそのまま動作し、React Compilerの恩恵を受けられる。

これを実装するには、まずReact Compilerをインストールします。

pnpm add -D babel-plugin-react-compiler

次にvite.config.tsにbabel-plugin-react-compilerを以下のように設定して有効化します。

vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [
    react({
      babel: {
        plugins: [
          ['babel-plugin-react-compiler'],
        ],
      },
    }),
  ],
})

以上の設定により、自動的にメモ化や最適化を行うようになります。

.envも追加する

pnpm create vite@latestで作成した環境には.envが含まれていないため、自身で追加する必要があります。

touch .env
pnpm add -D dotenv
.env
MESSAGE=foobar
VITE_MESSAGE=world!

ちなみにViteはフロント側で参照する場合は「VITE_」プレフィックス付きの変数しかフロント側で参照できないので注意が必要です。

sample.mjs
import 'dotenv/config'

console.log(`Hello ${process.env.MESSAGE}`)
// Hello foobar
main.tsx
console.log(`Hello ${import.meta.env.VITE_MESSAGE}`)
// Hello world!

テスト環境も追加する

pnpm create vite@latestで作成した環境にはテストのための環境が含まれていないので、自身でインストールする必要があります。

ユニットテスト、インテグレーションテスト、E2Eテストをするのであれば、Vitest、Ajv、Playwright、@testing-library/react、@testing-library/domなどをインストールしておくと良いでしょう。

pnpm add -D vitest ajv playwright @testing-library/react @testing-library/dom

最後にGitを設定

既存の環境にはGitがないため、git initを実行してコミットしておくと良いでしょう。

最後にGitHubにプッシュしておけば完了です。

git init
git add --all
git commit -m "first commit"

話が長くなるので割愛しましたが、Storybook、Husky、GitHub ActionsでのCI設定はしていないので、これらの設定方法がわかる方は追加したほうが良いです。

# GitHub ActionsでのCI設定例
name: Lint & Type Check

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  lint:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: 'pnpm'

      - name: Install dependencies
        run: |
          corepack enable
          pnpm install

      - name: Run ESLint
        run: pnpm eslint .

      - name: TypeScript type check
        run: pnpm tsc --noEmit