viteでreact(or preact)+typescript(+tailwindcss)な開発環境を構築
吉川@広島です。
最近viteが非常に快適でハマって(良い意味の方)おり、ReactとPreactの環境構築を試してみたので備忘録がてら紹介します。
viteには
npm init vite@latest my-vue-app -- --template vue
のように自分で設定することなくscaffoldする機能があるのですが、今回はこれを使わずに構築する手順を共有したいと思います。
環境
- node 15.11.0
- yarn 1.22.10
- npm 7.18.1
- vite 2.4.4
プロジェクト作成
ディレクトリを作って入ります。
mkdir my-app cd my-app
必要パッケージのインストール
- react, react-dom (or preact)
- vite (+ @vitejs/plugin-react-refresh or @prefresh/vite)
- typescript
- @tsconfig/recommended
- @types/node
を入れていきます。viteプラグインとして、reactの場合は@vitejs/plugin-react-refresh、preactの場合は@prefresh/viteを入れます。@tsconfig/recommendedはtsconfigの設定を省力化するために採用します。@types/nodeはvite.config.tsのために入れています。
Reactの場合
yarn add react react-dom yarn add -D vite @vitejs/plugin-react-refresh typescript @types/react @types/react-dom @tsconfig/recommended @types/node
Preactの場合
yarn add preact yarn add -D vite @prefresh/vite typescript @tsconfig/recommended @types/node
configファイル作成
tsconfig.json
ts.config.jsonを作成します。
touch tsconfig.json
Reactの場合
@tsconfig/recommendedのおかげで随分楽に記述できました。
{ "extends": "@tsconfig/recommended/tsconfig.json", "compilerOptions": { "jsx": "react", "baseUrl": "./", "paths": { "@/*": ["src/*"] } } }
pathsの設定は好みですが、個人的に import { MyComponent } from @/components/my-component
のように絶対パスでimportできるようにしたいのでこのように設定しています。
Preactの場合
Reactの設定に "jsxFactory": "h"
を加えます。
{ "extends": "@tsconfig/recommended/tsconfig.json", "compilerOptions": { "jsx": "react", + "jsxFactory": "h", "baseUrl": "./", "paths": { "@/*": ["src/*"] } } }
vite.config.ts
vite.config.tsを作成します。
touch vite.config.ts
Reactの場合
import { defineConfig } from 'vite' import reactRefresh from '@vitejs/plugin-react-refresh' import path from 'path' export default defineConfig({ root: './', plugins: [reactRefresh()], resolve: { alias: { '@/': path.join(__dirname, './src/'), }, }, })
Preactの場合
- @vitejs/plugin-react-refreshの代わりに@prefresh/viteを使う
jsxFactory: 'h'
を定義する必要がある
がReactの場合との差分です。
jsxFactoryの対処を行わない場合、実行時に Uncaught ReferenceError: React is not defined
のエラーが発生します。
import { defineConfig } from 'vite' -import reactRefresh from '@vitejs/plugin-react-refresh' +import preactRefresh from '@prefresh/vite' import path from 'path' export default defineConfig({ root: './', - plugins: [reactRefresh()], + plugins: [preactRefresh()], + esbuild: { + jsxFactory: 'h', + }, resolve: { alias: { '@/': path.join(__dirname, './src/'), }, }, })
entrypointとなるindex.htmlとtsxファイルを作成
index.html
touch index.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> </head> <body> <div id="root"></div> <script type="module" src="/src/index.tsx"></script> </body> </html>
ここまで来たらあとはtsxを書くだけです。
index.tsx
mkdir src touch src/index.tsx
Reactの場合
import React from 'react' import ReactDOM from 'react-dom' ReactDOM.render(<div>Hello World</div>, document.querySelector('#root'))
Preactの場合
import { h, render } from 'preact' render(<div>Hello World</div>, document.querySelector('#root')!)
Preactの場合、renderの第2引数はnullableな値が許されないため !
が必要です(もしくは、ちゃんとnullチェック処理をする)。
ローカルサーバ起動
ローカルサーバを起動し、ブラウザで動作確認をします。
yarn vite
お疲れさまでした。
[Optional] tailwindcss
以下はさらにtailwindcssを導入したい場合の手順です。
- Install Tailwind CSS with Vue 3 and Vite - Tailwind CSS
- Starter using Vite + React + TypeScript + Tailwind CSS. - DEV Community
上記を参考に進めました。
環境
- tailwindcss 2.2.6
- autoprefixer 10.3.1
- postcss 8.3.6
必要パッケージをインストール
yarn add -D tailwindcss@latest postcss@latest autoprefixer@latest
tailwind.config.jsとpostcss.config.jsを作成
viteプロジェクト作成ではしませんでしたが、tailwindに関してはsccafoldさせて頂きます。
tailwindcss init -p
これで
- tailwind.config.js
- postcss.config.js
が生成されます。
tailwind.config.jsのpurgeを次のように書き換えます。
module.exports = { - purge: [], + purge: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], darkMode: false, // or 'media' or 'class' theme: { extend: {}, }, variants: { extend: {}, }, plugins: [], }
この設定をすることで実際に使われているCSSのみバンドルに含めることになり、バンドルサイズ削減に繋がります。
Tailwind CSS の Purge でビルドサイズを縮小する
試しに、手元のサンプルプロジェクトでpurgeの設定ありなしでCSSのバンドルサイズを比較してみました。
まず、purgeを提示したようにちゃんと指定した場合。
yarn vite build ... dist/assets/index.3d16e845.css 4.16kb / brotli: 1.26kb
次に、 purge: []
のままビルドした場合。
yarn vite build ... dist/assets/index.bf59349f.css 3166.01kb / brotli: skipped (large chunk)
絶対にpurgeは設定すべきということが分かりました。
index.cssを作成し、index.tsxで読み込む
次のようなindex.cssを作成します。
touch src/index.css
@import 'tailwindcss/base'; @import 'tailwindcss/components'; @import 'tailwindcss/utilities';
あとは、このindex.cssをindex.tsxでimportすれば導入完了です。
import React from 'react' import ReactDOM from 'react-dom' +import './index.css' ReactDOM.render(<div>Hello World</div>, document.querySelector('#root'))