SassDoc 是一款專門為 Sass 程式碼生成註釋的工具,通過 SassDoc,開發者可以通過類似 JSDoc 的方式在 Sass 程式碼上新增註釋,然後直接用命令生成文件。最近在處理團隊框架 QMUI Web 時,遇到了需要為大量 Sass 方法寫文件的問題,因此研究了這個工具,本文將會詳細說明 SassDoc 的使用方法以及其中的最佳實踐。
基本使用
在 Sass 中,可以使用多行註釋 /* xxxx */
和單行註釋 // xxxx
兩種註釋方法。如文章開頭所述,SassDoc 是使用類似 JSDoc 的方式,即在程式碼中通過註釋編寫文件內容的方式生成文件,因此 SassDoc 有特定的註釋語法:
/// 跨瀏覽器的漸變背景,垂直漸變,自上而下
///
/// @group 外觀
/// @name gradient_vertical
/// @param {Color} $start-color [#555] - 漸變的開始顏色
/// @param {Color} $end-color [#333] - 漸變的結束顏色
/// @param {Number} $start-percent [0%] - 漸變的開始位置,需要以百分號為單位
/// @param {Number} $end-percent [100%] - 漸變的結束位置,需要以百分號為單位
@mixin gradient_vertical($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%){
background-image: -webkit-gradient(linear, left top, left bottom, color-stop($start-percent, $start-color), color-stop($end-percent, $end-color)); // Safari 4-5, Chrome 1-9
background-image: -webkit-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // Safari 5.1-6, Chrome 10+
background-image: -moz-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // Firefox 3.6+
background-image: -o-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // Opera 12
background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=0); // IE9 and down
}複製程式碼
總結如下:
- 使用
///
作為 SassDoc 的註釋標識(舊版的 SassDoc 中,使用的是 Sass 的註釋方式,但這樣這些註釋也會被輸出到 CSS 程式碼中,因此最新版的 SassDoc 選擇重新定義一個///
作為專屬的註釋方式) ///
中的第一行沒有任何標記的文字會被當作 Sass 方法的描述- 帶有
@name
,@param
這類標記的會當作對應的註釋屬性,完整的標記列表可以參考 sassdoc.com/annotations…
按照以上的方法,在 Sass 程式碼上寫好了需要的註釋,接下來就應該輸出文件了。輸出文件首先要安裝 SassDoc 工具:
npm install sassdoc -g複製程式碼
然後對需要生成文件的 Sass 檔案執行如下命令:
sassdoc sassFileName複製程式碼
例如:對 _compatible.scss 執行上面的操作,會直接生成如下的文件頁面:
如上圖各個方法已經根據註釋的內容輸出對應的文件,並且文件的樣式也很完善。至此,就是 SassDoc 的基本使用。
進階使用
使用非預設主題以及其他選項
如果對預設的樣式不滿意,也可以使用官網提供的其他主題,在介紹如何使用其他主題時,先要介紹一下 SassDoc 的選項:
- dest SassDoc 的輸出目錄,預設為
./sassdoc
- exclude 排除某些 Sass 檔案,可以使用 * 萬用字元,型別為陣列
- package 型別為 String 或 Object,該選項可以告知 SassDoc 專案的標題,版本號等資訊,預設值為
./package.json
- theme 文件的主題,預設為 default
- autofill 規定那些屬性需要儘量自動補全,預設為
["requires", "throws", "content"]
- groups 該方法的分組,文件中會根據把同一個分組的方法歸類到一起展示,預設為
{ undefined: "general" }
- no-update-notifier 在使用 SassDoc 時(例如執行輸出文件的命令),如果當前的 SassDoc 不是最新版本,會有輸出提示,這個選項可以控制取消這個提示,預設為
false
- verbose SassDoc 預設不會輸出各個文件的生成進度,如果需要可以把這個選項設定為
true
- strict 嚴格模式,預設為
false
,開啟後則使用一些廢棄語法會報錯(例如上面提到的舊版中可以使用的多行註釋)
可以看出,如果希望使用其他主題,只需要下載對應的主題,並且在 theme
這個選項中進行配置即可,官方的其他主題列表。
檔案級註解
SassDoc 提供了一個檔案級註解的功能,檔案級註解與上面的普通註解相似,但是並不是書寫在每個方法之上,而是寫在檔案的開頭,它作用是當方法的註解缺少某些屬性時,會自動把檔案級註解當作預設值使用。
例如在 _calculate.scss 中,方法的註解中都沒有寫 group
這個屬性,但在檔案級註解中有 group
屬性,後續生成的文件都會以檔案級註解中的 group
值當作自身的值。
程式碼:
////
/// 輔助數值計算的工具方法
/// @author Kayo
/// @group 數值計算
/// @date 2015-08-23
////
/// 獲取 CSS 長度值屬性(例如:margin,padding,border-width 等)在某個方向的值
///
/// @name getLengthDirectionValue
/// @param {String} $property - 記錄著長度值的 SASS 變數
/// @param {String} $direction - 需要獲取的方向,可選值為 top,right,bottom,left,horizontal,vertical,其中 horizontal 和 vertical 分別需要長度值的左右或上下方向值相等,否則會報 Warning。
/// @example
/// // UI 介面的一致性往往要求相似外觀的元件保持距離、顏色等元素統一,例如:
/// // 搜尋框和普通輸入框分開兩種結構處理,但希望搜尋框的搜尋 icon 距離左邊的空白與
/// // 普通輸入框游標距離左邊的空白保持一致,就需要獲取普通輸入框的 padding-left
/// $textField_padding: 4px 5px;
/// .dm_textField {
/// padding: $textField_padding;
/// }
/// .dm_searchInput {
/// position: relative;
/// ...
/// }
/// .dm_searchInput_icon {
/// position: absolute;
/// left: getLengthDirectionValue($textField_padding, left);
/// ...
/// }
@function getLengthDirectionValue($property, $direction) {
...
}複製程式碼
效果:
最佳實踐
完全自定義外觀
如果你不喜歡 SassDoc 提供的主題,或者本身的文件有一整套樣式(例如上面提到的框架有自己的完整官網,因此 Sass 方法的文件也需要配合官網的風格),那麼你就需要完全自定義樣式。對開發者來說,常用的思路應該是把 Sass 程式碼中的註釋輸出為特定格式,例如 JSON,然後頁面中通過讀取這些資料輸出 HTML。
SassDoc 中也提供了一些相關的介面,第一步是把指定的 Sass 檔案讀取出裡面的註解,並輸出陣列,在此之前,你需要建立一個腳手架,方便你呼叫這個任務,持續地更新你的文件,例如使用 Gulp,首先在本地目錄安裝 SassDoc:
npm install sassdoc --save-dev複製程式碼
然後建立一個 Gulp 的 Task:
gulp.task('readToolMethod', false, function(){
var sassdoc = require('sassdoc');
sassdoc.parse([
'./qmui/helper/mixin/'
], {verbose: true})
.then(function (_data) {
// 文件的資料
console.log(_data);
});
});複製程式碼
可以看到,會輸出陣列格式的資料,並把每個方法作為一個 Object,Object 中包含了各個註解屬性及其屬性值:
接下來,你就可以根據這個資料拼接 HTML 了。
資料分組
SassDoc 中輸出的陣列資料並沒有按不同 Group 把方法歸類到不同的陣列中,但在拼接 HTML 時,我們一般需要把方法按 group 歸類到不同的陣列中,方便遍歷。這裡給出一個方法,把剛剛的陣列按 group 拆分成二維陣列:
gulp.task('readToolMethod', false, function(){
var fs = require('fs'),
sassdoc = require('sassdoc'),
_ = require('lodash');
sassdoc.parse([
'./qmui/helper/mixin/'
], {verbose: true})
.then(function (_data) {
if (_data.length > 0) {
// 按 group 把陣列重新整理成二維陣列
var _result = [],
_currentGroup = null,
_currentGroupArray = null;
for (var _i = 0; _i < _data.length; _i++) {
var _item = _data[_i];
// 由於 IE8- 下 default 為屬性的保留關鍵字,會引起錯誤,因此這裡要把引數中這個 default 的 key 從資料裡改名
if (_item.parameter) {
for (var _j = 0; _j < _item.parameter.length; _j++) {
var _paraItem = _item.parameter[_j];
if (_paraItem.hasOwnProperty('default')) {
_paraItem['defaultValue'] = _paraItem['default'];
delete _paraItem['default'];
}
}
}
if (!_.isEqual(_item.group, _currentGroup)) {
_currentGroup = _item.group;
_currentGroupArray = [];
_result.push(_currentGroupArray);
} else {
_currentGroupArray = _result[_result.length - 1];
}
_currentGroupArray.push(_item);
}
_result.reverse();
// 準備把陣列寫入到指定檔案中
var _outputPath = './qmui_tools.json';
// 寫入檔案
fs.writeFileSync(_outputPath, 'var comments = ' + JSON.stringify(_result), 'utf8');
}
});
});複製程式碼
上面演示瞭如何把陣列按 group 拆分為二維陣列,並以 JSON 格式寫入到檔案中,方便拼接 HTML。需要注意的是,@param 這個註解中有一個 default 屬性,代表引數的預設值,因此生成 JSON 後會產生一個 default 屬性,在 IE8- 下,default 為屬性的保留關鍵字,直接使用會引起錯誤,因此這裡要把引數中這個 default 的 key 從資料裡重新命名,避免發生這種錯誤。
重新拼接方法體
在書寫文件時,一般需要列出方法體(即完整的方法宣告),例如:
SassDoc 輸出的資料中本身不包含方法體,但是提供了組成方法體需要的資料,下面的方法可以利用一個 SassDoc 的 item 拼接處完整的方法體:
var makeCompleteMethodWithItem = function(item) {
var result = '',
itemType = null;
if (item.context.type === 'placeholder') {
itemType = '%';
} else {
itemType = item.context.type + ' ';
result = '@';
}
result = result + itemType + item.context.name;
if (item.parameter) {
result += '(';
var paraList = item.parameter;
for (var paraIndex = 0; paraIndex < paraList.length; paraIndex++) {
var paraItem = paraList[paraIndex];
if (paraIndex !== 0) {
result += ', 複製程式碼
__JJ_LT_JJ__/span__JJ_GT_JJ__;
} __JJ_LT_JJ__span class="hljs-keyword"__JJ_GT_JJ__else__JJ_LT_JJ__/span__JJ_GT_JJ__ {
result += __JJ_LT_JJ__span class="hljs-string"__JJ_GT_JJ__'__JJ_LT_JJ__/span__JJ_GT_JJ__;
}
result += paraItem.name;
__JJ_LT_JJ__span class="hljs-keyword"__JJ_GT_JJ__if__JJ_LT_JJ__/span__JJ_GT_JJ__ (paraItem.defaultValue) {
result = result + __JJ_LT_JJ__span class="hljs-string"__JJ_GT_JJ__': '__JJ_LT_JJ__/span__JJ_GT_JJ__ + paraItem.defaultValue;
}
}
result += __JJ_LT_JJ__span class="hljs-string"__JJ_GT_JJ__')'__JJ_LT_JJ__/span__JJ_GT_JJ__;
}
result += __JJ_LT_JJ__span class="hljs-string"__JJ_GT_JJ__' { ... }'__JJ_LT_JJ__/span__JJ_GT_JJ__;
__JJ_LT_JJ__span class="hljs-keyword"__JJ_GT_JJ__return__JJ_LT_JJ__/span__JJ_GT_JJ__ result;
};SassSDocMeister
最後推薦一款官方的工具—— SassSDocMeister,這個工具可以線上預覽 SassDoc 註解的效果,對於剛接觸 SassDoc 的使用者來說會比較方便。
完整的 Demo 請參考 QMUI Web 和 QMUI Web Demo,如果你覺得這篇文章對你有幫助,歡迎 Star。