iT邦幫忙

2025 iThome 鐵人賽

DAY 30
0
Modern Web

Super Easy CSS,極度簡單 PART 3!讓想像躍然於螢幕之上系列 第 30

#93 SASS/SCSS (12) 防呆與偵錯 @debug / @warn / @error

  • 分享至 

  • xImage
  •  

我們已經了解了 SASS/SCSS 的所有主要功能了,不過「我要如何確保別人(或未來的自己)不會用錯我寫的工具?」這是當 Mixin 和 Function 變得越來越複雜時,需要好好考慮的問題。

在 SCSS 中,可以為自己的 Code 建立「防呆」和「除錯」機制,SCSS 提供了三個指令,也就是:@debug@warn@error。其實我們在介紹 Lists 和 Maps 時就已經稍微帶過其中的 @warn 了。

本篇同步發表於我的 Hashnode 部落格:
Eva Chen | 網頁設計師下班後 (hashnode.dev)


一、@debug:類似 JS 的 console.log

當你在寫複雜的 Function 或迴圈,想知道某個變數在某個時間點的值到底是多少時,就可以使用 @debug

它的作用就跟 JS 中的 console.log() 完全一樣,會在你的 Console 終端機 (Terminal) 的編譯訊息中,印出你想查看的任何變數或表達式。

1. 語法

@debug $你想查詢的變數;
@debug "在字串中需要使用插值語法:#{$你想查詢的變數}";
  • 用途: 檢查程式碼執行過程中的中間值,用來除錯。

  • 特性: 不會中斷編譯,只會印出訊息。

2. 範例:檢查 px-to-rem 函式的計算過程

// SCSS
@use "sass:math";

@function px-to-rem($pixels) {
    $base-font-size: 16;
    $result: math.div($pixels, $base-font-size) * 1rem;

    // 我想知道 $result 算出來到底是多少
    @debug "輸入值:#{$pixels}px,結果:#{$result}";

    @return $result;
}

h1 {
    font-size: px-to-rem(32);
}

當你存檔編譯時,你不會在產出的 CSS 檔案中看到任何東西,但在你的 Console (終端機)中,會看到以下這樣的訊息:

@debug:9  輸入值:32px,結果:2rem

這樣就能夠一目瞭然地知道 Function 的計算是否如我們預期。


二、@warn:友善的提醒

有時候,一個錯誤不至於讓整個 Code 崩潰,但你仍然希望提醒開發者「這功能即將被棄用」或是「少了這個值」。這就是 @warn 的完美使用時機。

1. 語法

@warn "你想提醒的事情";
  • 用途: 提出建議、警告棄用的功能、提醒潛在問題。

  • 特性: 不會中斷編譯,但會在終端機顯示黃色的警告訊息。

2. 範例:缺少 List 的值

// SCSS
@use "sass:list";

$z-layers: "modal", "dropdown", "tooltip";

// 尋找 'dropdown' 的位置,回傳 2
$dropdown-index: list.index($z-layers, "dropdown");

// 尋找 'header' 的位置,回傳 null
$header-index: list.index($z-layers, "header");

.dropdown-menu {
    // 可以根據索引值來計算 z-index
    z-index: $dropdown-index; // 結果為 2
}

@if not $header-index {
    // 由於 $header-index 是 null,這個警告會被觸發
    @warn "在 z-layers 列表中找不到 'header'。";
}

編譯會成功,但終端機會顯示一條清晰的警告,提醒開發者:

@warn:19  在 z-layers 列表中找不到 'header'。

三、@error:守護你程式碼底線的最後防線

當傳入的參數完全錯誤,會導致產生無效或毀滅性的 CSS 時,你必須立即中止編譯過程,並告訴開發者他到底做錯了什麼。這就是 @error 的用途。 它可以印出錯誤訊息及堆疊追蹤,讓開發者能快速定位問題。

1. 語法

@error "error 原因";
  • 用途: 驗證 Function 或 Mixin 的參數與已知錯誤的情況,防止產生無效的 CSS。

  • 特性: 立即中斷編譯,並在終端機顯示紅色的錯誤訊息。

2. 範例:結合 sass:metasass:math 驗證 Mixin 參數

為了讓工具(Mixin 或 Function)更穩固,我們可以使用 Sass 內建的模組來進行更嚴謹的參數驗證。

  • sass:meta:提供了一系列可以「檢查」Sass 語法結構中各種資訊的功能。其中 meta.type-of() 函式可以回傳傳入值的「型別」(例如:number, string, color 等)。

  • sass:math:提供了許多數學相關的函式。 其中 math.is-unitless() 函式可以檢查一個數值是否「不帶單位」。

假設我們有個畫出圓形的 Mixin,我們要確定傳入的 $size 必須是一個帶有單位的數字。

// SCSS
@use "sass:meta";
@use "sass:math";

@mixin circle($size) {
    // 第一關:檢查傳入的是否為數字型別
    @if meta.type-of($size) != "number" {
        @error "傳入 circle mixin 的 $size 參數型別錯誤,必須是數字 (Number),但卻收到了 '#{$size}' (#{meta.type-of($size)})。";
    }
    // 第二關:檢查數字是否帶有單位
    @if math.is-unitless($size) {
        // 如果條件成立,就拋出錯誤並停止編譯!
        @error "傳入 circle mixin 的 $size 參數 ('#{$size}') 必須是一個帶有單位的數字 (例如: 100px)。";
    }

    width: $size;
    height: $size;
    border-radius: 50%;
}

.avatar-correct {
    @include circle(100px);     // 這會正常運作
}

.avatar-wrong-type {
    @include circle("200px"); // 這會觸發第一個 @error,因為 "200px" 是字串 (String)
}

.avatar-wrong-unit {
    @include circle(300);       // 這會觸發第二個 @error,因為 300 是無單位數字
}

當編譯這段程式碼時,只要遇到不符合條件的 @include,編譯就會立刻失敗,並在 Console(終端機)中顯示你事先寫好的錯誤原因,明確告訴開發者問題出在哪裡。

3. 錯誤訊息

(1) 如果觸發第一個錯誤的訊息:

@error:26  "傳入 circle mixin 的 $size 參數型別錯誤,必須是數字 (Number),但卻收到了 '200px' (string)。"
   ╷
26 │     @include circle("200px");
   │     ^^^^^^^^^^^^^^^^^^^^^^^^
   ╵

(2) 如果觸發第二個錯誤的訊息:

@error:30  "傳入 circle mixin 的 $size 參數 ('300') 必須是一個帶有單位的數字 (例如: 100px)。"
   ╷
30 │     @include circle(300);
   │     ^^^^^^^^^^^^^^^^^^^^
   ╵
  - 30:5  root stylesheet

透過這種方式,可以有效避免團隊成員或未來的自己因為不了解你做的工具而產生壞掉的 CSS,事先把已知的錯誤寫好,這樣未來遇到問題時就不用找問題找個老半天,能夠快速找問題主因並解決它。


哇!鐵人賽終於完結啦!感動!

之後還有可能會更新這系列文章,也許可以湊到 100 篇?
不過終於沒有時間壓力啦!突然感覺到放鬆不少。 :)

真正的心得文之後真正完結,會再仔細寫,
雖然可能看起來都穩穩地產出,但其實這次鐵人賽也遇到不少小風波呀!


↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

感謝看到最後的你,若你覺得獲益良多,請不要吝嗇給我按個喜歡。❤️

如果你喜歡我的創作,還想看看其他有趣的分享與日常,
可以追蹤我的 IG @im1010ioio,或者是🧋送杯珍奶鼓勵我,謝謝你🥰。

Eva Chen 送杯珍奶鼓勵我


上一篇
#92 SASS/SCSS (11) 資料結構 Map
系列文
Super Easy CSS,極度簡單 PART 3!讓想像躍然於螢幕之上30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
Antonio
iT邦新手 2 級 ‧ 2025-10-14 09:54:12

恭喜完賽!每次看完文章都有「原來還可以這樣用」的驚喜感,從第一年鐵人賽就開始追了,每年都很期待你的文章,總能看到 CSS 的更多可能性。今年同樣收穫滿滿 > <

Eva Chen iT邦新手 1 級 ‧ 2025-10-14 10:48:55 檢舉

謝謝你!!(感動)
這次我自己也是收穫很多,很多都是我第一次研究的。
也能給你幫助真是太好了,感謝支持!/images/emoticon/emoticon07.gif

我要留言

立即登入留言