日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

解析如何自動(dòng)化生成vue組件文檔

瀏覽:71日期:2022-09-28 14:32:36
目錄一、現(xiàn)狀二、社區(qū)解決方案2.1、業(yè)務(wù)梳理三、技術(shù)方案3.1、Vue文件解析3.2、信息提取3.2.1、可直接獲取的信息3.2.2、需要約定的信息四、總結(jié)五、展望一、現(xiàn)狀

Vue框架在前端開發(fā)中應(yīng)用廣泛,當(dāng)一個(gè)多人開發(fā)的Vue項(xiàng)目經(jīng)過長期維護(hù)之后往往會(huì)沉淀出很多的公共組件,這個(gè)時(shí)候經(jīng)常會(huì)出現(xiàn)一個(gè)人 開發(fā)了一個(gè)組件而其他維護(hù)者或新接手的人卻不知道這個(gè)組件是做什么的、該怎么用,還必須得再去翻看源碼,或者壓根就沒注意到這個(gè)組件 的存在導(dǎo)致重復(fù)開發(fā)。這個(gè)時(shí)候就非常需要維護(hù)對(duì)應(yīng)的組件文檔來保障不同開發(fā)者之間良好的協(xié)作關(guān)系了。

但是傳統(tǒng)的手動(dòng)維護(hù)文檔又會(huì)帶來新問題:

效率低,寫文檔是個(gè)費(fèi)時(shí)費(fèi)力的體力活,好不容易抽時(shí)間把組件開發(fā)完了回頭還要寫文檔,想想都頭大。 易出錯(cuò),文檔內(nèi)容容易出現(xiàn)差錯(cuò),可能與實(shí)際組件內(nèi)容不一致。 不智能,組件更新迭代的同時(shí),需要手動(dòng)將變更同步到文檔中,消耗時(shí)間還容易遺漏。

而理想中的文檔維護(hù)方式則是:

工作量小,能夠結(jié)合Vue組件自動(dòng)獲取相關(guān)信息,減少從頭開始寫文檔的工作量。 信息準(zhǔn)確,組件的關(guān)鍵信息與組件內(nèi)容一致,不出錯(cuò)。 智能同步,Vue組件迭代升級(jí)時(shí),文檔內(nèi)容可以自動(dòng)的同步更新,無需人工校驗(yàn)信息是否一致。二、社區(qū)解決方案2.1、業(yè)務(wù)梳理

為了能實(shí)現(xiàn)上述理想效果,我搜索并研究了一下社區(qū)中的解決方案,目前Vue官方提供了Vue-press可以用于快速搭建Vue項(xiàng)目文檔, 而且也已經(jīng)有了可以自動(dòng)從Vue組件中提取信息的庫了。

但是已有的第三方庫并不能完全滿足需求,主要存在以下兩個(gè)問題:

信息不全面,一些重要內(nèi)容無法獲取例如不能處理v-model,不能解析屬性的修飾符sync,不能獲取methods中函數(shù)入?yún)⒌脑敿?xì)信息等。 比如下面的例子,value屬性與input事件可以合起來構(gòu)成一個(gè)v-model屬性,但是這個(gè)信息在生成的文檔中沒有體現(xiàn)出來,要文檔讀者自行理解判斷。而且生成的文檔中沒有展示是否支持sync。

解析如何自動(dòng)化生成vue組件文檔

有較多的自定義標(biāo)識(shí),而且標(biāo)識(shí)的命名過于個(gè)性化,對(duì)原有的代碼侵入還是比較大的。例如下圖中的代碼,為了標(biāo)記注釋,需要在原有的 業(yè)務(wù)代碼中額外添加'@vuese' '@arg'等標(biāo)識(shí),使得業(yè)務(wù)代碼多出了一些業(yè)務(wù)無關(guān)內(nèi)容。

解析如何自動(dòng)化生成vue組件文檔

三、技術(shù)方案

針對(duì)以上文中提到的問題以及社區(qū)方案的不足,我們團(tuán)隊(duì)內(nèi)沉淀出了一個(gè)小工具專門用于Vue組件信息獲取并輸出組件文檔,大致效果如下:

解析如何自動(dòng)化生成vue組件文檔

上圖中左邊是一個(gè)常見的Vue單文件組件,右邊是生成的文檔。我們可以看到我們從組件中成功的提取到了以下一些信息:

組件的名稱。 組件的說明。 props,slot,event,methods等。 組件的注釋內(nèi)容。

接下來我們將詳細(xì)的講解如何從組件中提取這些信息。

3.1、Vue文件解析

既然是要從Vue組件中提取信息,那么首先的問題就是如何解析Vue組件。Vue官方開發(fā)了Vue-template-compiler庫專門用于Vue解析, 這里我們也可以用同樣的方式來處理。通過查閱文檔可知Vue-template-compiler提供了一個(gè)parseComponent方法可以對(duì)原始的Vue文件進(jìn)行處理。

import { parseComponent } from ’Vue-template-compiler’const result = parseComponent(VueFileContent, [options])

處理后的結(jié)果如下,其中template和script分別對(duì)應(yīng)Vue文件中的template和script的文本內(nèi)容。

export interface SFCDescriptor { template: SFCBlock | undefined; script: SFCBlock | undefined; styles: SFCBlock[]; customBlocks: SFCBlock[];}

當(dāng)然僅僅是得到文本是不夠的,還需要對(duì)文本進(jìn)行更進(jìn)一步的處理來獲取更多的信息。得到script后,我們可以用babel把js編譯成js的AST(抽象語法樹),這個(gè)AST是一個(gè)普通的js對(duì)象,可以通過js進(jìn)行遍歷和讀取 有了Ast之后我們就可以從中獲取到我們想到詳細(xì)的組件信息了。

import { parse } from ’@babel/parser’;const jsAst = parse(script, [options]);

接著我們來看template,繼續(xù)查找Vue-template-compiler的文檔我們找到compile方法,compile是專門用于將template編譯成AST的, 正好可以滿足需求。

import { compile } from ’Vue-template-compiler’const templateAst = compile(template, [options]);

得到結(jié)果中的ast則為template的編譯結(jié)果。

export interface CompiledResult { ast: ASTElement, render: string, staticRenderFns: Array<string>, errors: Array<string>}

通過第一步的文件解析工作,我們成功獲取到了Vue的模板ast和script中的js的AST,下一步我們就可以從中獲取我們想要的信息了。

3.2、信息提取

根據(jù)是否需要約定,信息可以分為兩種:

一種是可以直接從Vue組件中獲取,例如props、events等。 另一種是需要額外約定格式的,例如:組件的說明注釋,props的屬性說明等,這部分可以放到注釋里,通過對(duì)注釋進(jìn)行解析獲取。

為了方便的從ast中讀取信息,這里先簡單介紹一個(gè)工具@babel/traverse,這個(gè)庫是babel官方提供的專門用于遍歷js AST的。使用方式如下;

import traverse from ’@babel/traverse’traverse(jsAst, options);

通過在options中配置對(duì)應(yīng)內(nèi)容的回調(diào)函數(shù),可以獲得想要的ast節(jié)點(diǎn)。具體的使用可以參考官方文檔

3.2.1、可直接獲取的信息

可以從代碼中直接獲取的信息可以有效的解決信息同步問題,無論代碼怎么變動(dòng),文檔的關(guān)鍵信息都可以自動(dòng)同步,省去了人工校對(duì)的麻煩。

可以直接獲取的信息有:

組件屬性props 提供外部調(diào)用的方法methods 事件events 插槽slots

1、2都可以利用traverse在js AST上直接遍歷名稱為props和methods的對(duì)象節(jié)點(diǎn)獲取。

事件的獲取稍微麻煩一點(diǎn),可以通過查找$emit函數(shù)來定位到事件的位置,而$emit函數(shù)可以在traverse中監(jiān)聽MemberExpress(復(fù)雜類型節(jié)點(diǎn)), 然后通過節(jié)點(diǎn)上的屬性名是否是’$emit’判斷是否是事件。如果是事件,那么在$emit父級(jí)中讀取arguments字段, arguments的第一個(gè)元素就是事件名稱,后面的元素為事件傳參。

this.$emit(’event’, arg);

traverse(jsAst, { MemberExpression(Node) { // 判斷是不是event if (Node.node.property.name === ’$emit’) { // 第一個(gè)元素是事件名稱 const eventName = Node.parent.arguments[0]; } }});

在成功獲取到Events后,那么結(jié)合Events和props,就可以進(jìn)一步的判斷出props中的兩個(gè)特殊屬性:

是否存在v-model:查找props中是否存在value屬性并且Events中是否存在input事件來確定。 props的某個(gè)屬性是否支持sync:判斷Events的時(shí)間名中是否存在有update開頭的事件,并且事件名稱與屬性名相同。

插槽slots的信息保存在上文的template的AST中,遞歸遍歷template AST找到名為slots的節(jié)點(diǎn),進(jìn)而還可以在節(jié)點(diǎn)上查找到name。

3.2.2、需要約定的信息

為什么除了可直接獲取的組件信息之外,還會(huì)需要額外的約定一部分內(nèi)容呢?其一是因?yàn)榭芍苯荧@取的信息內(nèi)容比較單薄,還不足以支撐起一個(gè)相對(duì)完善的組件文檔;其二是我們?nèi)粘i_發(fā)組件時(shí)本身就會(huì)寫很多的注釋,如果能直接將部分注釋提取出來放到文檔中,可以大大降低文檔維護(hù)的工作量;

整理一下可以約定的內(nèi)容有以下幾條:

組件名稱。 組件的整體介紹。 props、Events、methods、slots文字說明。 Methods標(biāo)記和入?yún)⒌脑敿?xì)說明。這些內(nèi)容都可以放在注釋中進(jìn)行維護(hù),之所以放在注釋中進(jìn)行維護(hù)是因?yàn)樽⑨尶梢院苋菀讖纳衔奶岬降膉s AST以及template AST中獲取到, 在我們解析Vue組件信息的同時(shí)就可以把這部分針對(duì)性的說明一起解析到。

接下來我們著重講解如何將提取注釋和注釋與被注釋的內(nèi)容是如何對(duì)應(yīng)起來的。

js中的注釋根據(jù)位置不同可以分為頭部注釋(leadingComments)和尾部注釋(trailingComments),不同位置的注釋會(huì)存放在對(duì)應(yīng)的字段中, 代碼展示如下:

// 頭部注釋export default {} // 尾部注釋

解析結(jié)果

const exportNode = { type: 'ExportDefaultDeclaration', leadingComments: [{ type: ’CommentLine’, value: ’頭部注釋’ }], trailingComments: [{ type: ’CommentLine’, value: ’尾部注釋’ }]}

在同一個(gè)位置上,根據(jù)注釋格式的不同又分為單行注釋(CommentLine)和塊級(jí)注釋(CommentBlock),兩種注釋的區(qū)別會(huì)反應(yīng)在注釋節(jié)點(diǎn)的type字段中:

/** * 塊級(jí)注釋 */ // 單行注釋 export default {}

解析結(jié)果

const exportNode = { type: 'ExportDefaultDeclaration', leadingComments: [ { type: ’CommentBlock’, value: ’塊級(jí)注釋’ }, { type: ’CommentLine’, value: ’單行注釋’ } ]}

另外,從上面的解析結(jié)果我們也可以看到,注釋節(jié)點(diǎn)是掛載在被注釋的export節(jié)點(diǎn)里面的,這也解決我們上面提到的另一個(gè)問題:注釋與被注釋的關(guān)聯(lián)關(guān)系怎么獲取的--其實(shí)babel在編譯代碼的時(shí)候已經(jīng)替我們做好了。

template查找注釋與被注釋內(nèi)容的方法不同。template中注釋節(jié)點(diǎn)與其他節(jié)點(diǎn)一樣是作為dom節(jié)點(diǎn)存在的, 在遍歷節(jié)點(diǎn)的時(shí)候通過判斷isComment字段的值是否為true來確定是否是注釋節(jié)點(diǎn)。而被注釋的內(nèi)容的位置在兄弟節(jié)點(diǎn)的后一位:

<!--template的注釋--> <slot>被注釋的節(jié)點(diǎn)</slot>

解析結(jié)果

const templateAst = [ { isComment: true, text: 'template的注釋', type: 3 }, { tag: 'slot', type: 1 }]

知道了如何處理注釋內(nèi)容,那么我們還可以利用注釋做更多的事情。例如可以通過在methods的方法的注釋中約定一個(gè)標(biāo)記@public來區(qū)分是私有方法還是公共方法,如果更細(xì)節(jié)一點(diǎn)的話, 還可以參考另一個(gè)專門用于解析js注釋的庫js-doc的格式,對(duì)方法的入?yún)⑦M(jìn)行更進(jìn)一步的說明,豐富文檔的內(nèi)容。

我們只需要在獲取到注釋內(nèi)容之后對(duì)文本進(jìn)行切割讀取即可,例如:

export default { methods: { /** * @public * @param {boolean} value 入?yún)⒄f明 */ show(value) {} }}

當(dāng)然了為了避免對(duì)代碼侵入過多,我們還是需要盡量少的添加額外的標(biāo)識(shí)。而入?yún)⒄f明采用了與js-doc相同的格式,主要還是因?yàn)檫@套方案 使用比較普遍,而且代碼編輯器都自動(dòng)支持方便編輯。

四、總結(jié)

編寫組件文檔是一個(gè)可以很好的提升項(xiàng)目內(nèi)各個(gè)前端開發(fā)成員之間協(xié)作的事情,一份維護(hù)良好的文檔會(huì)極大的改善開發(fā)體驗(yàn)。而如果能進(jìn)一步的使用工具把維護(hù)文檔的過程自動(dòng)化的話,那開發(fā)的幸福感還能得到再次提升。

經(jīng)過一系列的摸索和嘗試,我們成功的找到了 自動(dòng)化提取Vue組件信息的方案,大大減輕了維護(hù)Vue組件文檔的工作量,提升了文檔信息的準(zhǔn)確度。具體實(shí)現(xiàn)上,先用vue-template-compiler對(duì)Vue文件進(jìn)行處理,獲得template的AST和js的AST,有了這兩個(gè)AST后就可以去獲取更加詳細(xì)的信息了, 梳理一下到目前為止我們生成的文檔里可以獲取到的內(nèi)容及獲取方式:

解析如何自動(dòng)化生成vue組件文檔

至于獲取到內(nèi)容之后是以Markdown的形式輸出還是json文件的形式輸出,就取決于實(shí)際的開發(fā)情況了。

五、展望

這里我們所討論的是直接從單個(gè)Vue文件去獲取信息并輸出,但是像很多第三方組件庫里例如elementUI的文檔,不僅有組件信息還有展示實(shí)例。如果一個(gè)組件庫維護(hù)的相對(duì)完善的話,一個(gè)組件應(yīng)該會(huì)有對(duì)應(yīng)的測試用例,那么是否可以將組件的測試用例也提取出來, 實(shí)現(xiàn)組件文件中示例部分的自動(dòng)提取呢?這也是值得研究的問題。

以上就是解析如何自動(dòng)化生成vue組件文檔的詳細(xì)內(nèi)容,更多關(guān)于自動(dòng)化生成vue組件文檔的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Vue
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
午夜在线一区| 亚洲午夜视频| 婷婷久久免费视频| 亚洲开心激情| 日韩高清一区在线| 国产精品一区二区av日韩在线| 久久国产毛片| 日韩一区二区三区免费播放| 国产精品视频一区视频二区| 国产精品s色| 久久亚洲国产精品尤物| 国产精品99一区二区三区| 三上悠亚国产精品一区二区三区 | 麻豆视频一区二区| 国内不卡的一区二区三区中文字幕 | 另类小说一区二区三区| 国产精品一区二区99| 美女国产精品久久久| 国产夫妻在线| 天堂资源在线亚洲| 国产麻豆综合| 日韩国产一二三区| 另类欧美日韩国产在线| 久久久久99| 在线精品亚洲| 美女视频免费精品| 999久久久精品国产| 蜜臀av性久久久久蜜臀aⅴ流畅 | 国产一区二区三区精品在线观看| 日韩在线第七页| 黄色日韩精品| 色综合视频一区二区三区日韩 | 国产美女久久| 日本少妇一区| 免费美女久久99| 国产精品亚洲二区| 色天使综合视频| 综合一区av| 国产专区精品| 亚洲欧美视频| 美女视频黄 久久| 亚洲国产专区校园欧美| 色8久久久久| av高清不卡| 亚洲欧洲国产精品一区| 精品亚洲成人| 老司机精品久久| 精品香蕉视频| 免费日本视频一区| 日韩综合在线| 日韩在线a电影| 久久影视三级福利片| 午夜欧美理论片| 国产极品模特精品一二| 蜜桃成人av| 国产精品一国产精品k频道56| 国产91精品对白在线播放| 欧美色综合网| 最新日韩欧美| 91亚洲国产高清| 日本aⅴ亚洲精品中文乱码| 亚洲天堂1区| 国产精品mm| 蜜桃视频在线观看一区| 国产不卡人人| 日本不卡不码高清免费观看| 日韩高清中文字幕一区二区| 久久黄色影视| 性色一区二区| 日韩欧美国产精品综合嫩v| 日韩区欧美区| 国产精品99免费看| 麻豆国产精品777777在线| 免费在线观看精品| 91精品综合| 国产在线视频欧美一区| 日韩毛片网站| 亚洲综合电影一区二区三区| 福利片在线一区二区| 日本aⅴ亚洲精品中文乱码| 亚洲国产专区| 国产一区二区三区不卡av| 日韩激情啪啪| 久久成人亚洲| 五月天久久久| 日韩影院二区| 国产一区二区三区黄网站| 青青草国产成人99久久| 夜夜嗨网站十八久久| 欧美日韩免费观看视频| 久久精品国产久精国产爱| 日韩欧美久久| 日韩在线播放一区二区| 欧美国产91| 久久久一本精品| 精品一二三区| 国产欧美高清视频在线| 亚洲精品女人| 亚洲欧美激情诱惑| 欧美特黄视频| 欧美1区2区3区| 在线亚洲人成| 四虎国产精品免费观看| 久久精品国产成人一区二区三区| 欧美色综合网| 日本精品一区二区三区在线观看视频| 久久亚洲精品伦理| 国产一区白浆| 欧美日韩国产综合网| 亚洲欧美伊人| 久久国产中文字幕| 欧美香蕉视频| 天堂8中文在线最新版在线| 国产成人精品一区二区三区视频| 蜜桃久久久久| 国产一区二区三区探花| 久草精品视频| 久久尤物视频| 高清在线一区| 日韩国产欧美| 人人精品亚洲| 欧美日韩在线播放视频| 亚洲黑丝一区二区| 好看的av在线不卡观看| 狠狠干成人综合网| 欧美另类专区| 99国内精品| 老鸭窝毛片一区二区三区| 国产模特精品视频久久久久| 西西人体一区二区| 亚洲精品伊人| 欧美亚洲综合视频| 免费在线成人| 日韩欧美精品综合| 国产精品88久久久久久| 一区二区视频欧美| 日韩一区欧美二区| 日本不卡一二三区黄网| 国产精品一区二区中文字幕| 久久精品一区| 啪啪国产精品| 午夜精品一区二区三区国产| 日韩一级精品| 日韩手机在线| 欧美激情视频一区二区三区免费 | 另类小说一区二区三区| 极品av在线| 日韩精品一区二区三区免费观影 | 日韩极品在线观看| 麻豆精品一区二区综合av| 国产96在线亚洲| 亚洲午夜av| 日本不卡视频在线| 精品国产aⅴ| 国产99精品一区| 免费欧美在线视频| 欧美精品97| 激情久久中文字幕| 日韩av中文字幕一区| 久久久久久夜| 久久亚洲一区| 美女国产精品久久久| 久久国产影院| 天堂va在线高清一区| 成人午夜在线| 老鸭窝亚洲一区二区三区| 国产日韩一区| 久久久久久久久久久妇女| 亚洲精品人人| 国产精品13p| 亚洲欧美日韩专区| 久久精品午夜| 免费久久99精品国产自在现线| 国产精品一区二区美女视频免费看| 婷婷综合六月| 日韩精品三级| 另类中文字幕国产精品| 亚洲精品乱码久久久久久蜜桃麻豆| 国产一区调教| 亚洲最大av| 色老板在线视频一区二区| 日本va欧美va精品发布| 久久久久久久久久久妇女| 欧美伊人久久| 欧美日韩国产高清电影| 91成人在线| 欧美精品一区二区三区精品| 国产精品网址| 亚洲欧美日韩国产综合精品二区| 久久不见久久见免费视频7| 激情综合自拍| 久久影院资源站| 亚洲深夜福利在线观看| 欧产日产国产精品视频| 欧美一区久久| 亚洲尤物在线| 日本美女一区| 国产精品黄色| 在线精品观看| 婷婷成人综合|