前言
相信很多開發者都有過需要撰寫文件的需求
而使用 JSDoc , Swagger , YUIDoc….等自動化生產API文件的場景肯定屢見不顯
今天則是想簡單紀錄一下,在2021台北工業自動化展覽後,由於公司需求,需要產出API Document。
使用的正式JSDoc ,但長年被JavaScript養壞的語法, 以及雜亂的結構導致文件撰寫困難的血淚史…
簡介Intro
當然想記錄一些2266的東西前,自然是不免俗需要介紹一下JSDoc。
不過如果已經熟識的人可以直接跳過這段碎念了,哈哈。
簡單的說就是在撰寫註解的同時,也是一個標記。
可以透過JSDoc或是其他API文件自動化生產工具產生API文件
不用再自己一步一步用Word慢慢寫(雖然有的公司還是如此…)
主要文本
客戶的需求
在得到公司要求API Document的當下,自然是很得意的認為,JS這麼隨意的語言。
文件肯定也能輕輕鬆鬆產出啦 (然後事實證明文件撰寫難度遠大於強型態語言QAQ)
但還好公司的專案,後端大多由我一手包辦,因此不論是重構或是參考,相較於繼承別人的遺產更方便
系統架構簡介
這個專案主要是作為雲平台IoT監控,而這樣的服務主要有四種設計模式
- FAAS
 - IAAS
 - PAAS
 - SAAS
 - On Premises
 
各種設計模式都有各自的優勢,單就這次的專案來說,我採用的是FAAS/SAAS混合架構(當然主要還是以FAAS為主,以微服務設計為核心思想)
服務之間的通訊協定應用層主要有MQTT/HTTP/WebSocket這三種方案通訊,當然也因為微服務設計,需要使用大量的RestFulAPI
這也導致API文件量大大增加 (所以獨立開發資源少的情況下,還是選擇IAAS或On Premises設計模式比較不會找自己麻煩)
每一個微服務跟每一個函式都需要文件
血淚踩坑紀錄
原因
在前面之所以認為能夠簡簡單單的自動產生文件,正是因為很多時候
舉個例子
我們打個比方:
1  | //這樣寫可能很糟糕,但為了長話短說,於是簡單舉個例子,有機會再修正。或是有好的提議也歡迎一起討論)  | 
需求
這一個簡單建立webServer的例子可以看到,引用了很多模組,然後為了microservice的設計理念,將很多動作都進行包裝跟代理處理。
因此簡單算一算,為每個方法及routes寫文件,就需要兩三百個註解 (真的是累死)
甚至為了滿足客戶及公司需求,需要對某些特別的service,在解析某些請求時會需要熱插拔函式(function)或是物件(object)或是成員(member)或是方法(method)
無論如何,就是會有動態增加屬性的需求。
比如原本解析mqtt訊息的協議只有A,然後A只做一件事情,就是把這個訊息透過LINE推播到手機
然後老闆或客人心血來潮,突然想要做B,而B是會分析訊息,根據需求做某些操作
這時候就能透過上傳文件或是傳遞字串到後端,後端把這些訊息寫入到地端(local),然後再使用require把這個檔案熱騰騰的引入使用
問題點
於時API document就變得很難撰寫,JSDoc不會幫你執行程式,所以像這樣的做法似乎是無效的
1  | /*  | 
這樣的做法,確實可以動態引用某些檔案(但其實很不建議,很可能被駭客利用,有很大的安全性問題)
不過也可以透過讓其擁有獨立的虛擬環境,隔離資源,稍微增加一點點安全性。
(當然還有更多做法,不過主題是JSDoc就不再多談)
其次是這樣的Document超級難寫啊!!!!!!

到底要怎麼抓那該死的undefined?? 到底怎麼處理可惡的T
查閱了無數文章,也上社群詢問。都沒有人擁有更好的解決辦法
解決方案
找答案的過程
嘗試了無數方案,看了不少TS官方文件,也翻閱了JSDoc官方文檔。
始終找不太到相關的解決辦法
但最後重新思路過一次,還是使用了JSDoc本身的魔法解決問題。
讓文檔能夠呈現想表達的意境

答案揭曉
那麼究竟是用什麼方式,讓這個文件從抓不到的 Undefined,到能夠呈現泛型引入方法的呢?
其實還是使用了namespace包裝,再使用name強制讓JSDoc紀錄我們想要讓它呈現的結果
大概長成這副德性

心得
其實JSDoc的作者也說過,JSDoc並非實際讓你的程式跑過一次。(原話雖然不是這樣但意思相似)
所以JSDoc在獲取及產生檔案的當下,是處於靜態的。
因此若想要使用JSDoc描述一個動態的過程,需要手刻,強制宣告。
讓JSDoc乖乖聽話產生想要的文件內容
接觸JSDoc及Clean Code的時間不長,若文章有誤十分歡迎討論糾正
如果能幫到有同樣的問題的人,我也非常開心:D
祝各位開發者開發順心