Sprockets Rails กับฟ้อนต์ที่ไม่โหลด

หลังจากที่โปรเจ็คหลายๆ ตัวได้อัพเวอร์ชันมาใช้ Rails 7 อีกสิ่งหนึ่งที่ได้รับผลกระทบตามมาคือการจัดการ asset ต่างๆ ที่อยู่ภายใน ซึ่งใน Rails 7 เปิดทางเลือกให้ผู้พัฒนาเลือกใช้เครื่องมือในการจัดการ JavaScript และ CSS ใดๆ ก็ได้ที่ถนัด

สำหรับเราเอง เราเลือกใช้ sprockets มาแต่ไหนแต่ไร เพียงแต่ในเวอร์ชัน 7 เราได้ใช้ sprockets-rails มาเป็น wrapper อีกทีหนึ่ง ซึ่งส่งผลให้เกิดปัญหาฟ้อนต์ต่างๆ ที่ถูกอ้างอิงไว้ในไฟล์ CSS ไม่ถูกโหลดเมื่อในหน้าเว็บ

ถ้าย้อนกลับไปที่การอ้างอิง asset ต่างๆ ใน CSS ตอนที่เรายังใช้ sprockets เพียวงอย่างเดียวจะมี helper ให้ใช้งานอยู่ไม่ว่าจะเป็น asset-path|asset-url, image-path|image-url, font-path|font-url โดยการอ้างอิงฟ้อนต์ที่เราใช้อยู่จะเป็นดังตัวอย่างด้านล่าง

  @font-face {
    ...
    src: font-url("IBMPlexSansThai-Regular.woff2") format("woff2");
  }

จะเห็นได้ว่าเราเรียกใช้ helper font-url ในการอ้างอิง URL เมื่อถูก compile ด้วยคำสั่ง rails assets:precompile จะถูกแปลงเป็น

  @font-face {
    ...
    src: url("/assets/IBMPlexSansThai-Regular-8cb267db96213347f522e3bc8a04822009fd83e45718c40f933a5aeb33d22446.woff2") format("woff2");
  }

แต่เมื่อเปลี่ยนมาใช้ sprockets-rails ปรากฏว่าเมื่อสั่ง compile จะได้ออกมาเหมือนเดิม ซึ่ง font-url ไม่ใช้ syntax ที่ CSS รู้จัก จึงทำให้ฟ้อนต์ไม่ถูกโหลดมาใช้งาน

จากที่ได้เข้าไปดูในโค้ด ปรากฏว่าจริงๆ แล้วเราไม่จำเป็นต้องใช้ helper อีกต่อไป เพราะตัว processor ใหม่จะตรวจจับจาก url() ที่อยู่ใน CSS และจัดการใส่ URL ที่ถูกต้องเข้าไป

AssetUrlProcessor

ดังนั้นต่อไปนี้ถ้าเราจะอ้างถึง asset ใดๆ ที่อยู่ใน CSS ก็ให้เรียกผ่าน url() ได้เลย ดังตัวอย่างด้านล่าง

  @font-face {
    ...
    src: url("IBMPlexSansThai-Regular.woff2") format("woff2");
  }

References