如何構建乙個微型的CMD模組化載入器

2022-05-24 23:27:11 字數 2409 閱讀 4233

前端模組化是乙個老生常談的話題,模組化的好處是不言而喻,比如易於**復用、易於維護、易於團隊開發d等云云。對於前端模組載入器,以前僅僅止步於會用的階段,為了加深對前端模組化的理解,大概花了一周的時間來學習、調研並嘗試自己實現乙個簡易版的符合cmd規範的載入器。

載入器是按照cmd規範進行設計的,具體的cmd規範就不列出了,詳情請見cmd規範。

use為程式啟動的入口,主要幹兩件事:

載入指定的模組

待模組載入完成後,呼叫**函式

1

function

use(ids, callback) )).then(function

(list) , function

(error) );

10 }

1

function

load(id) )

8 module.on("error", reject);9})

10 }

use會呼叫load函式,這個函式的作用是根據模組的id,載入模組,並返回乙個promise物件。

define的作用主要是用來定義乙個模組。按照cmd的規範,定義乙個模組的**類似:

1

var factory = function

(require, exports, module)

4 define(factory);

為了方便說明,我給匿名函式取名為factory, factory就是我們模組定義的工廠函式,它只是define函式的乙個引數,並不會被直接執行,而是會在需要的時候由專門的函式來呼叫生成介面。

1

function

define(factory) )).then(function

() , function

() );

15 } else

18 }

require(id)

require函式比較簡單,主要作用就是根據模組id獲取指定的模組,然後返回這個模組的對外介面。

1

function

require(id)

7 }

模組定義**直到現在,才會被執行。執行模組定義**的函式就是getmoduleexports函式:

1

function

getmoduleexports(module) ;

4module.factory(require, module.exports, module);5}

6return

module.exports;

7 }

記得剛接觸sea.js的時候,對介面暴露物件moduleexports的區別不是很清楚,學習完別人的原始碼並嘗試自己實現一遍的時候,它們的區別已經非常明朗了:

exports只是module.exports的乙個引用,單純的改變exports的值並不會對module.exports造成任何影響,所以通過

1 exports =

5 }

這樣的形式來定義介面是無效的。

demo請見這裡, 原始碼請見這裡

請開啟控制台檢視結果

果然學習技術最好方法之一就是閱讀別人的**。閱讀別人的**是痛苦的,因為**裡充斥這他個人的**癖好,有時候乙個很簡單的條件判語句可能用一些hack技巧實現了之後,在不了解的情況下,看的就比較痛苦了,以為另有玄機,傻乎乎的看了半天。不過,到最後搞明白之後,還是有些許成就感的。

前端模組化載入器,以前是只見樹木不見森林,通過這次學習,不能說完全搞清楚了乙個模組載入器的所有實現細節,但是對於像模組是怎樣實現非同步載入的,模組是如何定義的,模組間如何進行依賴分析的這些問題有了乙個更深的認識和理解。

模組化的構建工具

1.requirejs 核心是支援amd風格的模組化執行 2.browserify 目標是讓執行在伺服器端的符合commonjs 執行在瀏覽器端 3.babel 定位是transformer,即語法轉換器,他承擔將es6,jsx轉化成es5語法的核心功能 4.systemjs 相容各種模組化規範的執...

我的乙個模組化程式(自助購票)

include include include includechar start 10 end 10 sort 10 void homepage void plan void ds void makesure void success include ticket.h void main incl...

構建乙個模組的層級包

檔案 init py的目的是要包含不同執行級別的包的可選的初始化 舉個例子,如果你執行了語句import graphics,檔案graphics init py將被匯入,建立graphics 命名空間 的內容。像import graphics.format.jpg這樣匯入,檔案graphics in...