ในช่วงต้นของยุคอินเทอร์เน็ต เว็บไซต์ง่ายกว่าและไม่ค่อย Interactive ด้วยการก้าวหน้าของเทคโนโลยี อุปกรณ์ และภาษาโปรแกรมมิ่ง พวกเขากลายเป็นซับซ้อนมากขึ้นและประกอบด้วยหลายไฟล์ รวมถึง Assets เช่น รูปภาพและ CSS Stylesheets
เว็บไซต์ของคุณ Interactive มากแค่ไหน คุณก็ต้องใช้ JavaScript Code มากเท่านั้น เพื่อใช้โค้ดดังกล่าว คุณต้อง Include ไฟล์ HTML Code ทั้งหมดโดยใช้ Script Tag วิธีการแบบนี้ Error-prone เพราะคุณต้องจำได้ทุกไฟล์และเก็บ Order ให้ถูกต้อง มิฉะนั้น โค้ดของคุณอาจไม่ทำงาน ด้วย Webpack Tool ปัญหาเหล่านี้หายไป Webpacker เป็น Bridge ระหว่าง Webpack และ Rails Application
บทความนี้ Deep Dive เข้าไปใน Webpacker และเสนอ Detailed Explanation ที่จะทำให้คุณเข้าใจว่า Tool นี้ทำงานภายใต้ฮุ๊ดอย่างไร เพื่อทำให้ Content มีค่ามากที่สุด ฉันตัดสินใจแบ่งออกเป็นส่วนต่อไปนี้:
- High-level Overview — ก่อนที่เราจะ Deep Dive ฉันจะอธิบาย High-level Overview ของ Webpack และ Webpacker คุณสามารถถือมันเป็น Preparation สำหรับหัวข้อ Advanced มากขึ้น
- Structure Explanation — เนื่องจากเราจะสำรวจหลายไฟล์ ดีที่จะรู้ว่าทำไม Structure นั้นจึงถูกใช้ และมันตอบสนอง General Purpose อย่างไร
- Anatomy Explanation — ส่วนนี้ครอบคลุมการสำรวจไฟล์สำคัญที่สุดของ Webpack Setup การรู้ว่าพวกเขาทำงานอย่างไร Essential สำหรับ Development Process ที่มีประสิทธิภาพและไร้ปัญหา
- Environment Specific Setup — ส่วนสุดท้ายอธิบายว่า Webpacker ทำงานใน Development และ Production Environments อย่างไร
หลังจากอ่านบทความนี้ คุณจะรู้ว่า Webpack และ Webpacker คืออะไร และทำไมเราต้องการพวกเขาใน Rails Application การ Deep Dive เข้าสู่ Webpacker's Internals จะช่วยให้คุณเข้าใจว่า Tool นี้เชื่อมต่อกับ Webpack อย่างไร และสื่อสารกับ Rails Application อย่างไร
ก่อนจะ Dive In
ก่อนจะออกไปน้ำลึก เราต้อง Prepare ก่อน High-level Overview เป็นวิธีดีในการเริ่มทำงานกับ Technology ใดๆ เพราะมันช่วยให้เราเข้าใจ Purpose ของ Tool ที่กำหนดและปัญหาที่มันแก้ได้ โดยไม่ต้อง Deep เข้าไปใน Internals
Webpack
ฉันกล่าวไปแล้วว่า Webpack ช่วยจัดระเบียบ JavaScript File Code ของเราเพื่อหลีกเลี่ยง Errors และปรับปรุง Website Performance มันจัดระเบียบ Code เข้า Bundles
Bundle คือไฟล์ที่ Multiple Modules ถูกวางอย่าง Intelligent โดยเคารพ Dependency Graph ที่สร้างขึ้นก่อน ด้วย Process นี้ เราสามารถมั่นใจได้ว่าโค้ดของเราจะทำงานตามที่คาดหวัง และก่อนที่เราจะ Invoke Library Code ที่กำหนด มันจะถูก Loaded แล้ว
Webpack ไม่ใช่ Tool 唯一ที่ใช้โดย Default ใน Rails เวอร์ชันใหม่สุด เมื่อ Project ถูก Generate Configuration Files สำหรับ Babel และ PostCSS ถูกสร้างด้วย PostCSS เป็น Tool สำหรับ Transform CSS ด้วย JavaScript และ Babel เป็น JavaScript Compiler ที่ทำให้เราเขียน Modern JavaScript ได้โดยไม่กังวลเรื่อง Browser Support
Webpacker
Webpacker เป็น Tool ที่ Integrate Webpack กับ Rails Application มันทำให้ง่ายต่อการ Configure และ Develop JavaScript-like Applications และ Optimize พวกเขาสำหรับ Production Environment
Source Code พร้อมใช้งานเป็น Gem และ Library มาพร้อม Development Server ที่ทำให้ Development ของ App เร็วมาก เพราะคุณไม่ต้อง Stop และ Start Server เพื่อดู Changes ที่ Introduce ใน JavaScript Files
The Deep Immersion (การดำน้ำลึก)
ตอนนี้คุณรู้แล้วว่า Webpack ถูกสร้างขึ้นเพราะอะไร และ Webpacker เล่น Role อะไรใน Rails Application เราสามารถ Focus เข้า Webpacker's Internals เพื่อดูว่ามันจัดระเบียบไฟล์, เร่ง Development Process และ Optimize Files สำหรับ Production Environment อย่างไร
Webpacker พร้อมใช้งาน Out-of-the-box ใน Rails เวอร์ชันใหม่สุด ก่อนสร้าง Project ใหม่ ให้แน่ใจว่า Node Version มากกว่าหรือเท่ากับ 10.17.0 เนื่องจาก Command webpacker:install จะถูก Invoke อัตโนมัติพร้อมกับ Rails New Command
Webpacker File Structure
หลังจาก Execute Install Command ไฟล์ต่อไปนี้ถูกสร้าง:
config/webpacker.yml— Main Configuration File ที่มี Default Configuration และ Configs สำหรับ Environments เฉพาะconfig/webpacker/— Directory ที่ JavaScript Configuration Files สำหรับ Environments เฉพาะถูกสร้างbin/webpack— Executable File ที่ Invoke Webpack เพื่อสร้าง Bundlesbin/webpack-dev-server— Executable File ที่ Start Development Server ซึ่ง Reload Webpack ทุกครั้งที่คุณทำ Changes ภายใน JavaScript Files ที่ Included ใน Bundle
The Anatomy of the Configuration File
Main Configuration File สำหรับ Webpacker อยู่ภายใต้ Config Directory และชื่อ webpacker.yml ไม่เหมือน Webpacker Configuration สำหรับ Webpack ถูกเก็บแยกสำหรับแต่ละ Environment ภายใต้ Directory config/webpack
Webpacker
โดย Default Configuration File มี Entries มาก — Default Ones และ Sections สำหรับแต่ละ Environment ที่คุณสามารถ Overwrite Specific Settings มาดู Settings สำคัญที่สุด:
source_path— Primary Source ของ JavaScript Files ใน Application ของคุณ ถูก Set เป็นapp/javascriptโดย Default และปกติไม่ต้องเปลี่ยน Value นี้source_entry_path— ชื่อ Directory ภายใต้ Source_path ที่คุณเก็บ Pack Files (Entry Points) โดย Default Setting นี้ Set เป็น Directory 'packs'public_root_path— Path ไป Directory ใน Application ของคุณที่ Accessible จาก Browser ใน Rails Application ทั่วไป คือ Public Directorypublic_output_path— เมื่อ Webpacker Compile Files ของคุณ มันจะวาง Compiled Files ทั้งหมดใน Directory นี้ภายใต้public_root_pathโดย Default Directory ชื่อ Packs แต่คุณสามารถตั้งชื่ออะไรก็ได้webpack_compile_output— หาก Flag ตั้งเป็น True Output Messages จะแสดงเมื่อ Files ถูก Compile มีประโยชน์เมื่อ Compilation Fails เพราะคุณจะ Aware และ Take Action ได้
คุ้มค่าที่จะกล่าวว่า Development Section ยังมี Configuration สำหรับ Dev Server ที่ใช้ Compile Files ใน Development Environment โดยไม่ต้อง Restart Server
หากคุณต้องการ Access Configuration จาก Rails Console หรือ Code Level คุณสามารถเรียก Webpacker.manifest.config ซึ่งจะ Return Configuration Class Instance
Webpack
แต่ละ Environment มี Configuration File ของตัวเอง แต่ในทุก File Main Environment File ถูก Import: config/webpack/environment.js ใน Environment Configuration File มีที่สำหรับ Load Custom Plugins ที่จะ Modify Default Behavior ของ Webpack เรายังสามารถ Add Custom Rules สำหรับ Compile Files ของเราได้
The Anatomy of the Pack File
Packs ตั้งอยู่ภายใต้ Directory app/javascript/packs แต่ละ Pack File ถูก Treat โดย Webpacker เป็น Entry Point เมื่อ Compilation Process เริ่มต้น
The Default Pack File
เมื่อคุณ Generate Rails Project ใหม่ Default Pack File ชื่อ application.js ถูกสร้างพร้อม Content ต่อไปนี้:
import Rails from "@rails/ujs"; import Turbolinks from "turbolinks"; import * as ActiveStorage from "@rails/activestorage"; import "channels"; Rails.start(); Turbolinks.start(); ActiveStorage.start();
ตามที่คุณเห็น ขั้นตอนแรกคือ Import Library ที่กำหนด และเรียก Initialization Method เมื่อจำเป็น เมื่อคุณเรียก Import System จะ Search สำหรับ Node Module ที่กำหนดหรือ Local Library ด้วย Standard Approach คุณไม่ต้อง Explicitly Initialize Library เพราะมัน Initialized เมื่อคุณ Include ใน Page Source ด้วย Script Tag
Good Practices สำหรับ Pack File
แม้คุณจะวาง Regular JavaScript Code ภายใน Pack File และ Execute ได้ ไม่ Recommended ที่จะเก็บ JavaScript Code ภายใน Pack File Best Approach คือเก็บ Files ให้ Clean และ Import และ Initialize Libraries ที่นี่เท่านั้น และเก็บ Logic อื่นๆ นอก Packs Directory
Including Pack Files ใน Application
Pack Files ไม่ได้ Included ใน Website Source โดยอัตโนมัติ เหมือน Asset Pipeline Case เราต้องใช้ Special Tag ภายใน Views:
<%= javascript_packs_with_chunks_tag 'application' %>
Method นี้ทำงานอย่างไร? ภายใต้ฮุ๊ด มันเรียก Webpacker Configuration ที่ Hold Data ที่คุณใส่ใน config/webpacker.yml มันมองหา application.js File ภายใน Entry Points Directory ซึ่งในกรณีของเราคือ app/javascript/packs คุณสามารถ Verify ได้โดยเรียกโค้ดต่อไปนี้:
Webpacker.manifest.config.source_entry_path
เมื่อ Entries ถูกพบ Webpacker เรียก Method javascript_include_tag Helper จาก Library ActionView ที่พร้อมใช้งานโดย Default ใน Rails Method ยอมรับ One หรือ More Sources และ Return Script Tags ที่คุณสามารถ Apply ตรงไปตรงมาที่ View
The Development Server
Webpacker Development Server's Entry Point คือ Executable File วางภายใน Folder bin ชื่อ webpack-dev-server กระบวนการ Run Server ประกอบด้วย 5 Steps:
- Setting Environment — Environment Name สำหรับ Node และ Rails ถูก Set เมื่อ Environment ไม่ได้ Specify โปรแกรม Assume ว่า Server จะ Executed ใน Development Environment
- Loading Configuration — File
config/webpacker.ymlถูก Load ด้วย Settings สำหรับ Environment ที่ Set ในขั้นตอนก่อน - Validating Command Options — โปรแกรม Check หากเรา Pass Appropriate Options ให้ Server Command ตัวอย่าง จะ Throw Error เมื่อ Option
--httpsถูกให้ แต่เราไม่ Specify ในconfig/webpacker.yml - Verifying Port's Availability — โปรแกรม Check หาก Port ที่ให้มา Available ถ้า Program อื่นใช้อยู่ มันจะ Throw Error ให้คุณรู้ว่าคุณต้อง Update Webpack Server Configuration ภายใน
config/webpacker.yml - Executing Webpack Serve Command — เมื่อ Node Modules Directory Exists โปรแกรม Execute Command ภายใน Directory มิฉะนั้น Execute ด้วย Yarn โปรแกรม Pass Configuration Option ให้ Command ที่ Point ไปหนึ่งใน Files วางภายใน Directory
config/webpack/
Server กำลังรัน และ Compile Code ของคุณ On-the-fly ดังนั้นคุณไม่ต้อง Restart Server เพื่อดู Changes และเช็คว่า Webpack สามารถสร้าง Bundle ด้วย Code ใหม่ได้หรือไม่
Development Server's Code ค่อนข้าง Simple มันเพียง Load Config จาก Configuration File ใน YAML Format และ Pass Proper Config ใน JavaScript Format ตรงไปที่ Command webpack serve คุณสามารถ Run ด้วยมือได้ แต่คุณไม่ต้องดูแล Command Arguments ที่ Proper ด้วย Built-in Command
Compiling Files สำหรับ Production Environment
สมมติว่าคุณต้องการ Deploy Application ที่ใช้ Webpacker ในกรณีนี้ คุณสามารถ Invoke Task assets:precompile ได้อย่างง่ายดาย เพราะ Webpacker Hook Up Task webpacker:compile เข้าไปอย่างอัตโนมัติ
Task webpacker:compile ทำงานภายใต้ฮุ๊ดอย่างไร? มาขุดลึกลงไปดู มันทำสิ่งต่อไปนี้:
- มัน Wrap Main Call เข้า 2 Blocks 确保
NODEEnvironment ถูก Set และ Webpacker Logs ถูก Output ไป Standard Out - มันเรียก Webpack และ Parse Logs ของมันเพื่อ Determine หาก Action Successful หรือไม่
ตอนนี้คุณสามารถ Visit Directory public/packs/js เพื่อดู Compiled Files พวกเขาควร Deploy ไป Server
สรุป
เราเพิ่งเรียนรู้ว่า Webpacker ทำงานภายใต้ฮุ๊ดอย่างไร คุณสามารถถือมันเป็น Bridge ระหว่าง Webpack Library และ Rails Application ที่ช่วยให้คุณ Configure Webpack ด้วย Ruby และใช้ JavaScript Code ภายใน Application ได้ง่าย
เพื่อสรุปบทความทั้งหมด มา Recall องค์ประกอบหลักของ Webpacker อีกครั้ง:
- Configuration — วางอยู่ใน
config/webpacker.ymlไฟล์ และอนุญาตให้คุณ Point Webpacker ไป Directory ที่คุณเก็บ JavaScript Files และ Packs - Pack — คือ Single Entry Point ที่ Webpacker เริ่ม Compilation Library ที่ Imported และ Initialized ใน File นั้นจะ Compiled อัตโนมัติ
- Development Server — Script 簡單ที่ช่วย Compile Files On-the-fly ดังนั้นคุณไม่ต้อง Restart Server ทุกครั้งที่ Modify JavaScript Files
- Compile Task — Rake Task 簡單ที่ Invoke Webpack และ Compile Files ภายใต้ Public Directory ดังนั้นคุณสามารถ Deploy ไป Production Server และทำให้ Available สำหรับ End-users
- View Helper — Helper ที่ช่วย Include Compiled Files ภายใน Views
สำหรับ Developers หลายคนที่ไม่มี Experience มาก Webpacker ดูเหมือนจะ Magical นิดหน่อย แต่จริงๆ มันคือ Library 簡單ที่ช่วยให้เราใช้ Webpack ด้วย Ruby Way
P.S. หากคุณต้องการอ่านโพสต์ Ruby Magic ทันทีที่เผยแพร่ สมัครรับข่าวสาร Ruby Magic newsletter และจะไม่พลาดโพสต์เด็ดๆ ไปเลย!