日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
給大家變個Node.js的小魔術(shù)

本文轉(zhuǎn)載自微信公眾號「神光的編程秘籍」,作者神說要有光。轉(zhuǎn)載本文請聯(lián)系神光的編程秘籍公眾號。

網(wǎng)站建設哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設計、網(wǎng)站建設、微信開發(fā)、小程序定制開發(fā)、集團企業(yè)網(wǎng)站建設等服務項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了蓮池免費建站歡迎大家使用!

魔術(shù)演出

我們準備一個 Node.js 的模塊 input.js:

 
 
 
 
  1. // input.js 
  2. function func() { 
  3.     return '卡頌' 
  4. module.exports = func(); 

這個模塊返回的值是啥?

東東:是“卡頌”。

那我在另一個模塊 test.js 中引入這個 input.js,然后打印一下:

 
 
 
 
  1. // test.js 
  2. const data = require('./input.js'); 
  3. console.log(data); 

之后我在 entry.js 里面引入 test.js:

 
 
 
 
  1. require('./test.js'); 

執(zhí)行之后打印的是啥?

東東:是“卡頌”。

真的么?那我們跑一下:

打印的是啥:

東東:是 “卡帥”,哇,好神奇,怎么做到的。

我:想不想學?

東東:想。

我:那接下來就進入魔術(shù)揭秘時間。

魔術(shù)揭秘

Node.js 加載模塊的流程是這樣的:

模塊加載會調(diào)用 load 方法, load 會調(diào)用對應后綴名的 _extensions 的方法來處理,其中會調(diào)用 _compile 來編譯并把結(jié)果放入 cache,之后返回。

所以呢?我們想改變 js 模塊的返回值,只需要改造下 Module._extensions['.js'] 就可以了。

 
 
 
 
  1. const Module = require('module'); 
  2. const fs = require('fs'); 
  3.  
  4. Module._extensions['.js'] = function (module, filename) { 
  5.     let content = fs.readFileSync(filename, 'utf8'); 
  6.     if (filename.includes('input')) { 
  7.         content = content.replace('卡頌', '卡帥'); 
  8.     } 
  9.     module._compile(content, filename); 
  10. }; 

我們對 filename 為 input 的文件,讀取內(nèi)容之后進行了替換,之后再調(diào)用 module._compile 來編譯,后續(xù)流程不變。

模塊引入方式不變,但是模塊內(nèi)容已經(jīng)悄悄的被修改了,這個魔術(shù)的名字叫做 require hook。

東東:原來是你藏了一段代碼沒展示。

我:魔術(shù)都是這樣的啊。而且你別小看了這個 require hook,它能做到很多強大的功能呢。

東東:哦?比如說

我:比如說 ts-node,它是怎么做到直接 require ts 模塊的?就是通過 require hook 偷偷做了編譯,其實你執(zhí)行的是編譯后的 js。

比如說 babel-register 它是怎么做到直接執(zhí)行帶有 esnext 新特性的代碼的?也是通過 require hook 偷偷做了編譯。

還有覆蓋率測試,其實是通過函數(shù)插樁做到的,也就是你每執(zhí)行一條語句都會計數(shù)。怎么插樁呢?跑單測的時候也沒手動插樁啊,就是因為工具內(nèi)部偷偷通過 require hook 做了插樁,才能得到覆蓋率數(shù)據(jù)。

東東:這個魔術(shù)還挺有用的嘛。學會了~

總結(jié)

Node.js 的 js 模塊加載的流程是 load -> _extensions['.js'] -> _compile,可以通過修改 _extensions['.js'] 來達到 hook 的目的,比如在 _compile 之前做一些代碼轉(zhuǎn)換。

這種 hook 在 babel-register、ts-node 還有單測的覆蓋率測試中都有應用,能夠達到透明的修改代碼的目的。

因為開發(fā)者不知道代碼什么時候被修改的,所以看起來比較神奇。


當前名稱:給大家變個Node.js的小魔術(shù)
本文鏈接:http://m.5511xx.com/article/cdigdei.html