Webpack 如何實現 live binding

2021-09-24 06:56:06 字數 2155 閱讀 1847

我們知道, es module 與 commonjs 有乙個比較大的差別在於,es module 中匯出的變數只是乙個佔位符,並不在 import 的時候進行賦值操作,而是當真正用到的時候才會去 import 的模組中取值,而且匯入的值只能在宣告值的模組內部被修改。

所有的 import 的值都是動態繫結的,可以理解為它們指向同一塊記憶體區,這在規範中稱為 live binding。 那麼,webpack 的執行時是怎麼實現這一套機制的呢?

先上 demo **

`index.js`

import from './async-data.mjs';

console.log('instance ', a);

settimeout(() => , 1000 );

`a.js`

let a = 1;

settimeout(() => , 0);

export ;

複製**

事實證明, webpack 編譯出來的結果符合規範。

那麼,webpack 是如何做到的呢?

我們來看看 webpack 打包出來的檔案。

(functions(modules)));

/******/ }

/******/ };

//....

})();

let a = 1;

settimeout(() => , 0);

/***/ }),

/***/ "./src/index.mjs":

/*!***********************!*\

!*** ./src/index.mjs ***!

\***********************/

/*! no exports provided */

/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) , 1000 );

/***/ })

})複製**

我們可以看到,webpack 將值拷貝變成了函式呼叫,把 a 變成乙個 getter,每次獲取相當於一次函式呼叫,呼叫時返回模組內的值,相當於利用閉包實現了 live binding。

還有一處值得留意的細節是,webpack 把 export 放在了所有 import 的上方,這麼做也是符合 esm 語義的,因為在模組執行前,模組的**就應該被 parse 一遍,模組的 import 和export 在當時就已經確定了。

那為什麼 export 會在 import 之上呢? 因為 export 是乙個沒有***的語句,所做的僅僅是把 expert 出去的變數包裹在 get 方法裡,這樣能夠有效解決迴圈引用的問題。而 import 是乙個有***的函式,會跳到另乙個模組中執行語句,當下乙個模組依賴於當前模組(即造成了迴圈引用),提前 export 宣告可以確定被引用模組的 export。

本質上說,我們希望我們匯出的變數,能夠在之後通過對於模組內值的改動,影響到外部。

而 commonjs 對於模組化的實現簡單粗暴,就是通過立即執行函式實現了作用域的封裝,而 module 是立即執行函式的引數之一,是 require 執行前事先準備好的乙個物件,其他模組通過對 module 的賦值實現模組中值的匯入。

那麼,我們知道 js 中物件的賦值是引用傳遞,利用這個特性,我們就可以實現近似於 live binding 的效果。

只要我們 export 乙個物件,那麼對這個物件的修改,就會影響到所有 require 的值。

根據這個思路,我們上面的 demo 就可以用 commonjs 等價實現為下面的例子:

`index.js`

const a = require('./a.js');

console.log('instance ', a);

settimeout(() => , 1000 );

`a.js`

let b =

settimeout(() => , 0);

module.exports = b;

複製**

執行結果:

//-> node index.js

instance

a 複製**

webpack打包專案如何實現github預覽

最近在用vue寫了乙個專案用來webpack打包後,想要上傳到github,並通過github pages預覽,在這個過程中遇到了一些問題,因此寫個筆記,以便查閱 完成vue專案以後,在上傳到github之前,需要修改一些配置才能通過github pages預覽專案。一 修改配置 解決檔案路徑問題 ...

如何學習 Webpack

tip 本文是 webpack howto 的原文,我覺得這篇文章寫得非常好,確實算是目前學習 webpack 入門的必讀文章。直接收錄之。這是一本教你如何應用webpack到你的專案中的工具書。它包含了我們在instagram中用到的絕大多數的內容。我的建議 這個教程作為你第乙個webpack的文...

如何學習 Webpack

tip 本文是 webpack howto 的原文,我覺得這篇文章寫得非常好,確實算是目前學習 webpack 入門的必讀文章。直接收錄之。這是一本教你如何應用webpack到你的專案中的工具書。它包含了我們在instagram中用到的絕大多數的內容。我的建議 這個教程作為你第乙個webpack的文...