Skip to main content

บันทึกการ Migrate โปรเจค React จาก Webpack เป็น Vite.js และสิ่งที่ควรรู้

Kongvut Sangkla

Intro

สวัสดีครับ บทความนี้จะพูดถึง Vite ที่สร้างโดย Evan You ซึ่งเป็นผู้พัฒนา Framework Vue.js ที่บอกว่า "is next-generation frontend tooling" ที่มอบว่าเร็วในโหมด dev server

Imgur

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

Imgur

Vite vs. Webpack

webpack คือหนึ่งใน Bundlers ที่ยอดนิยมมากสำหรับ Web App development แต่มันช้ากว่า Vite ที่ใช้โมดูล native ES modules ทำให้ Vite มีข้อได้เปรียบด้านความเร็วที่เหนือกว่า webpack สำการจัดการกับ Code และ Dependencies เพื่อการ Bundling ซึ่ง webpack นั้นจะ Bundles ไฟล์ทั้งหมดในโปรเจคถึงจะทำงานได้

Imgur

กระบวนการ Bundling เริ่มจาก Multiple routes -> modules จะได้ bundle จากนั้น Server ready พร้อมทำงาน

ด้วยวิธีการข้างต้นเป็นเหตุผลว่าทำไม webpack ถึงช้ากว่ามาก (โดยเฉพาะอย่างยิ่งกับโปรเจคขนาดใหญ่) ดังนั้นเมื่อโปรเจคโตขึ้น จำนวนโค้ดที่ต้องประมวลผลก็เพิ่มขึ้น ดังนั้นกระบวนการคอมไพล์ด้วย webpack จะนานขึ้นเรื่อย ๆ

ในทำนองเดียวกัน ระหว่างการเปลี่ยนโมดูลด่วนเมื่อมีการอัปเดตโค้ด webpack จำเป็นต้องทำการประมวลผลเพิ่มเติมเพื่ออัปเดต Bundle แต่นี่ไม่ใช่กรณีของ Vite เนื่องจากการใช้ native ES modules โดยรูปภาพด้านล่างเป็นการอธิบายกระบวนการ Bundle ของ Vite

Imgur

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 จากนั้นกำหนดค่าดังนี้

vite.config.ts
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 เป็น /

index.html
// Before
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />

// After
<link rel="icon" href="/favicon.ico" />

จากนั้นเปลี่ยน path ของ entry point

index.html
<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 และกำหนดค่าดังนี้

tsconfig.vite.json
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}

จากนั้นแก้ไขค่าที่ไฟล์ tsconfig.json ดังนี้

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_ แทน

.env
#REACT_APP_NAME="React App"
#เป็น
VITE_NAME="React App"

Change build output folder

ตามปกติ Vite เวลาสั่ง Build จะได้ Folder dist แต่หากต้องการเปลี่ยน Folder สำหรับ Output build สามารถกำหนดค่าที่ไฟล์ vite.config.ts ได้ดังนี้

vite.config.ts
export default defineConfig({
// ...
build: {
outDir: 'build'
}
})

Change build output folder

ปกติ Vite เวลาสั่ง Start จะไม่ได้เปิด Web browser ให้อัตโนมัติ และถ้าหากต้องการให้เปิดอัตโนมัติสามารถกำหนดค่าได้ดังนี้

vite.config.ts
export default defineConfig({
// ...
server: {
open: true,
}
})

Change port number

ปกติ Vite เวลาสั่ง Start จะใช้ Default port 3000 และถ้าหากต้องการเปลี่ยนสามารถกำหนดค่าได้ดังนี้

vite.config.ts
export default defineConfig({
// ...
server: {
port: 8000,
}
})

สรุป

ส่วนตัวใช้ Vite มาสักพักแล้ว ค่อนข้างพอใจกับประสิทธิภาพ ด้วยความลับของการทำงานที่ใช้ Esbuild ที่เขียน golang เร็วแรงทะลุปรอท 😄

ที่จริง Vite นิยามคือ Frontend Tools แต่จริง ๆ แล้วก็มีคนนำไปใช้ Build พวกที่เป็น Backend ด้วยเหมือนกันแต่ส่วนตัวยังไม่ได้ไปถึงขั้นนั้น แค่บอกว่ามันทำได้ด้วยนะ 😅

บทความต่อไปที่อยากเขียนเกี่ยวกับ Vite คือการ Build ในหลายรูปแบบ Environment เช่นการ Pre-Build ที่เป็นแบบ Dev การ Build สำหรับ Production และการ Build สำหรับ Staging

References

Loading...