วันนี้ผมได้ลองใช้งาน esbuild ครั้งแรก ซึ่งก่อนหน้านี้ เคยได้ยิน และได้เห็นผ่านตา แต่ไม่เคยได้จับมันจริงๆ เพราะส่วนใหญ่ผมก็จะเป็นแค่ผู้ใช้งาน Library/ Frmework เลยไม่ได้ลงไปถึงขั้นต้อง config webpack/esbuild อะไรพวกนั้น
หลังจากได้ลองเล่นไปนิดๆหน่อย ก็ลองมาเขียนบทความบันทึกไว้ครับ ซึ่งส่วนใหญ่ Reference ผมก็อ่านจาก Official esbuild ครับ
esbuild คืออะไร?
esbuild เป็น JavaScript bundler/Compiler ที่เขียนด้วยภาษา Go คล้ายๆกับ Webpack, Rollup หรือ SWC คือทำหน้าที่ รวมไฟล์ แปลงไฟล์ minify ต่างๆ
Feature หลักๆ คือ
- ES6 และ CommonJS
- รองรับ Tree shaking (คือ module ไหนไม่ได้ import ก็ไม่ถูกยัดรวม bundle)
- มี API สำหรับ JavaScript และ Go
- รองรับ TypeScript และ JSX
- Sourcmap และ Minify เป็นต้น
Install esbuild
เริ่มต้น เราจะทำการสร้างโปรเจ็คขึ้นมาก่อน ผมตั้งชื่อให้มันว่า try-esbuild ละกัน และก็ initial project ด้วย yarn
mkdir try-esbuildcd try-esbuild
yarn init -yจากนั้นทำการ install esbuild ลงไป
yarn add esbuildตัว esbuild เราก็จะสามารถเรียกจาก folder นี้ได้แล้ว:
./node_modules/.bin/esbuild --version
0.14.36First bundle
ต่อมาลอง build จริงๆ ด้วยการใช้ React และ ReactDOM กัน ทำการติดตั้ง dependencies:
yarn add react react-domต่อมาสร้างไฟล์ app.jsx ขึ้นมา มีโค๊ดดังนี้
import * as React from 'react'import * as Server from 'react-dom/server'
let Greet = () => <h1>Hello, world!</h1>console.log(Server.renderToString(<Greet />))ตัวโค๊ดด้านบน ใช้ความสามารถของ react เพื่อ server render ทำให้เราสามารถรันด้วยคำสั่ง node ได้
ซึ่งถ้าเรารันตรงๆ แบบนี้ จะ error:
node app.jsxต้องทำการ bundle file ด้วย esbuild ก่อน แบบนี้:
./node_modules/.bin/esbuild app.jsx --bundle --outfile=out.jsจะได้ไฟล์ผลลัพธ์และไฟล์ output คือ out.js
out.js 507.3kb
⚡ Done in 10msเมื่อได้ไฟล์นี้เราสามารถรันด้วยคำสั่ง
node out.js
<h1>Hello, world!</h1>React App
เผื่อยังไม่เห็นภาพ ลองเป็น React ฝั่ง Client บ้าง ผมสร้างโฟลเดอร์มาใหม่ ขื่อ src ข้างในมีไฟล์ App.jsx ดังนี้ (เอามาจาก template ของ create-react-app)
import React from 'react'
function App() { return ( <div className="App"> <header className="App-header"> <h1>üëã Hello esbuild!</h1> </header> </div> )}
export default Appและไฟล์ src/index.jsx เป็นแบบนี้
import React from 'react'import ReactDOM from 'react-dom/client'
import App from './App'
const root = ReactDOM.createRoot(document.getElementById('root'))root.render( <React.StrictMode> <App /> </React.StrictMode>)ต่อมา ก็ทำการ bundle ไฟล์ ไว้ที่โฟลเดอร์ dist (ใช้ --outdir แทน --outfile ก่อนหน้านี้)
./node_modules/.bin/esbuild --bundle src/index.jsx src/App.jsx --outdir=distสร้างไฟล์ index.html ขึ้นมา
<!doctype html><html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="description" content="Hello esbuild" /> <title>Hello esbuild</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div>
<script src="dist/index.js"></script> </body></html>