關鍵要點
@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中文網其他相關文章!