国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

babel原理分析-babel-register addHook

sugarmo / 1761人閱讀

摘要:動態編譯編譯到這行的時候進行編譯原理分析注本文參考代碼為版本代碼。于是簡單寫了一個運行去看這個的執行時機以及。當然雖然是廢棄的,但是這個模塊已經鎖死,所以大佬還在肆無忌憚的用,當然已經做了修正

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

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

在之前的文章中已經簡單介紹了babel-register的功能

那么babel如何給require加上鉤子,使得在node環境下實現動態編譯的呢(靜態編譯:統一babel。動態編譯:js編譯到這行的時候進行編譯)

原理分析

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

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

首先想到的是node官版有沒有提供原生的方法處理,官版確實提供了一個require.extensions的方法,可惜已經廢棄了,moudle模塊也沒有所謂addhook的辦法。那就只能安靜點看pirate的實現了

深入pirate的源碼時,我們卻發現實際pirate這個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];
      }
    });
  };
}

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

于是簡單寫了一個demo

console.log("naturelessTT")

debugger;

require("require.js")

babel-node index.js --inspect-brk運行去看這個hook的執行時機以及call stack。

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

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

當然雖然是廢棄的,但是node這個模塊已經鎖死,所以babel大佬還在肆無忌憚的用,當然0.7已經做了修正

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.

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93617.html

相關文章

  • babel各單元簡介&如何寫一個babel插件

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

    peixn 評論0 收藏0
  • 你真的會用 Babel 嗎?

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

    mochixuan 評論0 收藏0
  • 干貨實例:什么是React服務端渲染?

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

    Jason_Geng 評論0 收藏0
  • 如何讓 node 運行 es6 模塊文件,及其原理

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

    ytwman 評論0 收藏0
  • ES6+mocha+istanbul,針對ES6語法的帶覆蓋率檢查的mocha測試

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

    wuyangnju 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<