เพิ่ม Component Importmap Autoloader เมื่อใช้งานร่วมกับ React หรือ Vue
ต่อเนื่องจาก Using importmap on Rails 6 จะเห็นได้ว่าตัวอย่างโค้ดมีการใช้งาน Stimulus ซึ่งคอนโทรลเลอร์ที่ได้นิยามไว้ในโฟลเดอร์ app/javascript/controllers
จะถูกนำเข้าไปรวมกับ application.js
แบบอัตโนมัติทุกตัวผ่านโมดูล stimulus-importmap-autoloader
import "@hotwired/stimulus-importmap-autoloader"
ส่วนคอมโพแนนท์ของ React หรือ Vue เราจะต้องใส่เพิ่มเข้าไปทีละคอมโพแนนท์ในไฟล์ application.js
import 'components/reverse_component'
import 'components/clock'
แบบคงไม่สะดวกแน่ ถ้าเราต้องมาเพิ่มคอมโพแนนท์ใหม่เข้าไปทุกๆ ครั้งเมื่อสร้างคอมโพแนนท์ใหม่ แน่นอนว่าเราจะต้องมี Autoloader สำหรับคอมโพแนนท์เหมือนกับ Stimulus ที่โหลดคอนโทรลเลอร์เข้าไปให้อัตโนมัติ ซึ่งเราก็ไปศึกษาโค้ด autoloader ของ Stimulus และนำมาปรับใช้กับคอนโพแนนท์แทน ดังนี้
// app/javascript/helpers/component-importmap-autloader.js
const importmap = JSON.parse(document.querySelector("script[type=importmap]").text)
const componentsPaths = Object.keys(importmap.imports).filter((e) => e.match("components/"))
componentsPaths.forEach(function(path) {
const name = path.replace("components/", "")
import(path)
.then(module => console.log(module))
.catch(error => console.log(`Failed to autoload components: ${name}`, error))
})
หลักการเบื้องต้นของโค้ด คือ
- ไปค้นหาคอมโพแนนท์ทั้งหมดที่อยู่ใน script ซึ่งมี type เป็น importmap ซึ่งตรงนี้เกิดขึ้นจากโค้ดที่มีการเรียกใช้
pin_all_from
- โหลดคอมโพแนนท์ทั้งหมดเข้าไปโดยผ่านการใช้งาน dynamic import
ด้วยวิธีการดังกล่าวสามารถทำให้เรานำเข้าคอมโพแนนท์ที่อยู่ภายใต้โฟลเดอร์ app/javascript/components
ซึ่งไม่ว่าจะเป็น React หรือ Vue ก็จะถูกโหลดเข้าไปได้หมดเลย