การใช้ `@forward` ใน SASS

การใช้ `@forward` ใน SASS

บทความนี้อธิบายเกี่ยวกับ @forward ใน SASS

เราจะอธิบาย @forward อย่างเข้าใจง่าย พร้อมทั้งตัวอย่างการใช้งานจริง

YouTube Video

การใช้ @forward ใน SASS

@forward คืออะไร?

ในระบบโมดูลของ SASS จะใช้ @use และ @forward แทนการใช้ @import @forward เป็นฟีเจอร์สำคัญในการรักษาสถาปัตยกรรมของคุณให้เป็นระเบียบ เป็นคำสั่งสำหรับ 'เปิดเผย' ตัวแปร มิกซ์อิน และฟังก์ชันที่นิยามไว้ในไฟล์อื่น มันไม่ได้ใช้โดยตรงแต่จะทำหน้าที่เป็นทางเข้า (entry point) ระบุว่า 'ให้ใช้โมดูลนี้จากที่นี่'

1@forward "variables";
  • โค้ดนี้หมายถึง 'ทำให้เนื้อหาใน variables.scss สามารถนำไปใช้จากไฟล์อื่นได้'

ความแตกต่างระหว่าง @use และ @forward

@use และ @forward เป็นไวยากรณ์สำหรับจัดการโมดูลทั้งคู่ แต่วัตถุประสงค์แตกต่างกันชัดเจน @use คือคำสั่งสำหรับใช้องค์ประกอบต่าง ๆ ในไฟล์นั้น ส่วน @forward คือคำสั่งสำหรับให้ไฟล์อื่นเข้าถึงองค์ประกอบเหล่านั้นได้

1// @use: import the module for use in this file
2@use "variables";
3
4// @forward: re-export the module for other files to consume
5@forward "variables";
  • @use แสดงถึงการพึ่งพาที่ไฟล์ปัจจุบันต้องการ ในขณะที่ @forward ทำให้ไฟล์นั้นทำหน้าที่เป็น จุดเข้าใช้งานสำหรับ API สาธารณะ การเข้าใจความแตกต่างนี้จะช่วยให้คุณตัดสินใจได้ว่าควรใช้ @forward ตรงไหน

ทำไมต้องใช้ @forward?

เมื่อเพิ่มไฟล์ Sass มากขึ้น คุณอาจต้องเขียน @use หลายบรรทัด การใช้ @forward ช่วยให้คุณ รวมทุกอย่างไว้ในไฟล์เริ่มต้นเพียงไฟล์เดียว

1styles/
2├─ foundation/
3│  ├─ _variables.scss
4│  ├─ _mixins.scss
5│  └─ _index.scss
6└─ main.scss
  • ในโครงสร้างนี้ _index.scss ทำหน้าที่เป็น 'API สาธารณะ'

วิธีการใช้ @forward เบื้องต้น

มาดูวิธีการใช้ @forward ในเบื้องต้นกัน

1// _variables.scss
2// Color definitions used across the project
3
4$primary-color: #006ab1;
5$secondary-color: #e0f0ff;
6
7// Internal use only (will be hidden via @forward hide)
8$debug-color: magenta;
  • แทนที่จะใช้ตัวแปรนี้โดยตรงด้วย @use คุณสามารถจัดกลุ่มโดยใช้ @forward
1// _index.scss
2@forward "variables";
  • จุดนี้ _index.scss จะไม่มีเนื้อหาใด ๆ; มันเป็น ไฟล์กลาง เท่านั้น

การใช้งานโมดูลที่ได้ @forward ไว้แล้ว

แทนที่จะ @use ไฟล์ย่อยแต่ละไฟล์โดยตรง ให้ @use เฉพาะไฟล์ index ที่รวม @forward ไว้ ในฝั่งผู้ใช้งาน คุณจึงสามารถใช้งานผ่านอินเทอร์เฟซที่มั่นคงได้โดยไม่ต้องรู้โครงสร้างภายใน

1// main.scss
2// Import the public API of the foundation layer
3@use "foundation";
4
5.button {
6  background-color: foundation.$primary-color;
7}
  • ด้วยดีไซน์นี้ แม้จะเปลี่ยนตำแหน่งของการกำหนดตัวแปรหรือ mixin คุณก็เปลี่ยนโครงสร้างภายในโดยไม่ต้องแก้โค้ดฝั่งผู้ใช้เลย

การรวมหลายโมดูลเข้าด้วยกันด้วย @forward

ในการพัฒนาจริง มักจะมีการแยกตัวแปร มิกซ์อิน และฟังก์ชันออกตามบทบาทหน้าที่ของแต่ละอย่าง สามารถเขียน @forward ได้หลายครั้ง ทำให้คุณรวมโมดูลที่แยกกันไว้ให้กลายเป็น API สาธารณะหนึ่งเดียวได้

ด้านล่างนี้ เราจะยกตัวอย่างมิกซ์อินและฟังก์ชัน พร้อมแสดงการออกแบบที่เปิดเผยสิ่งเหล่านี้ต่อภายนอกในรูปแบบอินเทอร์เฟซเดียว

 1// _mixins.scss
 2// Reusable mixins for layout and components
 3
 4// Reset default button styles
 5@mixin button-reset {
 6  appearance: none;
 7  background: none;
 8  border: none;
 9  padding: 0;
10  margin: 0;
11  font: inherit;
12  color: inherit;
13}
14
15// Clearfix utility
16@mixin clearfix {
17  &::after {
18    content: "";
19    display: table;
20    clear: both;
21  }
22}
23
24// Internal mixin (not intended to be part of the public API)
25@mixin debug-outline {
26  outline: 2px dashed red;
27}
 1// _functions.scss
 2// Utility functions for consistent styling
 3
 4@use "sass:math";
 5
 6// Convert px to rem based on a 16px root size
 7@function rem($px) {
 8  @return math.div($px, 16) * 1rem;
 9}
10
11// Clamp a value between a minimum and maximum
12@function clamp-value($value, $min, $max) {
13  @return math.max($min, math.min($value, $max));
14}
1// _index.scss
2// Re-export variables, mixins, and functions as a single public API
3@forward "variables";
4@forward "mixins";
5@forward "functions";
  • โดยเปิดเผยแค่ไฟล์ index นี้เท่านั้น คุณก็สามารถ ซ่อนโครงสร้างภายในและมอบอินเทอร์เฟซที่ใช้งานง่ายให้กับผู้ใช้

การป้องกันชื่อซ้ำ (as)

ถ้ามีตัวแปรหรือ mixin ชื่อซ้ำกันในหลายโมดูล คุณสามารถระบุ as ใน @forward เพื่อ เพิ่มคำนำหน้าให้ไม่เกิดปัญหาชื่อซ้ำ

1// Add a prefix when re-exporting to avoid name collisions
2@forward "variables" as var-*;

โค้ดนี้จะทำให้ $primary-color ใน variables ถูกเปิดเผยในชื่อใหม่ดังนี้:

1// foundation.$var-primary-color
  • วิธีนี้ช่วยให้ กำหนดกฏการออกแบบให้ชัดเจนและขยายระบบอย่างปลอดภัย เป็นเทคนิคสำคัญโดยเฉพาะในโปรเจกต์ขนาดใหญ่หรือไลบรารีที่มีการแชร์

การซ่อนสมาชิกที่ไม่จำเป็น (hide)

โมดูลอาจมี ตัวแปรหรือ mixin ที่ไว้ใช้งานเฉพาะภายในเท่านั้น การใช้ hide จะช่วยให้คุณซ่อนค่าดังกล่าวเมื่อนำไปเผยแพร่อีกครั้ง และป้องกันการเข้าถึงจากภายนอก

1// Re-export everything except internal debug variables
2@forward "variables" hide $debug-color;

ด้วยการตั้งค่านี้ $debug-color จะ ใช้งานได้เฉพาะภายในโมดูล ลดความเสี่ยงในการถูกใช้งานโดยบังเอิญจากผู้ใช้

การระบุสมาชิกที่ต้องการเปิดเผย (show)

หากต้องการเปิดเผยแค่บาง mixin หรือฟังก์ชัน ให้ใช้ show โดยการจำกัดสิ่งที่เปิดเผยออกไป คุณสามารถทำให้จุดประสงค์และแนวคิดการออกแบบของโมดูลชัดเจนยิ่งขึ้น

1// Explicitly expose only selected mixins as the public API
2@forward "mixins" show button-reset, clearfix;
  • เมื่อใช้ show แบบนี้ จะเห็นชัดในทันทีว่ามี API ตัวไหนที่เปิดให้ใช้งานอย่างเป็นทางการบ้าง

@forward ไม่สามารถใช้เพียงลำพังได้

ประเด็นสำคัญคือตัวแปรที่ถูก @forward จะไม่สามารถใช้งานภายในไฟล์นั้นเองได้

1@forward "variables";
2
3.test {
4  color: $primary-color; // Error
5}
  • @forward ใช้สำหรับ 'เปิดเผยใหม่' เท่านั้น ส่วน 'การใช้งาน' เป็นหน้าที่ของ @use

ตัวอย่างของการแบ่งหน้าที่ที่ถูกต้อง

ในการออกแบบโมดูลของ Sass ควรแยกชั้น API ที่ให้สาธารณะใช้ และ ชั้นการทำงานภายใน อย่างชัดเจน @forward กำหนด API สาธารณะ ส่วน @use ใช้งาน API นั้นจากฝั่งการใช้งานจริง

1// _index.scss (public API)
2@forward "variables";
3@forward "mixins";
1// _component.scss
2// Consume the public API of the foundation layer
3@use "foundation";
4
5.card {
6  color: foundation.$primary-color;
7}
  • ด้วยโครงสร้างนี้ จะ เห็นชัดเจนว่าส่วนไหนคืออินเทอร์เฟซสาธารณะและส่วนไหนคือการทำงานภายใน ส่งผลให้การออกแบบโปร่งใสมากขึ้น

ความแตกต่างที่ชัดเจนกับ @import

@import จะขยายทุกนิยามที่นำเข้าไปสู่ global scope ในทางตรงข้าม @use และ @forward เปิดเผยองค์ประกอบอย่างชัดเจนและเข้าถึงผ่าน namespace

 1// @import (deprecated)
 2// Everything is injected into the global scope
 3$color: red;
 4
 5.button-import {
 6  color: $color;
 7}
 8
 9// @use + @forward (recommended)
10// Access values explicitly through a namespace
11@use "foundation";
12
13.button-use {
14  color: foundation.$primary-color;
15}
  • ด้วยความแตกต่างนี้ คุณจะปรับปรุงความปลอดภัยและการดูแลรักษาให้ดีขึ้นมาก โดยหลีกเลี่ยงปัญหาการเขียนทับหรือ dependency ที่สับสนโดยไม่ตั้งใจ

สรุป

@forward เป็น ฟีเจอร์สำคัญที่ช่วยให้โค้ดของคุณดูแลรักษาง่าย เมื่อระวังว่า 'ควรเปิดเผยอะไรและอะไรเป็นการทำงานภายใน' โครงสร้างสไตล์ของคุณจะปลอดภัยและอ่านง่ายขึ้น หากใช้ @use และ @forward อย่างถูกต้อง คุณจะกำหนดความสัมพันธ์ระหว่างโมดูลได้ชัดเจน และสร้างดีไซน์ที่ทนต่อการเปลี่ยนแปลงได้ดี

คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย

YouTube Video