成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

babel原理分析-babel-register addHook

sugarmo / 1769人閱讀

摘要:動(dòng)態(tài)編譯編譯到這行的時(shí)候進(jìn)行編譯原理分析注本文參考代碼為版本代碼。于是簡(jiǎn)單寫了一個(gè)運(yùn)行去看這個(gè)的執(zhí)行時(shí)機(jī)以及。當(dāng)然雖然是廢棄的,但是這個(gè)模塊已經(jīng)鎖死,所以大佬還在肆無忌憚的用,當(dāng)然已經(jīng)做了修正

babel原理分析-babel-register addHook 前言

閱讀本文時(shí)希望您對(duì)babel-register有一定了解,如果還有不了解的可以閱讀之前的文章傳送門

在之前的文章中已經(jīng)簡(jiǎn)單介紹了babel-register的功能

那么babel如何給require加上鉤子,使得在node環(huán)境下實(shí)現(xiàn)動(dòng)態(tài)編譯的呢(靜態(tài)編譯:統(tǒng)一babel。動(dòng)態(tài)編譯:js編譯到這行的時(shí)候進(jìn)行編譯)

原理分析

注:本文參考代碼為babel-0.7.0-beta版本代碼。

其實(shí)在上文babel-register中可以看到,node環(huán)境下babel的編譯,是通過一個(gè)require上addHook的解決方法,那么這個(gè)hook是怎么掛載到require上的呢

首先想到的是node官版有沒有提供原生的方法處理,官版確實(shí)提供了一個(gè)require.extensions的方法,可惜已經(jīng)廢棄了,moudle模塊也沒有所謂addhook的辦法。那就只能安靜點(diǎn)看pirate的實(shí)現(xiàn)了

深入pirate的源碼時(shí),我們卻發(fā)現(xiàn)實(shí)際pirate這個(gè)npm包并沒有做什么功能

核心代碼不超過100行,如下

const Module = module.constructor.length > 1
  ? module.constructor
  : BuiltinModule;

export function addHook(hook, opts = {}) { // eslint-disable-line import/prefer-default-export
  let reverted = false;
  const loaders = [];
  const oldLoaders = [];
  let exts;

  const originalJSLoader = Module._extensions[".js"];

  const matcher = opts.matcher || null;
  const ignoreNodeModules = opts.ignoreNodeModules !== false;
  exts = opts.extensions || opts.exts || opts.extension || opts.ext || [".js"];
  if (!Array.isArray(exts)) exts = [exts];

  exts.forEach((ext) => {
    if (typeof ext !== "string") throw new TypeError(`Invalid Extension: ${ext}`);
    const oldLoader = Module._extensions[ext] || originalJSLoader;
    oldLoaders[ext] = oldLoader;

    loaders[ext] = Module._extensions[ext] = function newLoader(mod, filename) {
      let compile;
      if (!reverted) {
        if (shouldCompile(filename, exts, matcher, ignoreNodeModules)) {
          compile = mod._compile;
          mod._compile = function _compile(code) {
            mod._compile = compile;
            const newCode = hook(code, filename);
            if (typeof newCode !== "string") {
              throw new Error(HOOK_RETURNED_NOTHING_ERROR_MESSAGE);
            }

            return mod._compile(newCode, filename);
          };
        }
      }

      oldLoader(mod, filename);
    };
  });
  return function revert() {
    if (reverted) return;
    reverted = true;

    exts.forEach((ext) => {
      if (Module._extensions[ext] === loaders[ext]) {
        Module._extensions[ext] = oldLoaders[ext];
      }
    });
  };
}

看起來這個(gè)代碼做的事很簡(jiǎn)單就是在給原生moudle方法上不斷地掛載moudle._extension[".js/.es6/.jsx"]之類的處理func,始終沒有看到執(zhí)行時(shí)機(jī)。

于是簡(jiǎn)單寫了一個(gè)demo

console.log("naturelessTT")

debugger;

require("require.js")

babel-node index.js --inspect-brk運(yùn)行去看這個(gè)hook的執(zhí)行時(shí)機(jī)以及call stack。

實(shí)際是require文件時(shí),io讀取文件后會(huì)通過moudle.load的方法加載文件,然后依次執(zhí)行_extension里掛載的方法

真相大白,但是令人驚訝的是0.7之前的版本并沒有引入pirate這個(gè)包,看了0.6.26版本后,emmmm,babel大佬使用了官版已經(jīng)標(biāo)記為廢棄的require.extensions。

當(dāng)然雖然是廢棄的,但是node這個(gè)模塊已經(jīng)鎖死,所以babel大佬還在肆無忌憚的用,當(dāng)然0.7已經(jīng)做了修正

Deprecated 

In the past, this list has been used to load non-JavaScript modules into Node.js by compiling them on-demand. However, in practice, there are much better ways to do this, such as loading modules via some other Node.js program, or compiling them to JavaScript ahead of time.

Since the module system is locked, this feature will probably never go away. However, it may have subtle bugs and complexities that are best left untouched.

Note that the number of file system operations that the module system has to perform in order to resolve a require(...) statement to a filename scales linearly with the number of registered extensions.

In other words, adding extensions slows down the module loader and should be discouraged.

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93617.html

相關(guān)文章

  • babel各單元簡(jiǎn)介&如何寫一個(gè)babel插件

    摘要:是怎么工作的如何編譯應(yīng)用場(chǎng)景語法糖的代碼統(tǒng)一相關(guān)概念介紹依賴,提供的方法,只轉(zhuǎn)化語法,不轉(zhuǎn)換類,的基礎(chǔ)配置利用對(duì)進(jìn)行劫持,在中進(jìn)行原理見同時(shí)對(duì)后的進(jìn)行緩存,提高下次效率讀取緩存根據(jù)判斷是否需要重新中傳入配置入口函數(shù)提供 Babel babel是怎么工作的? parse->AST->transform->gengerate 如何編譯js->AST babel應(yīng)用場(chǎng)景 語法糖的polyfi...

    peixn 評(píng)論0 收藏0
  • 你真的會(huì)用 Babel 嗎?

    摘要:安裝然后在的配置文件加入入口文件引入這樣就可以啦,還是可以減少很多代碼量的。是參數(shù),等同于執(zhí)行正常。這個(gè)包很簡(jiǎn)單,就是引用了和,然后生產(chǎn)環(huán)境把它們編譯到目錄下,做了映射,供使用。 引入 這個(gè)問題是對(duì)自己的發(fā)問,但我相信會(huì)有很多跟我一樣的同學(xué)。對(duì)于 babel 的使用,近半年來一直停留在與 webpack 結(jié)合使用,以及在瀏覽器開發(fā)環(huán)境下。導(dǎo)致很多 babel 的包,我都不清楚他們是干嘛...

    mochixuan 評(píng)論0 收藏0
  • 干貨實(shí)例:什么是React服務(wù)端渲染?

    摘要:今天分享一篇公司大佬的文章,非常厲害的大神崇拜臉,講講服務(wù)端渲染。服務(wù)端渲染,它到底用了什么原理呢服務(wù)端渲染原理服務(wù)端渲染的方式有很多,主流的服務(wù)端語言為使用渲染。 富婆來報(bào)道,今天想問題想不出來,隨手抓了一下頭發(fā),沒想到啊沒想到,我那濃(mei)密(sheng)茂(ji)盛(gen)的秀發(fā)又少了好幾根,一定要改掉這個(gè)想不出來問題就揪頭發(fā)的壞習(xí)慣。今天分享一篇公司大佬的文章,非常厲害的...

    Jason_Geng 評(píng)論0 收藏0
  • 如何讓 node 運(yùn)行 es6 模塊文件,及其原理

    摘要:如何讓運(yùn)行模塊文件,及其原理最新版的支持最新版幾乎所有特性,但有一個(gè)特性卻一直到現(xiàn)在都還沒有支持,那就是從開始定義的模塊化機(jī)制。便是使用這種方式達(dá)到運(yùn)行模塊文件的目的的。 如何讓 node 運(yùn)行 es6 模塊文件,及其原理 最新版的 node 支持最新版 ECMAScript 幾乎所有特性,但有一個(gè)特性卻一直到現(xiàn)在都還沒有支持,那就是從 ES2015 開始定義的模塊化機(jī)制。而現(xiàn)在我們很...

    ytwman 評(píng)論0 收藏0
  • ES6+mocha+istanbul,針對(duì)ES6語法的帶覆蓋率檢查的mocha測(cè)試

    摘要:安裝注意版本為為支持語法安裝依賴包注意為了使支持語法,在加入注意為了使支持語法,在加入小貓快跳最終運(yùn)行或都可以參考 安裝 mocha, chai,mochawesome,istanbul npm install mocha chai mochawesome [email protected] --save-dev 注意1: istanbul 版本為 ^1.0.0-alpha....

    wuyangnju 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<