国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - 編程技術 - 聊聊Eslint 的 Disble、Enable 的注釋配置是怎么實現(xiàn)的

聊聊Eslint 的 Disble、Enable 的注釋配置是怎么實現(xiàn)的

2021-09-22 23:22神光的編程秘籍神說要有光 編程技術

注釋中的配置在 eslint、webpack、terser 等工具中都有應用,分別叫 inline config、magic comment、annotation,但都指的同一個東西。

聊聊Eslint 的 Disble、Enable 的注釋配置是怎么實現(xiàn)的

不知道大家有沒有用過 eslint 的注釋的配置方式:

  1. /*eslint-disableno-alert,no-console*/
  2. alert('foo');
  3. console.log('bar');
  4. /*eslint-enableno-alert,no-console*/
  5.  
  6. //eslint-disable-next-line
  7. alert('foo');

eslint 支持 eslint-disable、eslint-enable、eslint-disable-next-line 等指定某個 rule 是否生效的行內配置,叫做 inline config。

webpack 中也有這種配置方式,可以在動態(tài)引入一個模塊的時候配置代碼分割的方式,叫做 magic comment。

  1. import(
  2. /*webpackChunkName:"my-chunk-name"*/
  3. /*webpackMode:"lazy"*/
  4. /*webpackExports:["default","named"]*/
  5. 'module'
  6. );

類似的,terser 也有這種機制,叫做 annotation,可以指定某個 api 是否是純的,純函數(shù)的話如果沒用到可以直接刪除。

  1. vara=/*#__PURE__*/React.createElement("div",null);

可以看到,很多庫都用到了這種通過注釋來配置的方式,不管是叫 annotation 也好、magic comment 也好,或者 inline config 也好,都指的同一個東西。

既然是這么常見的配置方式,那么他們是怎么實現(xiàn)的呢?

注釋中配置的實現(xiàn)原理

我們拿 eslint 的 inline config 的實現(xiàn)來看一下。

eslint 會把源碼 parse 成 AST,然后對把 AST 傳入一系列 rule 來做檢查,檢查結果會用 formatter 格式化后輸出。

注釋的配置是在哪一步生效的呢?

我簡化了一下源碼,是這樣的:

  1. verify(text){
  2. //parse源碼
  3. constast=parse(text);
  4. //調用rule,拿到lint的問題
  5. constlintingProblems=runRules(ast);
  6. //通過AST拿到注釋中的配置
  7. constcommentDirectives=getDirectiveComments(ast);
  8. //根據(jù)注釋中的配置過濾問題
  9. returnapplyDisableDirectives(lintingProblems,commentDirectives);
  10. }

可以看到,整體流程是:

  • 把源碼 parse 成 AST
  • 調用 rule 對 AST 做檢查,拿到 lint 的 problems
  • 通過 AST 拿到注釋中的 diectives
  • 通過 directives 過濾 problems,就是最終需要報出的問題

也就是說 eslint 的 inline config 是在 lint 完 AST,拿到各種 problems 之后生效的,對 problems 做一次過濾。

那怎么從 AST 中取出 directives 的呢?又是怎么過濾 problems 的呢?

我們分別看一下。

從 AST 取出 directives 的源碼簡化以后是這樣的:

  1. functiongetDirectiveComments(ast){
  2. constdirectives=[];
  3. ast.comments.forEach(comment=>{
  4. constmatch=/^[#@](eslint(?:-env|-enable|-disable(?:(?:-next)?-line)?)?|exported|globals?)(?:\s|$)/u.exec(comment.trim());
  5. if(match){
  6. constdirectiveText=match[1];
  7. ...
  8. directives.push({type:xxx,line:loc.start.line,column:loc.start.column+1,ruleId});
  9. }
  10. }
  11. returndirectives;
  12. }

其實就是對 AST 中所有的 comments 的內容做一下正則的匹配,如果是支持的 directive,就把它收集起來,并且記錄下對應的行列號。

之后就是對 problems 的過濾了。

簡化后的源碼是這樣的:

  1. functionapplyDisableDirectives(problems,disableDirectives){
  2. constfilteredProblems=[];
  3.  
  4. constdisabledRuleMap=newMap();
  5.  
  6. letnextIndex=0;
  7. for(constproblemofproblems){
  8. //對每一個probelm,都要找到當前被禁用的rule
  9. while(
  10. nextIndex
  11. compareLocations(disableDirectives[nextIndex],problem)<=0
  12. ){
  13. constdirective=disableDirectives[nextIndex++];
  14.  
  15. switch(directive.type){
  16. case"disable":
  17. disabledRuleMap.set(directive.ruleId,directive);
  18. break;
  19. case"enable":
  20. disabledRuleMap.delete(directive.ruleId);
  21. break;
  22. }
  23. }
  24. //如果problem對應的rule沒有被禁用,則返回
  25. if(!disabledRuleMap.has(problem.ruleId)){
  26. filteredProblems.push(problem);
  27. }
  28. }
  29. returnfilteredProblems;
  30. }
  31.  
  32. functioncompareLocations(itemA,itemB){
  33. returnitemA.line-itemB.line||itemA.column-itemB.column;
  34. }

我們理下思路:

我們要過濾掉 problems 中被 disabled 的 rule 報出的 problem,返回過濾后的 problems。

可以維護一個 disabledRuleMap,表示禁用的 rule。

對每一個 problem,都根據(jù)行列號來從 disableDirectives 中取出 directive 的信息,把對應的 rule 放入 disabledRuleMap。

然后看下該 problem 的 rule 是否是被禁用了,也就是是否在 disabledRuleMap 中,如果是,就過濾掉。

這樣處理完一遍,返回的 problem 就是可以報出的了。

這就是 eslint 的 eslint-disable、eslint-enable、eslint-disable-next-line 等注釋可以配置 rule 是否生效的原理。

eslint 是根據(jù)行列號找到對應的 comment 的,其實很多 AST 中會記錄每個節(jié)點關聯(lián)的 comment。

比如 babel 的 AST:

聊聊Eslint 的 Disble、Enable 的注釋配置是怎么實現(xiàn)的

這樣可以根據(jù) AST 來取出注釋,之后通過正則來判斷是否是 directive。

通過行列號來查找 comment,通過 AST 找到關聯(lián)的 comment,這是兩種查找注釋的方式。

總結

注釋中的配置在 eslint、webpack、terser 等工具中都有應用,分別叫 inline config、magic comment、annotation,但都指的同一個東西。

它們都是找到 AST 中的 comments,通過正則匹配下是否是支持的 directive(指令),然后取出對應的信息。

找到 directive 之后,還要找到 directive 生效的地方,可以用兩種方式來查找:一種是根據(jù)行列號的比較,一種是根據(jù)關聯(lián)的 AST 來查找。

找到 directive 和對應生效的地方之后,就可以根據(jù) directive 中的信息做各種處理了。

注釋中的配置是一種比較常見的配置方式,適合一些局部的配置。理解了它們的實現(xiàn)原理,能夠讓我們更好的掌握這種機制。

原文鏈接:https://mp.weixin.qq.com/s/_XWzQ6FmxiGANPBUT7YNYQ

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 中文字幕精品一区久久久久 | 色伊人 | 蜜桃一区 | 黄色在线观看视频网站 | 成人在线观看免费 | 久久精品欧美 | 中文二区 | 一区二区免费在线视频 | 久久奸 | 涩涩涩久久久成人精品 | 国产精品久久久久久久一区探花 | 偷拍自拍亚洲欧美 | 国产99一区二区 | 精品一区av | www亚洲精品 | 欧美午夜一区二区福利视频 | 一级黄色大片在线 | 国产一区二区三区四区二区 | 日韩在线 | 午夜视频导航 | 成人精品视频一区二区三区 | 亚洲视频欧美视频 | 亚洲精品一二区 | 中文字幕日韩一区 | 国产精品一二三区视频出来一 | 久久久久久久久久久九 | 91成人黄色 | 婷婷在线免费视频 | 国产一区免费 | www.久久视频 | 国产毛片18片毛一级特黄日韩a | 国产三级毛片 | 国产伦精品一区二区三区四区视频 | 久久精品久久久久电影 | 欧美日韩亚洲二区 | 欧美精品999 | 久久国产精品无码网站 | 日韩福利一区二区 | 成人网av| 亚洲一一在线 | 99精品欧美一区二区三区 |