成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

OMD: javascript模塊化開(kāi)發(fā)兼容CommonJS, AMD, CMD 以及 原生 JS

lavor / 3235人閱讀

摘要:它就是一套兼容方案,目前兼容的有以及原生支持。返回值問(wèn)題在第一次使用時(shí),。具體是什么意義呢的返回值,其實(shí)就是插件提供的對(duì)外接口,而實(shí)際上,就是一個(gè)對(duì)象。而在環(huán)境下,只需要將這個(gè)返回值賦予即可完成該模塊的接口。

有更新,請(qǐng)到github上看源碼

什么是OMD

在node.js流行起來(lái)之前,javascript的開(kāi)發(fā)方式都是函數(shù)式的順序依賴關(guān)系,直到node火起來(lái)。CommonJS其實(shí)首先提供了一個(gè)豐富的可擴(kuò)展的庫(kù),在此基礎(chǔ)上提供可應(yīng)用的API,在這些API的基礎(chǔ)上,逐漸形成一套規(guī)范,使得javascript的開(kāi)發(fā)在這些規(guī)范的基礎(chǔ)上進(jìn)行。它的重要特征就是運(yùn)行開(kāi)發(fā)者模塊化的開(kāi)發(fā)javascript,提供一個(gè)模塊,這個(gè)模塊對(duì)外提供接口,有一個(gè)入口去調(diào)動(dòng)所有的模塊協(xié)同完成不同的功能。node就是在此規(guī)范上建立起來(lái)的服務(wù)端框架。

node可以被認(rèn)為是應(yīng)用程序開(kāi)發(fā)的一個(gè)案例,它是運(yùn)行在服務(wù)器上的javascript。而是否可以在瀏覽器上面也遵循CommonJS規(guī)范呢?為了達(dá)到這個(gè)目的,requirejs火起來(lái),與它對(duì)應(yīng)的是AMD規(guī)范。實(shí)際上,AMD規(guī)范是CommonJS的一個(gè)兼容方案,requirejs希望建立一個(gè)既滿足應(yīng)用程序,又滿足瀏覽器運(yùn)行的規(guī)范。AMD也逐漸被開(kāi)發(fā)者接受,國(guó)外很多javascript發(fā)布產(chǎn)品,基本上都遵循或支持amd規(guī)范。

seajs是專注于瀏覽器的模塊化javascript開(kāi)發(fā)框架,和前兩者不同的是,它只專注于瀏覽器端,而且更優(yōu)雅靈活,它所遵循的是CMD規(guī)范,其創(chuàng)始人為中國(guó)的前端大牛玉伯。自此,三家分立,各有裨益,javascript的模塊化開(kāi)發(fā)規(guī)范已經(jīng)被創(chuàng)立完畢,以后就將其逐漸完善,并實(shí)現(xiàn)更多的應(yīng)用。

在此基礎(chǔ)上,有人試圖實(shí)現(xiàn)兼容。也就是自己的代碼既能在node上運(yùn)行,也能在符合amd規(guī)范的代碼環(huán)境中運(yùn)行。于是產(chǎn)生了umd,其實(shí)umd并不算規(guī)范,而只能算一種兼容方案,它可以兼容CommonJS和AMD。但國(guó)內(nèi)更多的其實(shí)是使用seajs,包括淘寶、騰訊的部分產(chǎn)品,都是使用seajs框架,而react等的跑火,有理由相信,未來(lái)的前端開(kāi)發(fā)一定是模塊化趨勢(shì)的。

就目前而言,為了能兼容commonjs amd cmd以及原生的javascript,我結(jié)合了前人的經(jīng)驗(yàn),發(fā)布了omd,它也不是什么規(guī)范,只是一套兼容方案罷了。

omd的目的,就是希望開(kāi)發(fā)javascript按照這個(gè)規(guī)則來(lái)完成代碼,就能使它在模塊化開(kāi)發(fā)環(huán)境下能跑,在普通的javascript或jquery代碼中也能跑。它就是一套兼容方案,目前兼容的有module.exports、amd、cmd以及原生支持。

OMD的源碼

首先,我需要將源碼放出來(lái),所有的讀者可以先簡(jiǎn)單的看下它的內(nèi)容,大致了解它的運(yùn)行規(guī)則。在github上follow這個(gè)項(xiàng)目,隨時(shí)了解最新的一些變化。

OMD原理詳解

在《javascript立即執(zhí)行某個(gè)函數(shù):插件中function(){}()再思考》一文中,我詳細(xì)闡述了!function(fun){}(function($){});,因此這里就不詳細(xì)闡述了。

兼容amd和cmd

if(typeof define == "function" && (define.amd != undefined || define.cmd != undefined) {
  define(function() {
    return fun();
  });
}

上面這段代碼,僅在amd或cmd規(guī)范下使用時(shí)才執(zhí)行define。我們這里把范圍縮小到requirejs和sea.js。對(duì)于requirejs而言,define和define.amd是可見(jiàn)的,因此執(zhí)行define(function(){});,同樣的道理,seajs也會(huì)執(zhí)行。但是作為兩種不同的規(guī)范,為何可以以相同的代碼返回呢?

在requirejs中,一個(gè)模塊可以如此去定義:

define({});
define(factory);
define(id,dependencies,factor);
define(dependencies,factor)

在seajs中也差不多,但是也有不同之處:

define({});
define(factory);
define(id,dependencies,factory);
define(id,factory);

前面三種都是一樣的,但是細(xì)節(jié)上也有所不同,第一種以對(duì)象的方式定義并不能解決我們插件中接口傳遞的目的,因此不考慮。剩下的就只有兩種相同的形式,但是就像前文說(shuō)到的一樣,OMD是為了實(shí)現(xiàn)兼容,也就是說(shuō)它必須作為框架被應(yīng)用,框架的基礎(chǔ)代碼具有穩(wěn)定性,不能讓用戶改來(lái)改去,否則也就失去了規(guī)范的意義。而在剩下的兩種中,define(id,dependencies,factory)的前兩個(gè)變量,都需要自己去定義,因此,也被排除。最終也就只有define(factory)這種形式被我們采用。

define(function(require,exports,module){
  var a = require("a");
});

這種代碼形式在require.js和sea.js中都可以使用,可是在sea.js中,可以使用exports.xxx = function(){}來(lái)提供接口,可是在require.js中,不得不采用return的形式,幸好,在sea.js中,return也是有效的。所以,最終,我們選擇了return的形式向外提供接口:

define(function(){
    return {
        fun1 : function(a,b) {},
        fun2 : function(c,d) {}
    }; // return的結(jié)果為一個(gè)對(duì)象
});

在sea.js或require.js中:

define(function(){
    var $omd = require("omd");
    var fun1 = $omd.fun1(12,34);
});

這樣,在omd.js中寫(xiě)的插件所提供的模塊接口,就可以被使用了。

兼容comomjs

當(dāng)define沒(méi)有被定義的時(shí)候,說(shuō)明跟sea.js和require.js沒(méi)有任何關(guān)系了,這個(gè)時(shí)候,我們要檢查是否支持node.js。

如果是在node.js環(huán)境下運(yùn)行,那么module和exports是一個(gè)由核心庫(kù)提供的全局變量。因此,只需要將插件提供的接口賦值給module.exports,就完成了當(dāng)前文件(模塊)所提供的接口了。

兼容原生的javascript

當(dāng)以上情況都不滿足的情況下,實(shí)際上,你所提供的接口,就是一個(gè)函數(shù)。你提供了一個(gè)fun1的接口,你就可以在其他javascript代碼中執(zhí)行fun1()函數(shù)。

全局變量$和局部變量$

把$作為變量名,最大的好處是兼容jquery和zepto。在第一個(gè)function(factory){}中,我兩次使用到了factory($),在這里,$沒(méi)有被事先聲明過(guò),因此用了一個(gè)if(typeof $ === "undefined")做判斷。但是如果當(dāng)前環(huán)境下已經(jīng)加載了jquery或zepto,$就是一個(gè)全局變量,實(shí)際上它是window.$。因此,在執(zhí)行factory($)時(shí),實(shí)際上是把$作為參數(shù)傳遞給了factory()。

而在前面那篇關(guān)于立即執(zhí)行函數(shù)的文章中我已經(jīng)講過(guò)了,在這里的factory()實(shí)際上就是第二個(gè)我們要真正用來(lái)寫(xiě)插件代碼的function($){},要理解這一點(diǎn),你必須讀懂上面那篇文章。

在factory($)中,$如果代表jquery或zepto,那么它實(shí)際上是一個(gè)全局變量。而到了function($),$實(shí)際上成為函數(shù)的參數(shù),成為一個(gè)局部變量。在function($){}中,雖然你可以使用$("#div1")進(jìn)行選擇,但你要知道,這里的$并非全局變量window.$,而是傳遞而來(lái)的,是它的引用。下文還會(huì)提到,要使用 var jQuery = $; 這樣詭異的代碼來(lái)處理某些情況。

factory($)返回值問(wèn)題

在第一次使用factory($)時(shí),return factory($)。第二次時(shí),ex = factory($)。從值的返回角度講,factory($)必然存在一個(gè)return。具體是什么意義呢?

factory($)的返回值,其實(shí)就是插件提供的對(duì)外接口,而實(shí)際上,就是一個(gè)對(duì)象Object。我們可以在第一次return factory($);的時(shí)候,也先執(zhí)行一次賦值操作:

define(function(){
    var ex = factory($);
    return ex;
});

前面已經(jīng)講過(guò)了,amd和cmd在define的function中return,實(shí)際上是模塊對(duì)外提供接口的一種方式,而這種方式,必須保證以對(duì)象的形式返回。因此,在插件代碼中,你可以看到,我首先定義的是一個(gè)ex = {},然后執(zhí)行return ex;從而對(duì)外提供了接口。

而在node.js環(huán)境下,只需要將這個(gè)ex返回值賦予exports即可完成該模塊的接口。在原生的JavaScript環(huán)境下,沒(méi)有接口這種概念,對(duì)外提供的,則是函數(shù)或?qū)ο髮傩?,將它賦予window對(duì)象,就相當(dāng)于提供了一個(gè)全局函數(shù)或全局變量。

OMD開(kāi)發(fā)規(guī)則

利用omd開(kāi)發(fā)兼容各個(gè)規(guī)范的插件(模塊)時(shí),只需要在// 真正的插件代碼都在這里這句注釋后面撰寫(xiě)插件代碼即可,無(wú)需像其他教程所示一樣,寫(xiě)一個(gè)(function($){}(jQuery)),直接寫(xiě)插件內(nèi)容即可。如果無(wú)需對(duì)外提供接口,則寫(xiě)完插件代碼就可以完成開(kāi)發(fā)。

關(guān)于var jQuery = $

在插件代碼中,一些插件并沒(méi)有使用$,而是使用jQuery。但是前文已經(jīng)提到了,在這個(gè)函數(shù)內(nèi)部,jQuery是未定義的,$是傳遞過(guò)來(lái)的變量,因此,將$賦值給jQuery,則讓jQuery重新有效。

如果需要對(duì)外提供接口,則在// 接口開(kāi)始后面使用對(duì)象屬性的方式,將接口賦值給ex。注意一點(diǎn),ex返回后,你不可以通過(guò)接口改變插件內(nèi)部的變量,這個(gè)接口是對(duì)外接口。

利用OMD開(kāi)發(fā)的步驟

1.在開(kāi)始開(kāi)發(fā)插件之前,將omd.js的代碼框架拷貝到你的項(xiàng)目(插件)文件中;

2.在注釋中對(duì)應(yīng)的位置開(kāi)始撰寫(xiě)你的腳步代碼

3.在注釋中指出接口輸出的位置處,通過(guò)ex.fun = function(){}的方式返回接口

4.完成代碼寫(xiě)作之后,利用JavaScript壓縮工具,凈化和壓縮你的Javascript代碼

OMD使用要點(diǎn)

和sea.js不同,require.js的所有模塊都是異步加載,這意味著你不能按照以往的方式,通過(guò)先加載哪個(gè)模塊,然后加載另外一個(gè)模塊來(lái)確定它們的依賴關(guān)系。不幸的是,所有的jquery插件都要依賴jquery庫(kù)。因此,在require中需要解決好這個(gè)依賴問(wèn)題。依賴的用法只有在define的參數(shù)中,前面已經(jīng)提到了define的幾種用法,我們來(lái)看下具體的實(shí)現(xiàn)方法:

define(["jquery"],function($){
    require(["plugin.omd.js"],function($plugin){
        $("#test").plugin();
        $plugin.p("#test");
    });
});

上面的代碼中,define(["jquery"])首先確定了這個(gè)模塊依賴于jquery,并將其返回接口以$作為變量。在這個(gè)基礎(chǔ)上,再去require(omd.js),則可以讓omd.js中的對(duì)jQuery的依賴可以實(shí)現(xiàn),omd.js中才可以正常使用jquery。

不過(guò),從require.js的設(shè)計(jì)上,模塊之間都是異步加載的,如果按照上述方法解決依賴問(wèn)題,性能上比sea.js要差很多。

我已經(jīng)將這個(gè)代碼放到github上,里面有demo,你可以看下plugin.js和main.js,來(lái)看看具體的用法。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/78597.html

相關(guān)文章

  • JavaScript」如何讓你的插件兼容CommonJS, AMD, CMD原生 JS

    摘要:模塊標(biāo)準(zhǔn)有三個(gè)全局變量和。模塊中有兩種方式提供對(duì)外的接口,一種是,一種是使用進(jìn)行返回。規(guī)范中,函數(shù)同樣有一個(gè)公有屬性。由于和都可以使用來(lái)定義對(duì)外接口,故可以合并成一句代碼。 模塊標(biāo)準(zhǔn) CommonJS CommonJS 有三個(gè)全局變量 module、exports 和 require。但是由于 AMD 也有 require 這個(gè)全局變量,故不使用這個(gè)變量來(lái)進(jìn)行檢測(cè)。 如果想要對(duì)外提供接...

    ShevaKuilin 評(píng)論0 收藏0
  • JavaScript塊化發(fā)展

    摘要:所有依賴這個(gè)模塊的語(yǔ)句,都定義在一個(gè)回調(diào)函數(shù)中,等到所有依賴加載完成之后前置依賴,這個(gè)回調(diào)函數(shù)才會(huì)運(yùn)行。如果將前面的代碼改寫(xiě)成形式,就是下面這樣定義了一個(gè)文件,該文件依賴模塊,當(dāng)模塊加載完畢之后執(zhí)行回調(diào)函數(shù),這里并沒(méi)有暴露任何變量。 模塊化是我們?nèi)粘i_(kāi)發(fā)都要用到的基本技能,使用簡(jiǎn)單且方便,但是很少人能說(shuō)出來(lái)但是的原因及發(fā)展過(guò)程?,F(xiàn)在通過(guò)對(duì)比不同時(shí)期的js的發(fā)展,將JavaScript模...

    mengbo 評(píng)論0 收藏0
  • 一覽js塊化:從CommonJS到ES6

    摘要:模塊化規(guī)范有的模塊系統(tǒng)。規(guī)范是服務(wù)器端模塊的規(guī)范,由推廣使用。對(duì)于依賴的模塊,是提前執(zhí)行,是延遲執(zhí)行。瀏覽器廠商和都宣布要原生支持該規(guī)范。它將逐漸取代和規(guī)范,成為瀏覽器和服務(wù)器通用的模塊解決方案。 本文由云+社區(qū)發(fā)表 模塊化是指把一個(gè)復(fù)雜的系統(tǒng)分解到一個(gè)一個(gè)的模塊。 模塊化開(kāi)發(fā)的優(yōu)點(diǎn): (1)代碼復(fù)用,讓我們更方便地進(jìn)行代碼管理、同時(shí)也便于后面代碼的修改和維護(hù)。 (2)一個(gè)單獨(dú)的文件就...

    antz 評(píng)論0 收藏0
  • 關(guān)于JavaScript模塊規(guī)范之CommonJSAMDCMD

    摘要:所有依賴這個(gè)模塊的語(yǔ)句,都定義在一個(gè)回調(diào)函數(shù)中,等到加載完成之后,這個(gè)回調(diào)函數(shù)才會(huì)運(yùn)行。也采用語(yǔ)句加載模塊,但是不同于,它要求兩個(gè)參數(shù)第一個(gè)參數(shù),是一個(gè)數(shù)組,里面的成員就是要加載的模塊第二個(gè)參數(shù),則是加載成功之后的回調(diào)函數(shù)。 本篇文章來(lái)自對(duì)文章《js模塊化編程之徹底弄懂CommonJS和AMD/CMD!》的總結(jié),大部分摘自文章原話,本人只是為了學(xué)習(xí)方便做的筆記,之后有新的體會(huì)會(huì)及時(shí)補(bǔ)充...

    binaryTree 評(píng)論0 收藏0
  • nodejs筆記-模塊機(jī)制

    摘要:模塊中定義的全局變量只作用于該文件內(nèi)部,不污染其他模塊。由純編寫(xiě)的部分稱為內(nèi)建模塊,例等模塊部分使用編寫(xiě)。兼容多種模塊規(guī)范檢測(cè)是否為或者檢測(cè)是否為或環(huán)境定義為普通模塊將模塊執(zhí)行結(jié)果掛載在對(duì)象下 1.為什么要CommonJS規(guī)范 javascript存在的缺點(diǎn) 沒(méi)有模塊系統(tǒng) 標(biāo)準(zhǔn)庫(kù)比較少 沒(méi)有標(biāo)準(zhǔn)接口 缺乏包管理系統(tǒng) CommonJS規(guī)范的提出,彌補(bǔ)了javascript沒(méi)有標(biāo)準(zhǔn)的缺...

    lscho 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<