博客 / 詳情

返回

看似nb的unbuild插樁技術,不過rewriting function爾🤔

看過element-plus的朋友都知道,它在開發階段使用的是unbuild進行的打包編譯。相比較傳統的rollupwebpack等老牌構建工具而言,unbuild更快!!

但這個快並不是指的編譯上更快,畢竟它説到底仍然是基於rollup的,和借力了esbuildvite相比它並不適合使用這個修飾詞

這裏的快,指的是次數,和其他構建工具監聽文件變更後reCompile不同,unbuild只在啓動時執行一次

而提供該能力的核心即jiti

jiti 是做什麼的

jiti是一個npm包,它實現的核心能力即代碼插樁

代碼插樁是指在運行時動態修改代碼的技術

如何啓用

package.json文件的scripts配置中指定--stub,示例如下

{
  "scripts": {
    "dev": "unbuild --stub"
  }
}

編譯結果如下

import jiti from "jiti這個包對應的系統文件地址";

jiti(...)('目標工程的入口文件');

源碼解析

注意,本文的重點是分析jiti的核心原理,因此對於unbuild不會進行深入探討,同時,既是核心原理,因此對於jiti的實現細節也不在探討範圍

我們關心的是:

1-jiti 是什麼

2-實時編譯是如何實現的

  • 首先,jiti 是什麼?

這要從其package.json包開始看起

從框紅的webpack可以知道,它就是一個普通的不能再普通的常規npm包,並沒有使用啥高大上的技術,換言之,它和插樁技術本身毫無關聯

因此,只能從入口找答案,它由main字段標識,指向lib文件夾

{
  "main": "./lib/index.js"
}
  • 實時編譯是如何實現的

從它是由webpack構建的就可以猜出來,像es語法降級,ts to js轉換這些操作一定是基於wb的某個loader或者plugin實現的,所以這一部分肯定也與插樁技術本身無關

故,去掉編譯相關的邏輯之後,我們很容易就發現瞭如下代碼。顯然,jiti對源代碼創建模塊並重寫了require方法

const mod = new Module(...);
mod.require = createJITI(...);

createJITI函數,其實就是對模塊的編譯過程,這就做到了,當訪問某個模塊的時候,再進行編譯,即運行時,也即插樁

總結

搞了半天,原來插樁就是個函數重寫😂

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.