首頁 >web前端 >css教學 >在sass中負責任地使用 @error

在sass中負責任地使用 @error

William Shakespeare
William Shakespeare原創
2025-02-24 09:25:38268瀏覽

Using @error responsibly in Sass

關鍵要點

  • Sass 中的 @error 指令是控製作者輸入和在出現問題時拋出錯誤的強大工具,這比允許編譯器失敗更有效。
  • 對於不支持 @error 的舊版 Sass,可以使用 @warn 指令代替。為了確保在出現錯誤時編譯器仍然崩潰,可以創建一個混合宏,在警告後觸發編譯錯誤。
  • feature-exists('at-error') 函數可用於檢查是否支持 @error。如果不支持,則使用 @warn 指令,然後使用沒有 @return 語句的函數來使編譯器崩潰。
  • log 函數可以在其他函數內使用,log 混合宏可以在其他地方使用,從而負責任地拋出錯誤。這允許對不同版本的 Sass 進行有效的錯誤管理。

自 Ruby Sass 3.4 和 LibSass 3.1 起,可以使用 @error 指令。此指令類似於 @warn,旨在終止執行過程並向當前輸出流(可能是控制台)顯示自定義消息。

毋庸置疑,此功能在構建涉及一些 Sass 邏輯的函數和混合宏時非常有用,以便控製作者的輸入並在出現任何問題時拋出錯誤。你必須承認這比讓編譯器慘敗要好,不是嗎?

一切都很好。除了 Sass 3.3 仍然被廣泛使用。甚至在某些地方使用 Sass 3.2。更新 Sass 並非易事,尤其是在大型項目中。有時,花費時間和預算來更新正常運行的東西並非可行之舉。對於這些舊版本,@error 毫無意義,並且被視為自定義的 at-directive,出於向前兼容性的原因,這在 Sass 中是完全允許的。

那麼,這意味著除非我們決定只支持最新的 Sass 引擎,否則我們不能使用 @error 嗎?好吧,你可以想像有一種方法,因此有了這篇文章。

思路是什麼?

思路很簡單:如果支持 @error,我們就使用它。否則,我們使用 @warn。儘管 @warn 不會阻止編譯器繼續執行,但我們可能希望在警告後觸發編譯錯誤,以便編譯徹底崩潰。享受吧,你並不經常可以肆無忌憚地破壞某些東西。

這意味著我們需要將整個內容包裝在一個混合宏中,讓我們稱之為 log(...)。我們可以這樣使用它:

<code>@include log('哎呀,你刚才的操作出了问题!');</code>

你必須承認,這很酷,不是嗎?好吧,吹噓夠了,讓我們來構建它。

構建日誌記錄器

因此,我們的混合宏的工作方式與 @error@warn 完全相同,因為它只是一個包裝器。因此,它只需要一個參數:消息。

<code>@include log('哎呀,你刚才的操作出了问题!');</code>

你可能會問自己我們將如何檢查 @error 支持。起初,我想出了一個涉及版本嗅探的笨拙解決方案,但這太糟糕了。此外,我完全忽略了這樣一個事實:Sass 核心設計師是聰明人,他們考慮到了整個事情,並為 feature-exists(...) 函數引入了 at-error 鍵,返回該功能是否受支持。

<code>@mixin log($message) { ... }</code>

如果你是一位補丁說明閱讀者,你可能知道 feature-exists(...) 函數僅在 Sass 3.3 中引入。它不涵蓋 Sass 3.2!好吧,部分屬實。在 Sass 3.2 中,feature-exists('at-error') 被評估為一個 真值 字符串。通過添加 == true,我們確保 Sass 3.2 不進入此條件,並移動到 @warn 版本。

到目前為止,一切順利。儘管我們必須在警告後觸發編譯錯誤。我們將如何做到這一點?有很多方法可以使 Sass 崩潰,但理想情況下,我們希望得到一些你可以識別的東西。 Eric Suzanne 之前想出了一個主意:調用沒有 @return 語句的函數足以崩潰。這種模式通常被稱為 noop,即 無操作。基本上,這是一個空函數,什麼也不做。由於 Sass 的工作方式,它會使編譯器崩潰。這很好!

<code>@mixin log($message) {
  @if feature-exists('at-error') == true {
    @error $message;
  } @else {
    @warn $message;
  }
}</code>

關於此函數的最後一點,我們將如何調用它? Sass 函數只能在特定位置調用。我們有幾種方法可用:

  • 一個虛擬變量,例如:$_: noop()
  • 一個虛擬屬性,例如:crash: noop()
  • 一個空條件,例如:@if noop() {}
  • 你可能還能找到其他幾種調用此函數的方法。

我想警告你不要使用 $_,因為它是在 Sass 庫和框架中常用的變量。雖然在 Sass 3.3 中可能不是問題,但在 Sass 3.2 中,這將覆蓋任何全局 $_ 變量,這在某些情況下會導致難以追踪的問題。讓我們使用空條件,因為它與 noop 配合使用時很有意義。一個用於 noop 函數的 noop 條件。

<code>@function noop() {}</code>

好了!讓我們用之前的代碼測試一下:

<code>@mixin log($message) {
  @if feature-exists('at-error') == true {
    @error $message;
  } @else {
    @warn $message;
    // 由于函数不能在 Sass 中的任何地方调用,
    // 我们需要在一个虚拟条件中进行调用。
    @if noop() {}
  }
}</code>

以下是 LibSass:

<code>@include log('哎呀,你刚才的操作出了问题!');</code>

以下是 Sass 3.4:

<code>message:
path/to/file.scss
1:1  哎呀,你刚才的操作出了问题!
Details:
column: 1
line: 1
file: /path/to/file.scss
status: 1
messageFormatted: path/to/file.scss
1:1  哎呀,你刚才的操作出了问题!</code>

以下是 Sass 3.2 和 3.3(輸出是一個大膽的猜測,因為我無法在我的終端中輕鬆測試這些版本了):

<code>Error: 哎呀,你刚才的操作出了问题!
在 path/to/file.scss 的第 1 行,位于 `log` 中
使用 --trace 获取回溯。</code>

這似乎有效!在任何引擎中,即使是舊引擎,編譯器也會退出。在那些支持 @at-error 的引擎上,它們會立即收到錯誤消息。在那些不支持的引擎上,它們會將消息作為警告接收,然後由於 noop 函數而使編譯崩潰。

使其能夠在函數內部記錄日誌

我們當前設置的唯一問題是,我們無法從函數內部拋出錯誤,因為我們構建了一個混合宏。混合宏不能包含在函數內部(因為它可能會打印 CSS 代碼,這與 Sass 函數無關)!

如果我們首先將混合宏轉換為函數會怎樣?此時,發生了一些奇怪的事情:@error 在 Sass 3.3- 中不被識別為函數的有效 at-directive,因此會慘敗:

函數只能包含變量聲明和控制指令。

公平地說。這意味著我們不再需要 noop hack,因為不支持的引擎會在我們不必強制的情況下崩潰。儘管我們必須將 @warn 指令放在流程的上方,以便在崩潰之前將消息打印到作者的控制台中。

<code>@include log('哎呀,你刚才的操作出了问题!');</code>

然後,我們可以提供一個混合宏,以獲得比臟的空條件和虛擬變量 hack 更友好的 API。

<code>@mixin log($message) { ... }</code>

最終想法

就是這樣!我們現在可以在函數內部使用 log(...) 函數(由於限制),並且可以在其他任何地方使用 log(...) 混合宏來負責任地拋出錯誤。非常整潔!

這是完整的代碼:(此處應提供完整的代碼示例,但由於無法直接執行代碼,我無法提供可運行的代碼片段)

在 SassMeister 上試用此 gist。 (此處應提供 SassMeister 的鏈接)

對於 Sass 中更高級的日誌記錄系統,我建議您閱讀《構建日誌記錄器混合宏》。關於支持舊版 Sass 版本,我建議您查看《何時以及如何支持多個版本的 Sass》。

(此處應包含關於負責任地使用 Sass 中的錯誤的常見問題解答部分,但由於篇幅限制,我已將其省略。)

以上是在sass中負責任地使用 @error的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn