บันทึกการ Migrate โปรเจค React จาก Webpack เป็น Vite.js และสิ่งที่ควรรู้
Table of contents
Intro
สวัสดีครับ บทความนี้จะพูดถึง Vite ที่สร้างโดย Evan You ซึ่งเป็นผู้พัฒนา Framework Vue.js ที่บอกว่า "is next-generation frontend tooling"
ที่มอบว่าเร็วในโหมด dev server
What's Vite
Vite เป็นคำภาษาฝรั่งเศส อ่านว่า "/vit/" ที่แป ลว่า "เร็ว"
Vite.js คือเครื่องมือแบบ build tool สำหรับ Modern web projects ที่เน้นความเร็วและประสิทธิภาพโดย Vite ใช้ native browser ES imports ที่ช่วยให้สามารถรองรับ Modern browsers ได้โดยไม่ต้อง build process ซึ่งมี 2 ส่วนคือ
- dev server ที่ให้คุณสามารถใช้งานคุณสมบัติเจ๋ง ๆ มากมาย (rich feature enhancements) ที่เหนือกว่า native ES modules ธรรมดา เช่น Hot Module Replacement (HMR) ที่เร็วมาก
- build command สำหรับ bundles พวก code ด้วย Rollup, Pre-configured เพื่อ Optimized ไฟล์ static assets สำหรับ Production
อะไรที่ทำให้ Vite น่าสนใจ
Vite นั้นใช้ความสามารถและประโยช น์จาก native ES modules ซึ่งมันก็ Support กับ Browsers รุ่นใหม่ ๆ อยู่แล้วโดยใน Development mode Vite นั้นสามารถ run server โดย compile (pre-build) และ run serve ได้ทันทีผ่าน ES modules ทำให้การทำงานนั้นเร็วมาก ๆ ซึ่งวิธีการนี้ช่วยให้ Vite ประมวลผลเฉพาะโค้ดที่จำเป็นในขณะนั้นได้ ดังนั้น Vite เลยจัดการกับโค้ดน้อยลงมากในขั้นตอน server startup และ code updates ต่างกับกรณีเครื่องมืออื่น ๆ เช่น webpack มาดูว่าทำไม
เหตุผลที่ทำให้ Vite เร็วมากก็เพราะว่ามันใช้ esbuild เป็น Bundler (เขียนด้วย golang) สำหรับการ Pre-bundling dependencies ระหว่าง Development โดยข้อมูลด้านล่างนี้คุณจะเห็นการเปรียบเทียบ esbuild กับ Bundlers ตัวอื่น ๆ ไม่ว่าจะเป็น webpack, Rollup และ Parcel
Vite vs. Webpack
webpack คือหนึ่งใน Bundlers ที่ยอดนิยมมากสำหรับ Web App development แต่มันช้ากว่า Vite ที่ใช้โมดูล native ES modules ทำให้ Vite มีข้อได้เปรียบด้านความเร็วที่เหนือกว่า webpack สำการจัดการกับ Code และ Dependencies เพื่อการ Bundling ซึ่ง webpack นั้นจะ Bundles ไฟล์ทั้งหมดในโปรเจคถึงจะทำงานได้
กระบวนการ Bundling เริ่มจาก Multiple routes -> modules จะได้ bundle จากนั้น Server ready พร้อมทำงาน
ด้วยวิธีการข้างต้นเป็นเหตุผลว่าทำไม webpack ถึงช้ากว่ามาก (โดยเฉพาะอย่างยิ่งกับโปรเจคขนาดใหญ่) ดังนั้นเมื่อโปรเจคโตขึ้น จำนวนโค้ดที่ต้องประมวลผลก็เพิ่มขึ้น ดังนั้นกระบวนการคอมไพล์ด้วย webpack จะนานขึ้นเรื่อย ๆ
ในทำนองเดียวกัน ระหว่างการเปลี่ยนโมดูลด่วนเมื่อมีการอัปเดตโค้ด webpack จำเป็นต้องทำการประมวลผลเพิ่มเติมเพื่ออัปเดต Bundle แต่นี่ไม่ใช่กรณีของ Vite เนื่องจากการใช้ native ES modules โดยรูปภาพด้านล ่างเป็นการอธิบายกระบวนการ Bundle ของ Vite
http request > entry > dynamic import (code split) > Multiple routes > modules
กระบวนการของ Vite ในตอนรันนั้นจะแตกต่างกับ webpack คือ Server ready ทันที โดยหากเรามีแอปพลิเคชันที่มีหน้าเว็บไม่กี่หน้า เช่น หน้าแรก เกี่ยวกับ ติดต่อ ฯลฯ และเราไปที่หน้าแรก เราจะใช้โค้ดสำหรับหน้าแรกเท่านั้น และนั่นคือสิ่งที่ Vite! ทำ
Migrate React (webpack) to Vite
หัวข้อนี้เป็นการ Migrate React (webpack) เดิมไปใช้ Vite แต่ถ้าหากท่านต้องการติดตั้งแบบโปรเจคใหม่สามารถทำตาม Guide ของ Vite ได้ที่นี่
1. Install dependencies
pnpm i -D vite @vitejs/plugin-react
2. Create Vite config file
สร้างไฟล์ vite.config.ts
ที่ root project จากนั้นกำหนดค่าดังนี้
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()]
})
3. Move index.html
ย้ายไฟล์ index.html
จาก public/
ไปไว้ที่ root project
4. Update index.html
เปลี่ยนค่าจาก %PUBLIC_URL%
ในไฟล์ index.html
เป็น /
// Before
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
// After
<link rel="icon" href="/favicon.ico" />
จากนั้นเปลี่ยน path ของ entry point
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!-- entry point 👇 -->
<script type="module" src="/src/index.tsx"></script>
5. Update tsconfig.json
สร้างไฟล์ tsconfig.vite.json
และกำหนดค่าดังนี้
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}
จากนั้นแก้ไขค่าที่ไฟล์ tsconfig.json
ดังนี้
{
"compilerOptions": {
"target": "ESNext",
"lib": ["dom", "dom.iterable", "esnext"],
"types": ["vite/client"],
"allowJs": false,
"skipLibCheck": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "ESNext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src"],
"references": [{ "path": "./tsconfig.vite.json" }]
}
6. Create vite-env.d.ts file
สร้างไฟล์ vite-env.d.ts
อยู่ใน src
จากนั้นกำหนดค่าดังนี้
ts title="vite-env.d.ts" /// <reference types="vite/client" />
7. Remove react-scripts
pnpm uninstall react-scripts
ลบไฟล์
react-app-env.d.ts
(ถ้ามี)
8. Update scripts in package.json
แก้ไขค่าที่ไฟล์ package.json
ดังนี้
{
"scripts": {
"start": "vite",
"build": "tsc && vite build",
"serve": "vite preview"
}
}
9. Start it up!
ทดลองสั่งรันให้ทำงานด้วยคำสั่ง pnpm start
จบแล้วสำหรับขั้นตอนการ Migrate ขั้นตอนต่อไปจะเป็นการปรับแต่ง (เพิ่มเติม)
การปรับแต่ง (เพิ่มเติม)
Environment variables
สิ่งที่ควรรู้คือ env
ของ Vite นั้นจะไม่เหมือนกับของ React ปกติโดยที่ Vite นั้นจะใช้ Prefix คือ VITE_
(เดิม REACT_APP_
) ดังนั้นต้องเปลี่ยน Prefix ในไฟล์ env
เป็น VITE_
แทนทั้งหมด
ส่วนคำสั่งสำหรับเรียกใช้ค่า env
ก็จะเปลี่ยนจาก process.env.REACT_APP_
เป็น import.meta.env.VITE_
แทน
#REACT_APP_NAME="React App"
#เป็น
VITE_NAME="React App"
Change build output folder
ตามปกติ Vite เวลาสั่ง Build จะได้ Folder dist
แต่หากต้องการเปลี่ยน Folder สำหรับ Output build สามารถกำหนดค่าที่ไฟล์ vite.config.ts
ได้ดังนี้
export default defineConfig({
// ...
build: {
outDir: 'build'
}
})
Change build output folder
ปกติ Vite เวลาสั่ง Start จะไม่ได้เปิด Web browser ให้อัตโนมัติ และถ้าหากต้องการให้เปิดอัตโนมัติสามารถกำหนดค่าได้ดังนี้
export default defineConfig({
// ...
server: {
open: true,
}
})
Change port number
ปกติ Vite เวลาสั่ง Start จะใช้ Default port 3000 และถ้าหากต้องการเปลี่ยนสามารถกำหนดค่าได้ดังนี้
export default defineConfig({
// ...
server: {
port: 8000,
}
})
สรุป
ส่วนตัวใช้ Vite มาสักพักแล้ว ค่อนข้างพอใจกับประสิทธิภาพ ด้วยความลับของการทำงานที่ใช้ Esbuild ที่เขียน golang เร็วแรงทะลุปรอท 😄
ที่จริง Vite นิยามคือ Frontend Tools แต่จริง ๆ แล้วก็มีคนนำไปใช้ Build พวกที่เป็น Backend ด้วยเหมือนกันแต่ส่วนตัวยังไม่ได้ไปถึงขั้นนั้น แค่บอกว่ามันทำได้ด้วยนะ 😅
บทความต่อไปที่อยากเขียนเกี่ยวกับ Vite คือการ Build ในหลายรูปแบบ Environment เช่นการ Pre-Build ที่เป็นแบบ Dev การ Build สำหรับ Production และการ Build สำหรับ Staging