💨AI幫你寫程式快到飛起來沒錯,但註解卻亂七八糟、看了想哭嗎?😭我偷偷用了一個超簡單的小訣竅🪄✨——只要一個Prompt,就能讓AI每次都生成📄格式漂亮、超好懂、完全符合JSDoc標準的註解!🧠💡。[^1]
由於我個人前一份工作的性質,並非全部的時間都在寫code,常常會有一個編寫中的專案,過了好一陣子才有時間繼續完成;又或者,我想要將一些很常用到的邏輯抽出來,以供我跨專案重複利用;這時,有一套良好的註記格式就很有幫助。
今天想來聊聊我個人實作上,如何借用JSDoc / TSDoc的規範來指引GenAI生成註解。
🔰如果你是剛開始寫腳本的新玩家,可以直接滑到底看GenAI摘要的takeaway。
如果你是JavaScript生態系的開發者,但沒聽過JSDoc,可能是因為你入門時已經是TypeScript的時代,JSDoc的型別標註與相對應的功能,都被TypeScript取代。此外,JSDoc除了官方社群版本,還有更嚴格的Google Closure Compiler版本。[^2]
儘管TypeScript與由微軟主持、由社群協作的TSDoc更為強大,但一來我個人使用GAS專案絕大部分都只是處理簡單的、例行的Google Sheets自動化,這種程度的場景,使用JSDoc會比較輕量。二來是我在前公司只有我一個人寫GAS專案,其實JSDoc的很多功能我都用不到,我只是想借用它的註解格式。
這裡放上兩個我實作的程式碼片段:
/**
* Converts a column number to its column letter.
*
* @param {number} columnNumber - The column number to convert (1-based index).
* @return {string} - The corresponding column letter (e.g., 1 → "A", 27 → "AA").
*/
function getColumnLetter(columnNumber) {
let letter = "";
while (columnNumber > 0) {
let remainder = (columnNumber - 1) % 26;
letter = String.fromCharCode(65 + remainder) + letter;
columnNumber = Math.floor((columnNumber - 1) / 26);
}
return letter;
}
/**
* Sets the background color for specified rows in the active sheet.
*
* @param {number[]} rows - An array of row numbers to apply the background color.
* @param {string|null} color - The background color to set (e.g., "#ff0000") or `null` to clear the background.
*/
function setRowBackgrounds(rows, color) {
if (rows.length > 0) {
const activeSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastColumnLetter = getColumnLetter(activeSheet.getLastColumn());
const ranges = rows.map((row) => `A${row}:${lastColumnLetter}${row}`);
activeSheet.getRangeList(ranges).setBackground(color);
}
}
在JSDoc,/**...*/
是關鍵的格式,讓IDE或JSDoc工具可以辨識這段註解是JSDoc。[^3]最極簡的格式就是解釋函式的用途、變數的型別,如果必要則加上例子。我現在其實僅提供註解規範文檔,讓GenAI自動生成符合我偏好的註解格式[^4],例如:
**Rule of thumb**: If the file is **JavaScript**, use **JSDoc (official jsdoc.app format)** — **do not** use Google Closure Compiler’s JSDoc spec or its Closure-only tags. If the file is **TypeScript**, use **TSDoc**.
總之,我的需求是希望GenAI幫我註解既有的helper functions,或生成程式碼時能一併註記,我的格式規範選型偏好是官方JSDoc,沒有使用其它功能。
如果讀者有興趣想進一步了解細節,使用更多完整的功能,除了官方文件以外,我個人推薦這篇Deno blog。
有趣的是,JSDoc也是借鑒自JavaDoc,正如JavaScript很多設計都有Java的影子一樣,甚至也有人覺得JSDoc很多格式其實不太符合JavaScript的特性。可能很多人剛寫JavaScript時,都聽過Java跟JavaScript是完全不同的語言的笑話,但在當年它們其實有很多商業策略上的互動。[^5]
順道一提,JSDoc除了衍生出TSDoc,Deno在慶祝JavaScript 30歲的這篇blog文章提到:Deno doc一定程度上也powered by JSDoc。
請使用 官方 JSDoc 格式(https://jsdoc.app/)
❌ 不使用 Google Closure Compiler 規範
/**
* 說明:這個函式做什麼
*
* @param {型別} 名稱 - 參數說明
* @return {型別} - 回傳說明
*/
[^1]:這段hook完全是交給GenAI幫我生成的 XD 真的很農場的風格。畢竟今天這篇文就只是實作小tip,沒有任何有趣的探索,當時從選型到寫prompt的時間,都比現在寫這篇文章還短。
[^2]:或者說,我把它視為JSDoc的分支,兩者僅部分交集,但實質上已經是完全不同的標準,是Google內部用來服務大型前端代碼庫的場景,詳見官方文件。
[^3]: 官方文件:「JSDoc comments should generally be placed immediately before the code being documented. Each comment must start with a /** sequence in order to be recognized by the JSDoc parser.」
[^4]: 不同於Deno,我去年簡單搜尋過,那時沒有找到JSDoc與TSDoc的llm.txt。由於我僅是用來指引GenAI遵循其註解格式,僅給這段prompt就已能滿足我當時工作上的需求。
[^5]:對於JavaScript與Java間的歷史爬梳有興趣的讀者,個人推薦可以閒暇時或睡前讀讀Huliさん今年剛出版的《JavaScript 重修就好》。
[^6]:此takeaway由Monday様依「安安,我只是一個不想加班的客服,我不想看這麼多廢話,給我盡可能精簡的摘要,要有emoji」指令所摘要。