LoginSignup
1
6

More than 1 year has passed since last update.

reactで開発中のアプリケーションのビルド基盤をcreate-react-appからviteに移行した

Last updated at Posted at 2023-01-06

まえがき

現在、業務でtoB向けサービスの開発を行なっています。
このプロジェクトのフロントエンドはReact+typescriptで構築されており、ビルド基盤はcreate-react-app(CRA)を利用しています。

この度、このプロジェクトのビルド基盤をCRAからViteへ移行したため、その記録を書いていきます。

Viteとは

公式サイトより

Vite(フランス語で「素早い」という意味の単語で /vit/ ヴィートのように発音)は、現代の Web プロジェクトのために、より速く無駄のない開発体験を提供することを目的としたビルドツールです。2 つの主要な部分で構成されています:

  • 非常に高速な Hot Module Replacement (HMR) など、ネイティブ ES モジュールを利用した豊富な機能拡張を提供する開発サーバ。
  • Rollup でコードをバンドルするビルドコマンド。プロダクション用に高度に最適化された静的アセットを出力するように事前に設定されています。

CRAを使用している場合、コード量が増加するにつれてビルド時間も増加してしまうという問題点があります。
Viteであればその問題点を解消できる(コード量が増えても高速でビルドできる)ので、開発効率を高めるためにも移行を決定しました。

プロジェクトについて

モノレポで開発を行なっています。
ディレクトリ構成は以下の通りです。

project
  ┣━ client … フロントエンド
  ┣━ server … bff
  ┣━ hasura … バックエンド(データベース)
  ┗━ sharedTypes … フロントエンド、バックエンドの両方で使用する型を置いておくディレクトリ

Viteへの移行は、clientディレクトリで行いました。

バージョンは以下の通りです。

  • react: 17.0.2
  • typescript: 4.1.2
  • vite: 2.9.5

移行にあたってやったこと

パッケージの整理

必要なパッケージ

  • vite
  • @vitejs/plugin-react

この2つをインストールするために、
yarn add -D vite @vitejs/plugin-reactを実行します。

不要になるパッケージ

  • react-scripts

これを削除するために、yarn remove react-scriptsを実行します。

package.jsonのscriptsの修正

package.jsonのscriptsを以下のように修正しました。

- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
- "eject": "react-scripts eject",
+ "start": "vite",
+ "build": "tsc && vite build",

このプロジェクトがモノレポであるが故に、scriptsを後に修正する必要があるとは、今はまだ知る由もなかった…

vite.config.tsの作成

clientの直下(package.jsontsconfig.jsonと同じ階層)に、vite.config.tsファイルを作成します。

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';

export default defineConfig({
  server: {
    host: true,
    open: true,
  },
  resolve: {
    alias: {
      src: path.resolve(__dirname, './src/'),
    },
  },
  build: {
    outDir: 'build',
  },
  plugins: [react()],
});

  • server.host
    こちらのDiscussionsによると、ファイルシステムを外部に公開するために必要なようです(曖昧)。
  • server.open
    trueにしておくと、サーバーを起動した時に自動でブラウザを開いてくれるようになります。
  • resolve.alias
    絶対パスを使用するために設定しました(曖昧)。
  • build.outDir
    ビルドされたファイルを出力するディレクトリ名を設定する項目です。
    CRAでのビルドファイルの出力先がbuildであるため、それに合わせてbuildに設定しました。
    (Viteでのビルドファイルの出力先は、デフォルトではdist)

index.htmlの修正

client/publicにあるindex.htmlを、client直下に移動します。

そして、index.htmlにscriptタグを追加します。

<body>
  <noscript>JavaScriptを有効にしてください</noscript>
  <div id="root"></div>
+  <script type="module" src="/src/index.tsx"></script>
</body>

また、<link />タグのhrefから%PUBLIC_URL%を削除します。

- <link rel="icon" href="%PUBLIC_URL%/favicon.svg" type="image/svg+xml" />
- <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
+ <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
+ <link rel="manifest" href="/manifest.json" />

環境変数の変更

CRAの場合はREACT_APP_で始まる環境変数を使用していましたが、ViteではVITE_で始まる環境変数を使用するため、変更します。

- REACT_APP_XXXXXX=hoge
+ VITE_XXXXXX=hoge

そして、環境変数の読み込み方法も変わります。
CRAの場合はprocess.envでしたが、Viteではimport.meta.envで読み込みを行うため、書き換えます。

- process.env.REACT_APP_XXXXXX
+ import.meta.env.VITE_XXXXXX

env.d.tsの作成

自分が定義した環境変数を読み込む際にtypescriptに自動補完してもらうために、client/srcに、env.d.tsを作成します。

interface ImportMetaEnv {
  readonly VITE_XXXXXX: string
  // その他の環境変数...
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

tsconfig.jsonの修正

tsconfig.jsoncompilerOptions.typesvite/clientを追加します。

"types": ["vite/client"]

.svg.pngなどのアセットをインポートする箇所でts2307エラーが発生していたのですが、これを追加したら直りました。

終了! と思いきや

これにて移行作業は終了です。yarn startをして、動作を確認していきます。
ローカルの開発環境では問題なく動きました。

次に、clientディレクトリをビルドして動作を確認します。
するとどうでしょう。ビルド時にエラーが出ました。

エラーの原因

エラーメッセージは

TS2307: Cannot find module 'sharedTypes/hoge/fuga' or its corresponding type declarations.

と、sharedTypesディレクトリからのインポート部分で発生していました。tsエラーですね。

sharedTypesはビルドせずにclientのビルドのみを行ったため、tscsharedTypesを見つけられなかったのが原因のようです。

エラーの修正

package.jsonのビルドコマンドからtscを削除します。

  "start": "vite",
- "build": "tsc && vite build",
+ "build": "vite build",

ビルド時のエラーは出なくなりますが、これだとtscによる型チェックが行われなくて困ってしまいます。
ですので、ビルド時ではなく開発中に型チェックを行ってもらえるようにします。

npm-run-allというパッケージ(コマンドラインツール)を使用するため、まずyarn add -D npm-run-allを実行してパッケージを追加します。
そして、startコマンドを以下のように修正します。

- "start": "vite",
+ "dev": "vite",
+ "type-check": "tsc --noEmit",
+ "start": "run-p \"dev\" \"type-check --watch\"",

(run-pは、複数のコマンドを並列実行するためのコマンドであるnpm-run-all --parallelのショートカットです)
これで、ローカルのサーバーを起動した際にtscの型チェックが行われるようになりました。

今度こそ終了!

再びビルドを行うと、今度はエラーも出ず、無事にビルドが完了しました。
デプロイされたものも問題なく動いているようですので、今度こそ晴れて終了です!

あとがき

移行作業にあたって、以下のサイト・記事を参考にしました。

1
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
6