SASS에서의 `@forward`

SASS에서의 `@forward`

이 글은 SASS의 @forward에 대해 설명합니다.

@forward에 대해 실용적인 예시를 포함하여 이해하기 쉽게 설명하겠습니다.

YouTube Video

SASS에서의 @forward

@forward란 무엇인가요?

SASS의 모듈 시스템에서는 @import 대신 **@use@forward**를 사용합니다. @forward는 아키텍처를 깔끔하게 유지하는 데 중요한 기능입니다. 이는 다른 파일에 정의된 변수, 믹스인, 함수들을 '외부에 공개'하는 데 사용하는 지시문입니다. 단독으로 사용하기보다는, '여기서부터 이 모듈을 사용하세요'라는 입구 역할을 합니다.

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하는 대신, 여러 @forward가 모여 있는 인덱스 파일만을 소비자 측에서 @use합니다. 이렇게 하면 내부 구조를 신경쓰지 않고 안정적인 인터페이스로 사용할 수 있습니다.

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}
  • 이런 설계에서는 변수나 믹스인의 정의 위치가 바뀌어도 소비자 쪽 코드를 수정하지 않고 내부 구조만 바꿀 수 있습니다.

@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)

여러 모듈에 같은 이름의 변수나 믹스인이 정의되어 있다면, @forwardas를 사용해 접두어를 추가하여 이름 충돌을 방지할 수 있습니다.

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

이 코드에서는 variables$primary-color가 다음과 같이 노출됩니다:.

1// foundation.$var-primary-color
  • 이 방법은 디자인 규칙을 명확히 하고, 안전하게 확장하는 방법이며, 특히 대형 프로젝트나 공유 라이브러리에서 필수적인 기술입니다.

불필요한 멤버 숨기기 (hide)

모듈에는 내부 구현에만 사용되는 변수나 믹스인이 있을 수 있습니다. hide를 사용하면 다시 노출할 때 이들을 제외시켜, 외부에서 접근하지 못하게 할 수 있습니다.

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

이 설정을 사용하면 $debug-color모듈 내부에서만 유효하여, 소비자가 실수로 사용하는 것을 막을 수 있습니다.

노출할 멤버 지정하기 (show)

특정 믹스인이나 함수만 노출하고 싶다면 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가 이를 구현 쪽에서 사용합니다.

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는 모든 가져온 정의를 글로벌 스코프에 확장합니다. 반면에 @use@forward항목을 명시적으로 노출하고 네임스페이스를 통해 접근합니다.

 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}
  • 이 차이로 인해 예기치 않은 덮어쓰기나 의존성 혼동을 막아 유지보수성과 안전성을 크게 높일 수 있습니다.

요약

@forward유지보수에 강한 디자인을 지원하는 중요한 기능입니다. '공개할 것과 내부 구현으로 숨길 것을 의도적으로 구분하면' 스타일 구조가 더 안전하고 가독성이 좋아집니다. @use@forward를 적절히 사용하면 의존성을 명확히 하고 변화에 강한 디자인을 실현할 수 있습니다.

위의 기사를 보면서 Visual Studio Code를 사용해 우리 유튜브 채널에서 함께 따라할 수 있습니다. 유튜브 채널도 확인해 주세요.

YouTube Video