摘要:語言官方未實現(xiàn)命名空間,我們定義一個函數(shù)以實現(xiàn)命名空間。函數(shù)的使用如我們可以這樣實現(xiàn)對象保存著所有已加載的模塊每一個模塊實例都有屬性作為時查找的標識符,屬性作為對外暴露的對象,屬性表示是否加載完。將函數(shù)傳入,來支持模塊內(nèi)引用其他模塊。
JavaScript語言官方未實現(xiàn)命名空間,我們定義一個define函數(shù)以實現(xiàn)命名空間。define函數(shù)的使用如:
define(function(exports, module, require) { const $ = require("http://path/to/defined-jquery"); $(function(){ // dom ready!!! }); });
我們可以這樣實現(xiàn):
(function(global) { "use strict"; var errMsg = Math.random().toString(32).substr(2); // rootModule 對象保存著所有已加載的模塊 var rootModule = {}; // 每一個模塊實例都有id屬性作為require時查找的標識符, // exports屬性作為對外暴露的對象,loaded屬性表示是否加載完。 function ModuleCtor(id) { if (!this || this.__proto__ !== ModuleCtor.prototype) { return new ModuleCtor(id); } this.id = id; this.exports = {}; this.loaded = !1; } function define(id, fn) { // 手動賦值模塊id,兼容一個script里有多個define。 if (typeof id === "function") { fn = id; id = document.currentScript ? document.currentScript.src : Math.random() .toString(32) .substr(2); } if (typeof id !== "string") { id = "" + id; } var module = ModuleCtor(id); exec(); function __require__(src) { // 如果依賴已經(jīng)加載過直接返回module.exports, // 如果沒有加載過則通過jsonp加載,并且拋出一個異常來打斷原函數(shù)執(zhí)行,在子模塊加載完畢后重新執(zhí)行原函數(shù)模擬異步代碼阻塞同步執(zhí)行。 if (rootModule[src] && rootModule[src].__proto__ === ModuleCtor.prototype) { return rootModule[src].exports; } loadScript(src, function() { exec(); }); throw new Error(errMsg); } function exec() { // 將__require__函數(shù)傳入fn,來支持模塊內(nèi)引用其他模塊。 try { fn.call(module.exports, module.exports, module, __require__); module.loaded = !0; rootModule[id] = module; } catch (err) { if (err.message !== errMsg) { throw err; } } } } function loadScript(src, callback) { var script = document.createElement("script"); script.src = src; script.onload = function() { callback && callback(src); }; document.body.appendChild(script); return script; } // 暴露define給全局 global.define = define; })(window);
這個模塊加載的實現(xiàn)有很多不足,如果模塊內(nèi)有很多require時會被執(zhí)行很多次,所以最好子模塊內(nèi)都是函數(shù)不要有自己的狀態(tài)。seajs的依賴解決方法是,調(diào)用函數(shù)的toString方法來獲得函數(shù)字面量,然后在parse出模塊依賴,先加載依賴,每一個依賴加載完成后都emit一個事件,當所有依賴都加載完畢后,才執(zhí)行factory函數(shù),factory函數(shù)只執(zhí)行一次,但是模塊加載的順序和require的順序基本沒有關系(并發(fā)請求,誰都有可能先到)。
======= 一本正經(jīng)的分割線 ======
順便吐槽一下seajs,由于某種原因,我再8102年見到了seajs而我在3000年前沒用過。文檔始終沒有交代require("caonima");是如何打斷函數(shù)執(zhí)行的。看了源碼發(fā)現(xiàn)是用了Function.prototype.toString方法,然后分析依賴并發(fā)加載(require函數(shù)是沒有順序之分的)??丛创a前,我自己為了模擬該行為,通過拋出異常再反復的重新執(zhí)行也實現(xiàn)了一個文件加載,而且我這個更賤的貨還是真的同步引入依賴,更加cmd一些。
附 Webpack 模塊加載原理:
(function(modulesArr) { var rootModule = {}; function __require__(id) { if (rootModule[id]) { return rootModule[id].exports; } var currentModule = modulesArr[id]; var module = { id, exports: {} }; currentModule.call(module.exports, module.exports, module, __require__); currentModule[id] = module; return module.exports; } return __require__(0); })([ function(exports, module, require) { var m1 = require(1); console.log(m1); }, function(exports, module, require) { exports.msg = "Hello World"; var m2 = require(2); m2(); }, function(exports, module, require) { module.exports = function() { var str = "Hello World"; console.log(str); return str; }; } ]);
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://www.ezyhdfw.cn/yun/95627.html
摘要:例如指定一些依賴到模塊中實現(xiàn)規(guī)范的模塊化,感興趣的可以查看的文檔。 CommonJS 定義了 module、exports 和 require 模塊規(guī)范,Node.js 為了實現(xiàn)這個簡單的標準,從底層 C/C++ 內(nèi)建模塊到 JavaScript 核心模塊,從路徑分析、文件定位到編譯執(zhí)行,經(jīng)歷了一系列復雜的過程。簡單的了解 Node 模塊的原理,有利于我們重新認識基于 Node 搭建的...
摘要:二模塊化誤區(qū)加快加載和執(zhí)行的速度,一直是前端優(yōu)化的一個熱點。結果文件減少,也達到了預期的效果。避免不必要的延遲。最后再根據(jù)文件的功能類型,來決定是放在頁面的頭部還是尾部。 注:本文是純技術探討文,無圖無笑點,希望您喜歡 一.前言 軟件行業(yè)極其缺乏前端人才這是圈內(nèi)的共識了,某種程度上講,同等水平前端的工資都要比后端高上不少,而圈內(nèi)的另一項共識則是——網(wǎng)頁是公司的臉面! 幾年前,谷歌的一項...
摘要:模塊化編程,已經(jīng)成為一個迫切的需求。隨著網(wǎng)站功能逐漸豐富,網(wǎng)頁中的也變得越來越復雜和臃腫,原有通過標簽來導入一個個的文件這種方式已經(jīng)不能滿足現(xiàn)在互聯(lián)網(wǎng)開發(fā)模式,我們需要團隊協(xié)作模塊復用單元測試等等一系列復雜的需求。 隨著網(wǎng)站逐漸變成互聯(lián)網(wǎng)應用程序,嵌入網(wǎng)頁的Javascript代碼越來越龐大,越來越復雜。網(wǎng)頁越來越像桌面程序,需要一個團隊分工協(xié)作、進度管理、單元測試等等......開發(fā)...
摘要:模塊系統(tǒng)為了讓的文件可以相互調(diào)用,提供了一個簡單的模塊系統(tǒng)。但是,沒有模塊系統(tǒng)。包管理簡稱,是隨同一起安裝的包管理工具。輸入命令,根據(jù)提示配置包的相關信息,生成相應的。以上所描述的模塊載入機制均定義在模塊之中。 Node.js簡介 首先從名字說起,網(wǎng)上查閱資料的時候會發(fā)現(xiàn)關于node的寫法五花八門,到底哪一種寫法最標準呢?遵循官方網(wǎng)站的說法,一直將項目稱之為Node或者Node.js。...
摘要:與在模塊化編程的世界中,有兩個規(guī)范不得不提,它們分別是和。所有依賴于某個模塊的代碼全部移到模塊加載語句的回調(diào)函數(shù)中去。的語句接受兩個參數(shù)在回調(diào)函數(shù)中,可以通過變量引用模塊?;卣{(diào)函數(shù)的返回值就是當前對象的導出值。 JavaScript本身不是一種模塊化語言,設計者在創(chuàng)造JavaScript之初應該也沒有想到這么一個腳本語言的作用領域會越來越大。以前一個頁面的JS代碼再多也不會多到哪兒去,...
閱讀 1493·2021-09-23 11:21
閱讀 3170·2019-08-30 14:14
閱讀 3246·2019-08-30 13:56
閱讀 4260·2019-08-30 11:20
閱讀 2017·2019-08-29 17:23
閱讀 2835·2019-08-29 16:14
閱讀 1760·2019-08-28 18:18
閱讀 1542·2019-08-26 12:14