これは、なにをしたくて書いたもの?
少し、Reactを扱ってみたいと思いまして。
とはいえ、どこから入ったらいいのかな?ということで、今回はViteを試してみることにしました。
あまりReact自体は出てこないんですけど。
今のReactの始め方
ここでReactの新しいプロジェクトを始め方を見てみます。
If you want to build a new app or a new website fully with React, we recommend picking one of the React-powered frameworks popular in the community. Frameworks provide features that most apps and sites eventually need, including routing, data fetching, and generating HTML.
Start a New React Project – React
今はReactをベースにしたフレームワークを利用することを勧められているようです。
このページでは、Next.js、Remix、Gatsby、Expo(ネイティブアプリ向け)が挙げられています。
個人的にはまずはフレームワークなしの使い方が知りたいのですが、これについてはフレームワークの紹介の後に隠れています。
ここを開いてみると、フレームワークを使わなくてもできるけれどフレームワークの利用を勧めると書かれています。
必要になるものがいろいろ足りてないし、セットアップが必要になるけれどそれでも頑張るのならどうぞ?という感じです。
You can definitely use React without a framework—that’s how you’d use React for a part of your page. However, if you’re building a new app or a site fully with React, we recommend using a framework.
Here’s why.
〜省略〜
If you’re still not convinced, or your app has unusual constraints not served well by these frameworks and you’d like to roll your own custom setup, we can’t stop you—go for it! Grab react and react-dom from npm, set up your custom build process with a bundler like Vite or Parcel, and add other tools as you need them for routing, static generation or server-side rendering, and more.
Start a New React Project / Can I use React without a framework?
ここで、ViteとParcelが出てきます。
Vite | Next Generation Frontend Tooling
お勧めはしないぞ、とは言われているものの、まずはReactにフォーカスしたいのでViteを選んでみます。
Vite
Viteのオフィシャルサイトはこちらで、次世代のフロントエンドツールであると書かれています。
Vite | Next Generation Frontend Tooling
The State of JS 2022のビルドツールのカテゴリーでも人気のようです。
State of JavaScript 2022: Build Tools
なぜViteが良いのか?というページは、こちら。
ここを見ると、以下の特徴が謳われています。
- 開発サーバーの起動時間の短縮
- 更新(Hot Module Replacement:HMR)の高速化
- 本番環境向けのバンドル
機能についてはこちら。
- モジュールインポート
- Hot Module Replacement(HMR)
- TypeScriptのサポート
- Vue、JSX、CSS
- Static AssetsやJSONのインポート
- Globインポート、動的インポート、WebAssemblyの利用
- Web Workerのサポート
- ビルドの最適化
TypeScriptのサポートについて
TypeScriptのサポートについてはちょっと気になるので、もう少し見ておきます。
Viteは.ts
ファイルのトランスパイルのみを実行し、型チェックは行いません。型チェックはIDEやビルドプロセスで確認することを
想定しているようです。
Note that Vite only performs transpilation on .ts files and does NOT perform type checking. It assumes type checking is taken care of by your IDE and build process.
Features / TypeScript / Transpile Only
isolatedModules
、useDefineForClassFields
には注意する必要があるようです。
Features / TypeScript / TypeScript Compiler Options
その他、影響を与えるものとしてextends
、importsNotUsedAsValues
、preserveValueImports
、jsxFactory
、jsxFragmentFactory
が
挙げられています。
ViteはデフォルトでNode.js APIを使用するため、クライアント側のコードであることを示すために、以下の宣言を追加する必要が
あるようです。
/// <reference types="vite/client" />
これはtsconfig.json
でも設定できるようです。
{ "compilerOptions": { "types": ["vite/client"] } }
Features / TypeScript / Client Types
Create React Appは?
ところで、Reactを始めるのに使うのはCreate React Appだと思うのですが、こちらはどうなったのでしょう?
Reactのこちらのページには名前がありませんでした。
Start a New React Project – React
現時点での最終リリースは、2022年4月の5.0.1です。
Release v5.0.1 · facebook/create-react-app · GitHub
以下あたりも参考に。
We need regualr CRA maintainer · Issue #11180 · facebook/create-react-app · GitHub
今後は見なくなっていくツールになっていきそうですね。
話を戻して、今回はViteを使ってみます。
環境
今回の環境は、こちら。
$ node --version v18.17.1 $ npm --version 9.6.7
Viteを始めてみる
こちらを見ながら、Viteを始めてみます。
まずはViteプロジェクトを作成するようです。
テンプレートをサポートしているようで、JavaScript、TypeScriptで以下があるようです。
JavaScript | TypeScript |
---|---|
vanilla | vanilla-ts |
vue | vue-ts |
react | react-ts |
preact | preact-ts |
lit | lit-ts |
svelte | velte-ts |
solid | solid-ts |
qwik | qwik-ts |
コミュニティがメンテナンスしているテンプレートもあるようです。
GitHub - vitejs/awesome-vite: ⚡️ A curated list of awesome things related to Vite.js
今回は、React+TypeScript(react-ts
)を選んでみます。
$ npm create vite vite-getting-started -- --template react-ts
出力結果。
Scaffolding project in /path/to/vite-getting-started... Done. Now run: cd vite-getting-started npm install npm run dev
プロジェクトができたようなので、ディレクトリ内に移動してみます。
$ cd vite-getting-started
ディレクトリ内の構成。
$ tree . ├── README.md ├── index.html ├── package.json ├── public │ └── vite.svg ├── src │ ├── App.css │ ├── App.tsx │ ├── assets │ │ └── react.svg │ ├── index.css │ ├── main.tsx │ └── vite-env.d.ts ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts 3 directories, 13 files
各種設定ファイルを見てみましょう。
package.json
{ "name": "vite-getting-started", "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.15", "@types/react-dom": "^18.2.7", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", "@vitejs/plugin-react": "^4.0.3", "eslint": "^8.45.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", "typescript": "^5.0.2", "vite": "^4.4.5" } }
tsconfig.json
{ "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"], "references": [{ "path": "./tsconfig.node.json" }] }
tsconfig.node.json
{ "compilerOptions": { "composite": true, "skipLibCheck": true, "module": "ESNext", "moduleResolution": "bundler", "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts"] }
vite.config.ts
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], })
ソースコードの一部。Reactを使ったものですね。
src/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>, )
src/App.tsx
import { useState } from 'react' import reactLogo from './assets/react.svg' import viteLogo from '/vite.svg' import './App.css' function App() { const [count, setCount] = useState(0) return ( <> <div> <a href="https://vitejs.dev" target="_blank"> <img src={viteLogo} className="logo" alt="Vite logo" /> </a> <a href="https://react.dev" target="_blank"> <img src={reactLogo} className="logo react" alt="React logo" /> </a> </div> <h1>Vite + React</h1> <div className="card"> <button onClick={() => setCount((count) => count + 1)}> count is {count} </button> <p> Edit <code>src/App.tsx</code> and save to test HMR </p> </div> <p className="read-the-docs"> Click on the Vite and React logos to learn more </p> </> ) } export default App
こちらは、クライアント側であることを宣言するファイルですね。
src/vite-env.d.ts
/// <reference types="vite/client" />
Features / TypeScript / Client Types
依存関係をインストール。
$ npm i
開発サーバーを起動。
$ npm run dev
実体はvite
コマンドですね。
"scripts": { "dev": "vite", "build": "tsc && vite build", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" },
開発サーバーが起動したようです。
VITE v4.4.9 ready in 970 ms ➜ Local: http://localhost:5173/ ➜ Network: use --host to expose ➜ press h to show help
確認してみます。http://localhost:5173
へアクセスしてみます。
動作しているのが確認できました。
クリックでカウントアップするサンプルなので、少し遊んでみます。
src/vite-env.d.ts
ここで、開発サーバーを1度止めます。
今度はプロダクション用にビルドしてみましょう。
$ npm run build
出力結果。
> vite-getting-started@0.0.0 build > tsc && vite build vite v4.4.9 building for production... ✓ 34 modules transformed. dist/index.html 0.46 kB │ gzip: 0.30 kB dist/assets/react-35ef61ed.svg 4.13 kB │ gzip: 2.14 kB dist/assets/index-d526a0c5.css 1.42 kB │ gzip: 0.74 kB dist/assets/index-c7e05d32.js 143.41 kB │ gzip: 46.10 kB ✓ built in 1.37s
dist
ディレクトリ内にファイルが生成されたようです。
$ tree dist dist ├── assets │ ├── index-d526a0c5.css │ ├── index-c7e05d32.js │ └── react-35ef61ed.svg ├── index.html └── vite.svg 1 directory, 5 files
こちらを確認してみましょう。PythonのHTTPサーバーを起動。
$ python3 -m http.server --directory dist
http://localhost:8000/
へアクセスして確認。
OKですね。
HMRを確認してみます。開発サーバーを起動。
$ npm run dev
App.tsx
を以下のように修正。
<h1>Vite + React</h1>
すると、コンソールに以下のように表示され
22:14:16 [vite] hmr update /src/App.tsx
変更が反映されたことが確認できました。
あとは型チェックですが。npm run build
の時はtsc
で確認してくれますが、開発サーバーを使っている時はそうはいきません。
tsc --watch
を追加しておくのがいいでしょうか。
"scripts": { "dev": "vite", "build": "tsc && vite build", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview", "typecheck:watch": "tsc --watch" },
こんな感じで。
$ npm run typecheck:watch
まとめ
ViteでReactを使ったプロジェクトを始めてみました。このあたり、全然追っていないのでトレンドとかやり方がいまひとつわかりません。
まあ、ちょっとずつ追っていければいいかなと思います。
気長にやっていこうかなと。