require.js深入了解 require.js特性介紹
現(xiàn)在,Require.js是我最喜歡的Javascript編程方式。它可以使代碼化整為零,并易于管理。而Require.js Optimizer能幫助我們將一個(gè)較大的應(yīng)用分散成多個(gè)較小的應(yīng)用,并通過依賴串聯(lián)起來,最后在編譯打包時(shí)合并起來。這些原因促使我們使用require.js。
那么,讓我們來看看require.js有什么牛逼的特性吧!
與CommonJS兼容
AMD (異步模塊定義規(guī)范) 出現(xiàn)自CommonJS工作組。CommonJS旨在創(chuàng)造Javascript的生態(tài)系統(tǒng)。 CommonJS的一個(gè)重要部分是transport/c, 即AMD的前身,而require.js則是該規(guī)范的一個(gè)實(shí)現(xiàn)。
CommonJS模塊和AMD模塊的語法差異,主要由于AMD需要支持瀏覽器的異步特性。而CommonJS模塊則需要同步進(jìn)行,例如:
var someModule = require( "someModule" );
var anotherModule = require( "anotherModule" );
exports.asplode = function() {
someModule.doTehAwesome();
anotherModule.doMoarAwesome();
};
AMD模塊是異步加載模塊的,故而模塊定義需要一個(gè)數(shù)組作為第一個(gè)參數(shù),而模塊加載完畢后回調(diào)的函數(shù)作為第二個(gè)參數(shù)傳入。
define( [ "someModule"], function( someModule ) {
return {
asplode: function() {
someModule.doTehAwesome();
// 這將會(huì)異步執(zhí)行
require( [ "anotherModule" ], function( anotherModule ) {
anotherModule.doMoarAwesome();
});
}
};
});
然而,在require.js中AMD亦能兼容CommonJS語法。通過AMD的define函數(shù)包裝CommonJS模塊,你也可以再AMD中擁有一個(gè)CommonJS模塊,例如:
define(function( require, exports, module )
var someModule = require( "someModule" );
var anotherModule = require( "anotherModule" );
someModule.doTehAwesome();
anotherModule.doMoarAwesome();
exports.asplode = function() {
someModule.doTehAwesome();
anotherModule.doMoarAwesome();
};
});
實(shí)際上,require.js通過函數(shù).toString解釋回調(diào)函數(shù)的模塊內(nèi)容,找到其正確的依賴,將其變成一個(gè)通常的AMD模塊。需要注意,如果你使用這種方式編寫模塊,可能會(huì)發(fā)生與其他AMD加載器不兼容的情況,因?yàn)檫@違背了AMD規(guī)范,但它能很好的理解這種格式的寫法。
這里發(fā)生了什么,require.js實(shí)際上做了function.toString的回調(diào)函數(shù)解析模塊的內(nèi)容,找到正確的依賴,就像它,如果它是一個(gè)正常的AMD模塊。重要的是要注意,如果您選擇這樣寫模塊,他們將最有可能不兼容與其他AMD模塊裝載機(jī),因?yàn)檫@違背了AMD規(guī)范,但它是很好的了解這個(gè)格式存在!
CDN回退
另一個(gè)隱藏的require.js瑰寶是,其支持當(dāng)CDN加載不正確時(shí),回退加載本地相應(yīng)的庫(kù)。我們可以通過require.config達(dá)到這個(gè)目的:
requirejs.config({
paths: {
jquery: [
'//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js',
'lib/jquery'
]
}
});
沒有依賴?對(duì)象字面量?沒問題!
當(dāng)你寫一個(gè)沒有任何依賴的模塊,并且只是返回一個(gè)對(duì)象包含一些功能函數(shù),那么我們可以使用一種簡(jiǎn)單的語法:
define({
forceChoke: function() {
},
forceLighting: function() {
},
forceRun: function() {
}
});
很簡(jiǎn)單,也很有用,如果該模塊僅僅是功能的集合,或者只是一個(gè)數(shù)據(jù)包。
循環(huán)依賴
在一些情況中,我們可能需要模塊moduleA和moduleA中的函數(shù)需要依賴一些應(yīng)用。這就是循環(huán)依賴。
// js/app/moduleA.js
define( [ "require", "app/app"],
function( require, app ) {
return {
foo: function( title ) {
var app = require( "app/app" );
return app.something();
}
}
}
);
得到模塊的地址
如果你需要得到模塊的地址,你可以這么做……
var path = require.toUrl("./style.css");
BaseUrl
通常,在進(jìn)行的單元測(cè)試時(shí),你的源代碼可能放在類似src的文件夾里,同時(shí),可能你的測(cè)試放在類似tests的文件夾里。這可能比較難讓測(cè)試配置正確。
比如我們?cè)趖ests文件夾有一個(gè)index.html文件,并需要本地加載tests/spec/*.js。并假設(shè),所有源代碼在為src/js/*.js,并有一個(gè)main.js在該文件夾。
index.html中,不在加載require.js時(shí)設(shè)置data-main。
<script src="src/js/vendor/require.js"></script>
<script>
require( [ "../src/js/main.js" ], function() {
require.config({
baseUrl: "../src/js/"
});
require([
"./spec/test.spec.js",
"./spec/moar.spec.js"
], function() {
// start your test framework
});
});
</script>
你可以發(fā)現(xiàn)main.js被加載。然而由于沒有設(shè)置data-main,所欲我們需要制定一個(gè)baseUrl。而當(dāng)使用data-main時(shí),baseUrl會(huì)根據(jù)其設(shè)定的文件來自動(dòng)設(shè)置。
在這里,你可以看到main.js被載入。然而,由于它沒有加載數(shù)據(jù)主要腳本標(biāo)記,那么您必須指定一個(gè)base即可。當(dāng)數(shù)據(jù)主要是用于baseURL時(shí)從主文件中的位置推斷。通過自定義baseUrl我們可以很容易將測(cè)試代碼和應(yīng)用代碼分開存放。
JSONP
我們可以這樣處理JSONP終端:
require( [
"http://someapi.com/foo?callback=define"
], function (data) {
console.log(data);
});
對(duì)于非AMD庫(kù),使用shim來解決
在很多請(qǐng)款下,我們需要使用非AMD庫(kù)。例如Backbone和Underscore并未適應(yīng)AMD規(guī)范。而jQuery實(shí)際上只是將自己定義成一個(gè)名為jQuery全局變量,所以對(duì)于jQuery什么都不用做。
幸運(yùn)的是,我們可以使用shim配置來解決這一問題。
require.config({
paths: {
"backbone": "vendor/backbone",
"underscore": "vendor/underscore"
},
shim: {
"backbone": {
deps: [ "underscore" ],
exports: "Backbone"
},
"underscore": {
exports: "_"
}
}
});
- 第二次聊一聊JS require.js模塊化工具的基礎(chǔ)知識(shí)
- 第一次接觸JS require.js模塊化工具
- Javascript模塊化編程(三)require.js的用法及功能介紹
- require.js+vue開發(fā)微信上傳圖片組件
- require.js 加載 vue組件 r.js 合并壓縮的實(shí)例
- require.js配合插件text.js實(shí)現(xiàn)最簡(jiǎn)單的單頁(yè)應(yīng)用程序
- require.js的用法詳解
- AMD異步模塊定義介紹和Require.js中使用jQuery及jQuery插件的方法
- 淺析js的模塊化編寫 require.js
相關(guān)文章
組件庫(kù)Monmrepo架構(gòu)與開發(fā)調(diào)試環(huán)境構(gòu)建詳解
這篇文章主要為大家介紹了組件庫(kù)Monmrepo架構(gòu)與開發(fā)調(diào)試環(huán)境構(gòu)建詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10Three.js學(xué)習(xí)之正交投影照相機(jī)
本篇主要介紹照相機(jī)中的正交投影照相機(jī)。學(xué)習(xí)Three.js的小伙伴們可以參考學(xué)習(xí)。2016-08-08Three.js學(xué)習(xí)之Lamber材質(zhì)和Phong材質(zhì)
本篇將介紹基本材質(zhì)以及兩種基于光照模型的材質(zhì)(Lamber與Phong),有需要的小伙伴們可以參考學(xué)習(xí)。2016-08-08js類庫(kù)styled-components快速入門教程
這篇文章主要為大家介紹了js類庫(kù)styled-components快速入門的教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06