SASS 모듈
이 글은 SASS 모듈에 대해 설명합니다.
@use와 @forward를 사용하여 SASS를 모듈화하는 방법과 변수, 믹스인, 함수, 테마 설정, 공개 API를 재사용하는 방법을 설명합니다.
YouTube Video
SASS 모듈
SASS 모듈 시스템은 스타일의 범위를 명확하게 지정하고 재사용 및 유지관리가 쉬운 구조를 제공합니다.
모듈의 기본 개념
SASS 모듈은 기존의 @import에서 발생했던 전역 네임스페이스 오염과 불분명한 의존성 문제를 해결합니다. 각 파일은 자신만의 네임스페이스를 가진 모듈로 로드되며, 명시적으로 내보낸 항목만 다른 파일에서 접근할 수 있습니다.
예시 파일 구조
먼저, 실제적인 프로젝트 구조의 예시를 보여드립니다. 아래는 소규모 디자인 시스템의 예시입니다.
1styles/
2├─ _variables.scss
3├─ _mixins.scss
4├─ _functions.scss
5├─ components/
6│ ├─ _button.scss
7│ └─ _card.scss
8├─ utilities/
9│ └─ _helpers.scss
10└─ main.scss- 이 구조는 모듈화는 물론, 부분별 테스트 및 교체도 쉽게 만들어 줍니다.
- 부분 파일은 파일명 앞에 밑줄(_)이 붙습니다.
@use의 기본
@use는 모듈을 로드하고 네임스페이스를 제공합니다. 이로 인해 이름 충돌을 막고, 소스 모듈을 명확하게 구분할 수 있습니다.
1// _variables.scss
2$primary-color: #0a74da;
3$padding-base: 12px;- 이 파일은 변수만 정의하는 단순한 파일입니다. 모듈에서 공개된 변수는
@use로 직접 참조할 수 있습니다.
1// main.scss
2@use 'variables';
3
4.example {
5 color: variables.$primary-color;
6 padding: variables.$padding-base;
7}- 여기에서는
variables모듈을variables.네임스페이스로 참조합니다. 이 접근법은 각 항목의 출처를 명확하게 해줍니다.
네임스페이스 단축/별칭 지정
as를 사용하면 네임스페이스를 짧게 지정할 수 있습니다.
1@use 'variables' as vars;
2
3.btn {
4 color: vars.$primary-color;
5}- 이것은
variables를 더 짧은 별칭vars로 가져오는 예시입니다. 가독성 또는 입력의 편리성 중 우선순위에 따라 이름을 선택하세요.
믹스인 정의
믹스인과 함수도 모듈 내에서 정의하고 사용할 수 있습니다. 주석을 프로젝트 규칙에 맞추어 통일함으로써 명확성을 높일 수 있습니다.
1// _mixins.scss
2// Create a simple responsive container mixin
3@mixin container($max-width: 1200px) {
4 width: 100%;
5 margin-left: auto;
6 margin-right: auto;
7 max-width: $max-width;
8}- 이 파일은 컨테이너용 믹스인을 정의합니다. 이 믹스인은 인자를 받으며, 기본값도 제공합니다.
1// main.scss
2@use 'mixins' as m;
3
4.wrapper {
5 @include m.container(1000px);
6}@include를 이용한 믹스인 사용 예시입니다.
함수 정의
함수는 값을 반환하는 데 사용되며, 모듈 내에서 정의하고 재사용할 수 있습니다. 디자인 값 계산을 함수로 캡슐화하면 스타일이 더 안정적이고 유지관리가 쉬워집니다.
1// _functions.scss
2@use 'sass:math';
3
4// Create a simple px-to-rem converter function
5@function to-rem($px, $base: 16) {
6 @return math.div($px, $base) * 1rem;
7}- 이 파일은 픽셀 값을 rem으로 변환하는 함수를 정의합니다. 기본 기준 값도 지정되어 있습니다.
1// main.scss
2@use 'functions' as f;
3
4.title {
5 font-size: f.to-rem(24);
6}@use를 통해 함수를 호출하고 결과를 스타일에 적용하는 예시입니다.
모듈 내보내기와 @forward (API 설계)
여러 내부 파일을 외부에 공개하고 싶을 때, @forward를 이용해 '공개 API'를 만들 수 있습니다.
1// _index.scss (module entry)
2@forward 'variables';
3@forward 'mixins';
4@forward 'functions';- 여러 내부 파일을 하나의 진입점으로 묶어, 그 진입점이 퍼블릭 API를 제공합니다. 이렇게 하면 하나의 진입점만 가져와도 모든 필요한 기능을 사용할 수 있습니다.
1// main.scss
2@use 'index' as ds; // ds = design system
3
4.button {
5 color: ds.$primary-color;
6 @include ds.container();
7}variables와mixins의 내용을index를 통해 한 번에 접근할 수 있습니다.@forward로 인해index가 퍼블릭 레이어가 됩니다.
@forward의 show / hide 옵션으로 API를 제어하기
특정 변수만 공개하고 싶다면 show 또는 hide 옵션을 사용하세요.
1// _variables.scss
2$internal-thing: 10px !default; // for internal use
3$primary-color: #0a74da !default;
4$secondary-color: #f5f5f5 !default;!default를 추가하면 값이 덮어쓰기 가능하도록 공개할 수 있습니다.
1// _index.scss
2@forward 'variables' show $primary-color, $secondary-color;
3@forward 'mixins';@forward의show를 이용해 필요한 요소만 API로 노출할 수 있습니다. 내부에서만 사용하는 변수와 함수는 외부에서 보이지 않습니다.
모듈 구성 가능하게 만들기 (with 사용)
모듈에 !default를 사용하면, 가져오는 쪽에서 with로 값을 덮어쓸 수 있습니다.
1// _theme.scss
2$brand-color: #ff6600 !default;
3$radius: 4px !default;
4
5@mixin button-style() {
6 background-color: $brand-color;
7 border-radius: $radius;
8}!default로 기본값이 정의된 모듈은with로 설정을 받을 수 있습니다.
1// main.scss
2@use 'theme' with (
3 $brand-color: #2288ff,
4 $radius: 8px
5);
6
7.my-btn {
8 @include theme.button-style();
9}@use의with는 가져올 때 모듈의 기본 변수를 덮어쓸 수 있게 해줍니다. 이는 테마 전환에 유용하게 쓰입니다.with는 가져올 때 한 번만 적용되며, 이후에는 값을 바꿀 수 없음에 유의하세요.
실전 예시: 버튼 컴포넌트 (완성 예제)
모듈을 사용해 버튼 스타일을 설계해 봅시다. 먼저, 변수와 믹스인을 각각의 모듈로 분리합니다.
1// _variables.scss
2$btn-padding-y: 8px !default;
3$btn-padding-x: 16px !default;
4$btn-font-size: 14px !default;
5$btn-primary-bg: #0a74da !default;
6$btn-primary-color: #fff !default;- 여기에 버튼용 기본 변수가 정의되어 있습니다.
!default를 사용하면, 사용자가 이 값을 덮어쓸 수 있습니다.
1// _mixins.scss
2@use "variables" as v;
3
4@mixin btn-base() {
5 display: inline-flex;
6 align-items: center;
7 justify-content: center;
8 padding: v.$btn-padding-y v.$btn-padding-x;
9 font-size: v.$btn-font-size;
10 border: none;
11 cursor: pointer;
12}- 버튼용 기본 믹스인은 여기에서 정의합니다. 재사용성을 위해 따로 분리해 두었습니다.
1// _button.scss
2@use 'variables' as v;
3@use 'mixins' as m;
4
5.button {
6 @include m.btn-base();
7 background: v.$btn-primary-bg;
8 color: v.$btn-primary-color;
9 border-radius: 4px;
10 transition: opacity 0.15s ease;
11 &:hover { opacity: 0.9; }
12}
13
14.button--large {
15 padding: calc(v.$btn-padding-y * 1.5) calc(v.$btn-padding-x * 1.5);
16 font-size: v.$btn-font-size * 1.25;
17}- 버튼 스타일은
@use로 네임스페이스를 참조하여 만듭니다. 변형(variant)은.button--large로 정의합니다.
1// main.scss
2@use 'button'; // or @use 'index' that forwards button, variables, mixinsbutton모듈을 가져오면 버튼 스타일을 바로 사용할 수 있습니다.
테마 전환 (여러 테마 파일 사용하기)
with로 구성하거나, 별도의 모듈을 만들어 @use로 사용할 모듈을 바꿔 테마를 전환할 수 있습니다.
1// themes/_light.scss
2$brand-color: #0a74da !default;1// themes/_dark.scss
2$brand-color: #111827 !default;- 여러 테마 파일에 브랜드 컬러 및 기타 설정을 정의한 뒤, 빌드 또는 가져오기 시에 전환하십시오.
1// main.scss (light theme)
2@use 'theme' with ($brand-color: #0a74da);
3@use 'button';with를 사용하거나, 빌드 과정에서 예를 들어@use 'themes/light'로 테마를 선택할 수 있습니다.
비공개와 공개 (접두사 _ 및 !default)
SASS에서 파일 이름 앞에 밑줄을 추가하면 해당 파일이 파셜로 인식됩니다. 하지만 모듈 내보내기(공개) 범위 관리는 @forward의 show와 hide로 제어하세요.
@forward로 공개 API를 구성하고, 내부 구현을 외부에서 숨길 수 있습니다.
실무 활용을 위한 베스트 프랙티스
실제 SASS를 사용할 때 유용한 기본 개념들을 아래에 정리했습니다. 이런 가이드라인을 따르면 개발 시 혼란을 줄이고 코드를 정돈할 수 있습니다.
- 테마에 따라 바뀔 가능성이 있는 변수에
!default를 추가하세요. 이렇게 하면 사용자가 값을 오버라이드하기 쉬워집니다. - 모듈은 역할에 따라 나누고, 한 가지 목적에 집중하는 것이 좋습니다. 변수, 믹스인, 컴포넌트를 분리하여 관리가 더 쉬워집니다.
- 공개 범위 관리는
@forward로 하고, 필요에 따라show나hide를 쓰세요. 공개 범위를 명확히 정하면 안전한 설계가 됩니다. - 네임스페이스로 각 함수의 소속 모듈을 명확하게 하세요. 이렇게 하면 다른 코드와의 혼동을 막을 수 있습니다.
with는@use시점에만 적용됨을 기억하세요. 나중에 바꿀 수 없으니, 가져올 때 구성을 정하세요.- 파일명 첫 부분에 밑줄을 붙여 부분 파일로 만들면, 각각 따로 컴파일되지 않습니다. 이렇게 하면 파일을 더 큰 구조로 쉽게 조합할 수 있습니다.
index모듈에 사용 예시를 포함시키면 테스트와 문서화에 도움이 됩니다. 사용자가 동작을 더 쉽게 이해할 수 있습니다.
이 내용을 명심하면 대규모 프로젝트 관리나 팀 코드 가독성 유지에 도움이 됩니다.
요약
SASS 모듈 시스템은 네임스페이스와 공개 API, 간소화된 설정을 통해 스타일 코드를 정리합니다. @use와 @forward를 잘 활용하면 팀 개발, 테마 전환, 라이브러리 설계가 훨씬 쉬워집니다.
위의 기사를 보면서 Visual Studio Code를 사용해 우리 유튜브 채널에서 함께 따라할 수 있습니다. 유튜브 채널도 확인해 주세요.