ViteでReactプロジェクトを作成する方法
はじめに
Reactの旧ドキュメントでは、Reactプロジェクトのセットアップ方法として、npxコマンドのcreate-react-app
が案内されていました。私も初めてReactに触れた時は、このコマンドでセットアップしていました。
しかし2023年3月に新しくなった新ドキュメントでは、create-react-app
の記載はなくなってしまいました。代わりに、Next.jsやRemixといったReact用フレームワークを使ったセットアップ方法が推奨されています。create-react-app
自体はまだ使うことが出来るようですが、公式ドキュメントでも触れられていない以上、もう推奨されていないのでしょう。
じゃあ、もうフレームワークを使わないとReactが使えないのかというと、そんなことはありません。Viteというビルド・ツールが、create-react-app
の代替としてよく使われているようです。
私も最近、CSSでちょっと試したいことがあったので、Viteで素のReactプロジェクトをセット・アップしてみました。
create-react-app
と比べて、セットアップも速く、非常にサクサク動いています。なかなか快適です。
今回はViteのセットアップ方法と、簡単な使い方を解説します。
Viteとは
概要
Vite(『ヴィィッ』と発音)は、フロントエンド向けのビルド・ツールです。Vue.jsの開発者が作成しています。
create-react-app
でセットアップした場合と同じように、開発サーバやHMR(Hot Module Replacement: スクリプト等を修正した時に、ブラウザのリロード無しで変更箇所のみ描写してくれる機能)もついてきます。
Reactだけでなく、Preact、Svelte、Vue、Solid、Vanilla-JS(素のJavaScript)等でも利用することが出来ます。
ちなみに、新ReactドキュメントのReact プロジェクトを始めるでも、「Next.jsやRemixのようなフレームワークを使いたくない場合は、ViteやParcelといったツールを使えば出来るよ」といった趣旨の記載もされています。
Viteを使うメリット
create-react-app
でReactをセットアップした場合と比較して、以下のメリットがあります。
- プロジェクトフォルダが軽量
create-react-app
でプロジェクト作成すると、約320MBくらいの容量になります。環境やバージョンによって多少変わると思いますが、かなり大きいです。
Viteの場合、100MBくらいです。
create-react-app
だとJestのようなテスト用パッケージや、Babel等も一緒にインストールされますが、Viteだとインストールされません。
シンプルに必要なものだけをインストールするのがコンセプトのようですね。
- HMRやビルドが速い
速いことが公式でも推されています。私の体感ですが、確かに速く感じます。create-react-app
は遅いと言われていたので、HMRやビルドの速度で不満は感じないと思います。
セットアップ
おおまかな流れは以下のとおりです。
- プロジェクト・フォルダの作成
- パッケージのインストール
- 開発サーバを起動して確認
なお、Viteを使うためにはNode.jsのバージョン18以上が必要です。
1.プロジェクト・フォルダの作成
まずは以下のコマンドでViteのプロジェクトフォルダを作成します。
npm create vite@latest
プロジェクト名を聞かれるので、任意の名前を入力します。デフォルトはvite-projectになっています。今回はvite-blogにしておきます。
? Project name: » vite-blog
フレームワークを選びます。↓矢印キーでReactを選んでエンターを押します。
? Select a framework: » - Use arrow-keys. Return to submit.
Vanilla
Vue
> React
Preact
Lit
Svelte
Solid
Qwik
Others
TypeScriptを使うか聞かれます。今回は上から2番上のTypeScript + SWCを選びます。SWCはRustベースのコンパイラです。従来のコンパイラより高速と言われています。
? Select a variant: » - Use arrow-keys. Return to submit.
TypeScript
> TypeScript + SWC
JavaScript
JavaScript + SWC
エンターを押して確定すると、以下の指示が表示されます。
Done. Now run:
cd vite-blog
npm install
npm run dev
プロジェクト・フォルダの作成はこれで完了です。次は、上記の指示に従って依存パッケージのインストールを行います。
2.パッケージのインストール
cd vite-blog
でプロジェクトのフォルダに移動し、npm install
を実行します。
cd vite-blog
npm install
私の場合、35秒ほどでパッケージのインストールが終わりました。
added 154 packages, and audited 155 packages in 35s
37 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
これでセットアップは完了です。
ちなみに、package.jsonは以下の内容になっています。
{
"name": "vite-blog",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
"@typescript-eslint/eslint-plugin": "^6.10.0",
"@typescript-eslint/parser": "^6.10.0",
"@vitejs/plugin-react-swc": "^3.5.0",
"eslint": "^8.53.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.4",
"typescript": "^5.2.2",
"vite": "^5.0.0"
}
}
React以外は、ViteとTypeScriptとEslint関連のパッケージのみなので、だいぶシンプルですね。
3.開発サーバを起動して確認
後は開発サーバを起動させ、セットアップが正常に終わっているか確認します。
npm run dev
を入力し、テンプレートのページがブラウザで表示されればOKです。
> npm run dev
VITE v5.0.2 ready in 506 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
localhostのポート5173で起動したことが分かります。Viteではデフォルトのポートは5173になっています。後述しますが、後から変えることができます。
リンクをクリックしブラウザでhttp://localhost:5173/
を開くと、ちゃんとテンプレートのページが表示されました!
エラーが出る場合
セットアップ後、場合によってはvite.config.tsに以下のエラーが表示される場合があります。
Cannot find module '@vitejs/plugin-react' or its corresponding type declarations.
もし出た場合、エディタを開きなおすと解消する場合があります。
それでも解消しない場合、vite.config.tsを開き、2行目を確認してください。
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc' // ←ここ
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
})
「TypeScript + SWC」を選択している場合、2行目はimport react from '@vitejs/plugin-react-swc'
になっている必要があります。
もし'@vitejs/plugin-react'
になっていたら、-swcをつけて下さい。
再現方法は分かっていないのですが、環境なのかバージョンなのか、稀に -swcがつかない場合があるようです。
なお、SWCが無いほうの「TypeScript」を選択している場合は、import react from '@vitejs/plugin-react'
で正しいです。念のため。
フォルダ構成
セットアップが完了した状態のフォルダ構成です。
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2023/11/27 23:10 node_modules
d----- 2023/11/27 23:07 public
d----- 2023/11/27 23:07 src
-a---- 2023/11/21 22:40 436 .eslintrc.cjs
-a---- 2023/11/21 22:40 253 .gitignore
-a---- 2023/11/21 22:40 366 index.html
-a---- 2023/11/27 23:08 88653 package-lock.json
-a---- 2023/11/27 23:07 750 package.json
-a---- 2023/11/21 22:40 1300 README.md
-a---- 2023/11/21 22:40 605 tsconfig.json
-a---- 2023/11/21 22:40 213 tsconfig.node.json
-a---- 2023/11/27 23:07 167 vite.config.ts
直下のファイル
ESLint、TypeScriptのconfigファイルに加え、Viteのconfigファイルも作成されています。私もまだ試せていませんが、Viteのconfigファイルでプラグインを指定することで、機能の拡張が行えます。
後は、README.mdとか.gitignoreのようなファイルです。
基本的には、create-react-app
でフォルダを作成した場合と大きな違いはありません。
index.htmlについて
create-react-app
の場合と1つ異なるのは、Reactのエントリーポイントとなるindex.htmlが、publicフォルダ内ではなく、プロジェクト直下に配置されていることです。
Viteのドキュメントにも、これは意図的なものと記載されています。publicフォルダに移さないようにしましょう。
セットアップ直後のindex.htmlは以下の内容になっています。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
faviconやタイトル等を変えたい場合は、このhtmlを修正すればOKです。viewportのようなmetaタグもあらかじめ設定されています。
後、<html lang="en">
は日本人なら"ja"に修正しておいたほうが良いかと思います。
create-react-app
の場合、index.html内にpublicフォルダのパスを指す %PUBLIC_URL% 変数がありましたが、Viteの場合は存在しません。publicフォルダのファイルは、上記の <link> タグのhref属性のように「/パス名」で指定します。例えば、publicフォルダ直下にあるvite.svgファイルならば、「/vite.svg」と記述すればOKです。
publicフォルダ
画像やCSS等、クライアント側から取得可能な資産を配置するフォルダです。外部から参照な可能なフォルダとなります。
デフォルトではfaviconとして使われているvite.svgが配置されています。
ReactであればCSSや画像はimportできるので、直接ここに配置するのはfaviconやrobots.txt等、特殊なファイルが中心になるかと思います。
上述のとおり、クライアント側からpublicフォルダのファイルにアクセスする場合、「/パス名」で指定します。
srcフォルダ
セットアップ直後のsrcフォルダの構成です。
C:.
│ App.css
│ App.tsx
│ index.css
│ main.tsx
│ vite-env.d.ts
│
└─assets
react.svg
Reactのソース関連ファイルが格納されています。初期で入っているのはテンプレート・ページのソースです。
vite-env.d.tsはvite用に定義した環境変数について与える型情報ファイルとなります。私もまだ深く触れられていないため、今回は割愛します。
後は、通常のReactのプロジェクトと扱いは同じです。main.tsxがエントリポイントです。プロジェクト・フォルダの直下のindex.htmlの<div id="root"></div>
に対応しています。
main.tsxの中身は以下のようになっています。
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
直下のindex.cssやApp.tsxをimportして使っています。いずれもテンプレートのものなので、不要であればファイルごと削除してしまい、自身のコンポーネントやCSSに差し替えていきましょう。
create-react-app
の場合、ファイル名はindex.tsxで作成されていましたが、中身と役割は同じですね。
assetsサブフォルダもありますが、テンプレート・ページで使われているReactロゴのsvgファイルが入っているだけです。
基本的な使い方
次に基本的な使い方を見てみます。
私が使ったものを中心に紹介しますが、他にもたくさんあるので詳細はドキュメントをご確認ください。
開発サーバを起動
以下のコマンドで開発サーバを起動します。
npm run dev
デフォルトだとport5173で稼働します。後はブラウザでhttp://localhost:5173/
を開けば作ったページの確認ができます。
余談ですが、実際に実行されているのはvite
コマンドです。package.jsonを見れば分かります。
{
"scripts": {
"dev": "vite",
...
}
}
node_modules/.bin
フォルダの中にスクリプトが格納されています。
ビルド
以下のコマンドでビルドできます。
npm run build
ビルドすると、プロジェクト直下にdistフォルダが作成され、ビルド後のファイルが格納されます。
セットアップ後の状態でビルドすると、distフォルダの中身は以下のようになっていました。
C:.
│ index.html
│ vite.svg
│
└─assets
index-4sK4E3Wk.css
index-YnIXOLyF.js
react-h3aPdYU7.svg
index.htmlやfaviconの画像に加え、assetsサブフォルダ内にJavaScriptファイルや、JavaScript内でimportしていたロゴの画像やcssが入っていることが確認できます。
本番にデプロイする際は、このdistフォルダをまるっとコピーすることになるかと思います。
ポート変更
開発サーバのportを変更したい場合、プロジェクト直下のvite.config.tsで指定します。
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
// serverオプションを追加
server: {
// port番号を指定
port: 5000,
}
})
server:{port:5000}
を今回追加しています。
これで開発サーバを起動すると、ちゃんとport5000で稼働しているのが分かります。
> npm run dev
> vite-blog@0.0.0 dev
> vite
VITE v5.0.2 ready in 576 ms
➜ Local: http://localhost:5000/
➜ Network: use --host to expose
➜ press h + enter to show help
指定したportが既に使われている場合、空いているportで稼働します。
- ドキュメント:server.port
publicフォルダを変えたい
クライアント側からアクセスできる静的(static)なフォルダは、デフォルトではpublicフォルダです。
別のフォルダに変えたい場合、vite.config.tsで指定します。publicでなく、staticという名前のフォルダにしたい場合、以下のように指定します。
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
// 絶対パス、もしくはプロジェクトフォルダからの
// 相対パスで指定
publicDir: "./static"
})
publicDir
にstaticにしたいフォルダ名を指定しています。今回はプロジェクト・フォルダからの相対パスで指定していますが、絶対パスでも大丈夫です。
これでプロジェクト直下のstaticフォルダがクライアント側からアクセスできる静的なフォルダになります。
- ドキュメント: publicDir
別のデバイスからアクセスしたい
スマホやタブレットでの見栄えを確認するために、開発サーバに別端末からアクセスしたい場合もあると思います。
デフォルトでは、別端末からのアクセスは出来ないように制限されているので、vite.config.tsを修正するか、開発サーバ起動時のオプションを指定する必要があります。
なお、前提として同じネットワークに接続している端末である必要があります。
vite.config.jsを修正する場合
server:{host:true}
を設定すればOKです。
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
// 別端末からアクセスを許可
server: {
host: true,
}
})
これで開発サーバを起動すると、urlが3つ表示されます。
>npm run dev
> vite-blog@0.0.0 dev
> vite
VITE v5.0.2 ready in 599 ms
➜ Local: http://localhost:5173/
➜ Network: http://192.168.0.23:5173/
➜ Network: http://172.28.128.1:5173/
➜ press h + enter to show help
真ん中のurl(私の場合、http://192.168.0.23:5173/
)を別のデバイスのブラウザに打ち込むと、ちゃんとページが表示されました。
3つ目のurlは良く分かっていません、、、別端末から開くことは出来ませんでした。ipconfigで確認すると、「イーサネット・アダプター」のIPv4と一致していました。有線で繋げている場合に使うのでしょうかね。ご存知の方いたら教えてください。
- ドキュメント:server.host
開発サーバ起動時のオプションで対応する場合
開発サーバを起動で記載したとおり、npm run dev
で実行されるコマンドはvite
です。
このコマンドに--host
オプションをつければ別端末からアクセスすることができます。
package.jsonで、コマンドにオプションを追加します。
{
"scripts": {
"dev": "vite --host",
...
}
}
scriptのdevを、vite --host
に修正しています。これでnpm run dev
したときに、vite --host
とオプション付きで実行されるようになります。
この状態で開発サーバを起動すると、同じようにurlが3つ表示されるので、2つ目のurlを別端末のブラウザに打ち込めば、ページが表示されます。
>npm run dev
> vite-blog@0.0.0 dev
> vite
VITE v5.0.2 ready in 599 ms
➜ Local: http://localhost:5173/
➜ Network: http://192.168.0.23:5173/
➜ Network: http://172.28.128.1:5173/
➜ press h + enter to show help
「毎回オプション付きで起動するのは嫌だ!1回ぽっきりでいいんだ!」という場合は、package.jsonは修正せずに、以下のコマンドで開発サーバを起動すればOKです。
npm run dev -- --host
コマンド実行時にオプションを渡しているので、その回限りで別端末からアクセス可能になります。
Webサーバのエンドポイントと連動させる
vite.config.tsにproxy設定を行うことで、ViteのプロジェクトからWebサーバのエンドポイント向けにリクエストを投げることができます。Webサーバとの連動を確認したい時に便利です。
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
proxy: {
// http://localhost:5173/api/test -> http://localhost:3000/api/test
"/api/test": "http://localhost:3000",
}
}
})
server:{proxy:{"vite側":"サーバ側"}}
で指定しています。
仮に、Vite開発サーバがport5173、Webサーバがport3000で稼働していた場合、上記の設定だと http://localhost:5173/api/test
へのリクエストはhttp://localhost:3000/api/test
にリダイレクトされます。
Vite側で、fetch("/api/test")
とすれば、Webサーバ側の /api/test
エンドポイントの処理が実行されます。
以下のように正規表現を使うことも可能です。1つ1つリダイレクト先を追加するのが面倒な場合は使えると思います。
export default defineConfig({
plugins: [react()],
server: {
proxy: {
"^/api/.*": "http://localhost:3000",
}
}
})
正規表現を使う場合、バージョンにもよるかもしれませんが、冒頭に^(キャレット)が必要です。上記は「/api/任意の1文字以上」という表現になります。
これで、以下のようにリダイレクトされます。
/api/test
->http://localhost:3000/api/test
/api/foo/bar
->http://localhost:3000/api/foo/bar
proxy設定は、あくまでVite側のリクエストをWebサーバ側にエンドポイント単位でリダイレクトする機能です。ViteとWebサーバをそれぞれ起動しておく必要があります。
加えて、Webサーバ側はVite外のプロジェクトなので、Webサーバ側からViteのエントリポイント(index.html)を返すことは出来ません。Webサーバ側からはVite側のbundlerやTypeScript等のconfigは見えないので、Viteプロジェクトのコンパイルができないからですね。
vite-expressのようなプラグインを利用すれば、Webサーバ側の処理とViteを統合することも出来るようです。HMRも効くようなので、便利そうですね。試す機会ができたら、別途記事にしたいと思います。
そもそも素のReactプロジェクトは必要か?
React公式ドキュメントから素のReactプロジェクトのセットアップ方法が消えたことについて、様々な意見が出ていました。余談として、私の意見も述べたいと思います。
上述のとおり、公式ではNext.jsやRemixのようなフレームワークを使ったセットアップが推奨されています。
確かに、素のReactだとSPA(シングル・ページ・アプリケーション)になり、複数ページのルーティングは出来なくなります。JavaScriptのサイズも大きくなり、ページの初期表示に時間がかかるようになってしまいます。公式ドキュメントに記載のとおり、結局フレームワークが必要になるケースは多いと思います。事実、このサイトも素のJavaScript→React→Next.jsと移行してきています。
しかし、React初心者がいきなりフレームワークから始めるのは、ちょっとハードルが高い気がします。フレームワーク固有で覚えなければならないことも多いので、Reactと並行して覚えるのは心が折られそうです。私も、初めにReactを触れていたからこそ、Next.jsに移行する際に、SSGのような固有の機能に集中できたのだと思っています。
なので、はじめてReactを触れる場合などに、素のReactを使うニーズはあると私は感じます※。Viteはそういう時にcreate-react-app
の代わりに使えると思います。
※「はじめてでもNext.jsやRemixのようなフレームワークを使うべし」という意見もあると思います。確かに、ReactにServer Componentが導入され、Next.jsのようなフレームワーク側の実装に依存する機能も大きくなったのも事実かと思います。上記はあくまで私の意見ということでよろしくお願いします。
最後に
Viteのセットアップ方法と基本的な使い方を解説しました。
私もまだCSSを試すために簡単な使い方をしただけですが、セットアップもHMRも速いので快適に使えています。個人的には、create-react-app
より容量を食わないのが嬉しいです。PCの容量をあまり気にせず気軽にセットアップできるのは魅力です。
他にも、.envファイルで環境変数を設定する等、まだ触れられていない機能がたくさんあります。便利な機能を見つけたら、適宜この記事に追加していきます。
サードパーティ製のプラグインも豊富なようなので、機能拡張もいろいろできそうです。触れる機会があったら、また記事にしてみたいと思います。
参考
- Vite: https://ja.vitejs.dev/
- Awesome Vite: https://github.com/vitejs/awesome-vite
- 旧Reactドキュメント: https://ja.legacy.reactjs.org/
- 新Reactドキュメント: https://ja.react.dev