摘要:若不存在則模塊標識應該默認定義為在加載器中被請求腳本的標識。其中是一個數組,里面的成員就是要加載的模塊是模塊加載完成之后的回調函數。在加載與兩個模塊之后執行回調函數實現具體過程。在判斷是否支持是否存在,存在則使用方式加載模塊。
我的github(PS:希望star): https://github.com/tonyzheng1...
今天由于項目中引入的echarts的文件太大,requirejs經常加載超時,不得不分開來加載echarts的各個圖表。但是使用echarts自帶的在線構建工具生成的支持AMD 標準的模塊報錯,所以不得不使用echarts的全局函數,使用requirejs的shim進行加載。借此機會學習一下AMD, CMD, CommonJS和UMD各自的規范,和它們之間的區別。
Javascript模塊化在了解這些規范之前,還是先了解一下什么是模塊化。
模塊化是指在解決某一個復雜問題或者一系列的雜糅問題時,依照一種分類的思維把問題進行系統性的分解以之處理。模塊化是一種處理復雜系統分解為代碼結構更合理,可維護性更高的可管理的模塊的方式。可以想象一個巨大的系統代碼,被整合優化分割成邏輯性很強的模塊時,對于軟件是一種何等意義的存在。對于軟件行業來說:解耦軟件系統的復雜性,使得不管多么大的系統,也可以將管理,開發,維護變得“有理可循”。
還有一些對于模塊化一些專業的定義為:模塊化是軟件系統的屬性,這個系統被分解為一組高內聚,低耦合的模塊。那么在理想狀態下我們只需要完成自己部分的核心業務邏輯代碼,其他方面的依賴可以通過直接加載被人已經寫好模塊進行使用即可。
首先,既然是模塊化設計,那么作為一個模塊化系統所必須的能力:
定義封裝的模塊。
定義新模塊對其他模塊的依賴。
可對其他模塊的引入支持。
好了,思想有了,那么總要有點什么來建立一個模塊化的規范制度吧,不然各式各樣的模塊加載方式只會將局攪得更為混亂。那么在JavaScript中出現了一些非傳統模塊開發方式的規范 CommonJS的模塊規范,AMD(Asynchronous Module Definition),CMD(Common Module Definition)等。
CommonJSCommonJS是服務器端模塊的規范,Node.js采用了這個規范。
根據CommonJS規范,一個多帶帶的文件就是一個模塊。加載模塊使用require方法,該方法讀取一個文件并執行,最后返回文件內部的exports對象。
例如:
// foobar.js //私有變量 var test = 123; //公有方法 function foobar () { this.foo = function () { // do someing ... } this.bar = function () { //do someing ... } } //exports對象上的方法和變量是公有的 var foobar = new foobar(); exports.foobar = foobar;
//require方法默認讀取js文件,所以可以省略js后綴 var test = require("./boobar").foobar; test.bar();
CommonJS 加載模塊是同步的,所以只有加載完成才能執行后面的操作。像Node.js主要用于服務器的編程,加載的模塊文件一般都已經存在本地硬盤,所以加載起來比較快,不用考慮異步加載的方式,所以CommonJS規范比較適用。但如果是瀏覽器環境,要從服務器加載模塊,這是就必須采用異步模式。所以就有了 AMD CMD 解決方案。
AMD和RequireJS AMDAMD是"Asynchronous Module Definition"的縮寫,意思就是"異步模塊定義".
AMD設計出一個簡潔的寫模塊API:
define(id?, dependencies?, factory);
第一個參數 id 為字符串類型,表示了模塊標識,為可選參數。若不存在則模塊標識應該默認定義為在加載器中被請求腳本的標識。如果存在,那么模塊標識必須為頂層的或者一個絕對的標識。
第二個參數,dependencies ,是一個當前模塊依賴的,已被模塊定義的模塊標識的數組字面量。
第三個參數,factory,是一個需要進行實例化的函數或者一個對象。
通過參數的排列組合,這個簡單的API可以從容應對各種各樣的應用場景,如下所述。
定義無依賴的模塊
define( { add : function( x, y ){ return x + y ; } } );
定義有依賴的模塊
define(["alpha"], function( alpha ){ return { verb : function(){ return alpha.verb() + 1 ; } } });
定義數據對象模塊
define({ users: [], members: [] });
具名模塊
define("alpha", [ "require", "exports", "beta" ], function( require, exports, beta ){ export.verb = function(){ return beta.verb(); // or: return require("beta").verb(); } });
包裝模塊
define(function(require, exports, module) { var a = require("a"), b = require("b"); exports.action = function() {}; } );
不考慮多了一層函數外,格式和Node.js是一樣的:使用require獲取依賴模塊,使用exports導出API。
除了define外,AMD還保留一個關鍵字require。require 作為規范保留的全局標識符,可以實現為 module loader,也可以不實現。
模塊加載require([module], callback)
AMD模塊化規范中使用全局或局部的require函數實現加載一個或多個模塊,所有模塊加載完成之后的回調函數。
其中:
[module]:是一個數組,里面的成員就是要加載的模塊;
callback:是模塊加載完成之后的回調函數。
例如:加載一個math模塊,然后調用方法 math.add(2, 3);
require(["math"], function(math) { math.add(2, 3); });RequireJS
RequireJS 是一個前端的模塊化管理的工具庫,遵循AMD規范,它的作者就是AMD規范的創始人 James Burke。所以說RequireJS是對AMD規范的闡述一點也不為過。
RequireJS 的基本思想為:通過一個函數來將所有所需要的或者說所依賴的模塊實現裝載進來,然后返回一個新的函數(模塊),我們所有的關于新模塊的業務代碼都在這個函數內部操作,其內部也可無限制的使用已經加載進來的以來的模塊。
那么scripts下的main.js則是指定的主代碼腳本文件,所有的依賴模塊代碼文件都將從該文件開始異步加載進入執行。
define用于定義模塊,RequireJS要求每個模塊均放在獨立的文件之中。按照是否有依賴其他模塊的情況分為獨立模塊和非獨立模塊。
獨立模塊,不依賴其他模塊。直接定義:
define({ method1: function(){}, method2: function(){} });
也等價于
define(function() { return { method1: function(){}, method2: function(){} } });
非獨立模塊,對其他模塊有依賴。
define([ "module1", "module2" ], function(m1, m2) { ... });
或者:
define(function(require) { var m1 = require("module1"), m2 = require("module2"); ... });
簡單看了一下RequireJS的實現方式,其 require 實現只不過是提取 require 之后的模塊名,將其放入依賴關系之中。
require方法調用模塊
在require進行調用模塊時,其參數與define類似。
require(["foo", "bar"], function(foo, bar) { foo.func(); bar.func(); } );
在加載 foo 與 bar 兩個模塊之后執行回調函數實現具體過程。
當然還可以如之前的例子中的,在define定義模塊內部進行require調用模塊
define(function(require) { var m1 = require( "module1" ), m2 = require( "module2" ); ... });
define 和 require 這兩個定義模塊,調用模塊的方法合稱為AMD模式,定義模塊清晰,不會污染全局變量,清楚的顯示依賴關系。AMD模式可以用于瀏覽器環境并且允許非同步加載模塊,也可以按需動態加載模塊。
官網 (http://www.requirejs.org/)
API (http://www.requirejs.org/docs...
CMD是SeaJS 在推廣過程中對模塊定義的規范化產出
對于依賴的模塊AMD是提前執行,CMD是延遲執行。不過RequireJS從2.0開始,也改成可以延遲執行(根據寫法不同,處理方式不通過)。
CMD推崇依賴就近,AMD推崇依賴前置。
//AMD define(["./a","./b"], function (a, b) { //依賴一開始就寫好 a.test(); b.test(); }); //CMD define(function (requie, exports, module) { //依賴可以就近書寫 var a = require("./a"); a.test(); ... //軟依賴 if (status) { var b = requie("./b"); b.test(); } });
雖然 AMD也支持CMD寫法,但依賴前置是官方文檔的默認模塊定義寫法。
AMD的API默認是一個當多個用,CMD嚴格的區分推崇職責單一。例如:AMD里require分全局的和局部的。CMD里面沒有全局的 require,提供 seajs.use()來實現模塊系統的加載啟動。CMD里每個API都簡單純粹。
UMDUMD是AMD和CommonJS的糅合
AMD模塊以瀏覽器第一的原則發展,異步加載模塊。
CommonJS模塊以服務器第一原則發展,選擇同步加載,它的模塊無需包裝(unwrapped modules)。
這迫使人們又想出另一個更通用的模式UMD (Universal Module Definition)。希望解決跨平臺的解決方案。
UMD先判斷是否支持Node.js的模塊(exports)是否存在,存在則使用Node.js模塊模式。
在判斷是否支持AMD(define是否存在),存在則使用AMD方式加載模塊。
(function (window, factory) { if (typeof exports === "object") { module.exports = factory(); } else if (typeof define === "function" && define.amd) { define(factory); } else { window.eventUtil = factory(); } })(this, function () { //module ... });
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79112.html
摘要:函數有兩個參數,第一個參數是當前運行時環境,第二個參數是模塊的定義體。在執行規范時,會優先判斷是當前環境是否支持環境,然后再檢驗是否支持環境,否則認為當前環境為瀏覽器環境 CommonJS規范 CommonJS定義的模塊分為3部分: require 模塊引用 exports 模塊導出 module 模塊本身 根據CommonJS規范,一個單獨的文件就是一個模塊。每一個模塊都是一個...
摘要:若不存在則模塊標識應該默認定義為在加載器中被請求腳本的標識。這也是目前很多插件頭部的寫法,就是用來兼容各種不同模塊化的寫法。語句輸出的值是動態綁定的,綁定其所在的模塊。 前言 歷史上,js沒有模塊化的概念,不能把一個大工程分解成很多小模塊。這對于多人開發大型,復雜的項目形成了巨大的障礙,明顯降低了開發效率,java,Python有import,甚至連css都有@import,但是令人費...
摘要:常見模塊化方案是由社區提出的模塊化方案中的一種,遵循了這套方案。是模塊化規范中的一種,遵循了這套規范。中的模塊化能力由兩個命令構成和,命令用于規定模塊的對外接口,命令用于輸入其他模塊提供的功能。 為什么需要模塊化 在ES6出現之前,JS語言本身并沒有提供模塊化能力,這為開發帶來了一些問題,其中最重要的兩個問題應當是全局污染和依賴管理混亂。 // file a.js var name =...
摘要:要想讓模塊再次運行,必須清除緩存。模塊加載會阻塞接下來代碼的執行,需要等到模塊加載完成才能繼續執行同步加載。環境服務器環境應用的模塊規范是參照實現的。這等同在每個模塊頭部,有一行這樣的命令。 commonJS 特點: 1、模塊可以多次加載,但是只會在第一次加載時運行一次,然后運行結果就被緩存了,以后再加載,就直接讀取緩存結果。要想讓模塊再次運行,必須清除緩存。2、模塊加載會阻塞接下來代...
摘要:即盡早地執行依賴模塊。阮一峰輸出值的引用模塊是動態關聯模塊中的值,輸出的是值得引用。的加載實現阮一峰運行時加載靜態編譯模塊是運行時加載,模塊是編譯時輸出接口。 模塊化開發 優點 模塊化開發中,通常一個文件就是一個模塊,有自己的作用域,只向外暴露特定的變量和函數,并且可以按需加載。 依賴自動加載,按需加載。 提高代碼復用率,方便進行代碼的管理,使得代碼管理更加清晰、規范。 減少了命名沖...
閱讀 1265·2021-09-27 13:35
閱讀 2563·2021-09-06 15:12
閱讀 3380·2019-08-30 15:55
閱讀 2829·2019-08-30 15:43
閱讀 432·2019-08-29 16:42
閱讀 3446·2019-08-29 15:39
閱讀 3062·2019-08-29 12:28
閱讀 1239·2019-08-29 11:11