Esbuild on Rails

ตลอดระยะเวลา 2 ปีที่ผ่านมา Webpack ได้ถูกนำเข้ามาเป็นตัว build โค้ดใน Rails แต่คาดว่าใน Rails เวอร์ชัน 7 คงจะมีการปลดประจำการ Webpack ออกไปให้เป็น optional แล้วอะไรหละที่จะมาแทน Webpack ก็อย่างที่ได้เห็นแล้วในชื่อบทความนั้นก็คือ esbuild นั้นเอง

โดยความเห็นส่วนตัว แล้ว Webpack เคยเป็นเครื่องมือที่น่าตื่นตาตื่นใจสมัยที่ออกมาใหม่ แต่ด้วยที่พอมีการอัพเดตเวอร์ชันใหม่ ก็มีทั้งการตั้งค่า ปลั๊กอิน โหลดเดอร์ต่างๆ ที่พัฒนาและปรับเปลี่ยนไป ทำให้รู้สึกว่า Webpack นั้นก็ยุ่งยากพอสมควรสำหรับมือใหม่เลยทีเดียว และใช้เวลาในการ build ค่อนข้างนาน

ในบทความนี้เราจะมาใช้ gem esbuild-rails ซึ่งเพิ่งถูกปล่อยออกมา (เวอร์ชัน 0.1.2) กับ Rails เวอร์ชัน 6 กันดู เพราะถ้าย้อนกลับไปในบทความการใช้งาน Importmap บน Rails 6 การใช้ importmap อาจจะไม่เหมาะกับบางสถานการณ์

esbuild:install rails esbuild:install

จะเห็นว่าสิ่งที่เแปลกตาไปคือการสร้างไฟลเดอร์ app/assets/esbuilds ขึ้นมา ซึ่งจะใช้สำหรับเก็บไฟล์ Javascript ที่ถูก build แล้วไว้ ถ้าเราอยากได้โฟลเดอร์เป็นอย่างอื่นก็ได้ทำได้ แต่ต้องเข้าไปแก้ไขในไฟล์ app/assets/config/manifest.js ให้ชื่อตรงกับโฟลเดอร์ที่เราเปลี่ยนด้วย

//= link_tree ../images
//= link_directory ../stylesheets .css
//= link_tree ../esbuilds .js # 👈 change folder name HERE!

npm:run:build npm run build

มาลองเปรียบเทียบระหว่าง Webpack และ esbuild กันแบบคร่าวๆ หลังจากผ่าน precompile

esbuild:install esbuild

esbuild:install webpack

ทั้งนี้การเปรียบเทียบอาจจะไม่ค่อยละเอียดมากนัก แต่ถ้าดูจากข้อมูลที่มีก็จะเห็นได้ว่าทั้งเวลา และขนาดที่ได้จากการคอมไพล์ด้วย esbuild ให้ประสิทธิภาพที่ดีกว่า

ในช่วง development แนะนำให้ใช้ Procfile เพื่อรันเว็บและรันคำสั่ง build แบบ watch mode จะดีกว่า

# Procfile
web: ./bin/rails server
build: npm run build -- --watch

ถ้าจะเอาไปรันบน production จริง เราก็จะเรียกใช้ ./bin/rails assets:precompile แต่ก็ต้องไปปรับแก้ค่าของ esbuild ให้เหมาะสมอีกทีหนึ่ง เช่น minify, sourcemap ซึ่งสามารถเข้าไปดู option ต่างๆ ได้ที่นี่

สำหรับ esbuild-rails ที่นำมาใช้งานนี้ยังเป็นเวอร์ชันแรกๆ ซึ่งอาจจะมีการเปลี่ยนแปลงอีกในอนาคต เพื่อให้การใช้งานสะดวกมากยิ่งขึ้น ยังไงก็ลองไปติดตามกันดู

ยังไงซะ เดี่ยวจะนำไปใช้งานบน production จริงแล้วจะเอาผลการใช้งานมาเล่าให้ฟังกันอีกทีนะครับ

‼️👋 esbundling-rails ได้ปรับให้เป็นส่วนหนึ่งของ jsbundling-rails แทนแล้ว

References