前端模块规范AMD/UMD/CommonJs
.babelrc文件中的:module設(shè)置為false,為什么會(huì)要設(shè)置成false?
解釋:使ES6模塊語(yǔ)法轉(zhuǎn)換到另一個(gè)模塊類(lèi)型(默認(rèn)啟用“commonjs”)。 設(shè)置為假則不變換模塊。或者傳入(“amd”、“umd”,“systemjs”、“commonjs”)。
什么是模塊?
Javascript的組件生態(tài)在最近幾年的發(fā)展很給力,我們的可選性更加廣泛了。這本是一件好事,但是當(dāng)多個(gè)第三方Javascript在一起混合使用的時(shí)候,我們可能會(huì)遇到一個(gè)很尷尬的問(wèn)題,那就是不是所有的組件都能在一起很愉快的玩耍的。
為了解決這個(gè)問(wèn)題,兩種競(jìng)爭(zhēng)關(guān)系的前端模塊規(guī)范(AMD和CommonJS)問(wèn)世了。他們規(guī)定開(kāi)發(fā)者們采用一種約定好的模式來(lái)寫(xiě)代碼,以避免污染整個(gè)生態(tài)系統(tǒng)。
AMD規(guī)范--通過(guò)define(['加載的模塊依賴','',''], 加載完依賴的回調(diào)函數(shù))
AMD規(guī)范,全稱”Asynchronous Module Definition”,稱為異步模塊加載規(guī)范。一般應(yīng)用在瀏覽器端。流行的瀏覽器端異步加載庫(kù)RequireJS(中文網(wǎng)站)實(shí)現(xiàn)的就是AMD規(guī)范。
下面是使用AMD規(guī)范定義一個(gè)名為foo模塊的方式,此模塊依賴jquery,
// filename: foo.js define(['jquery'], function ($) {// methodsfunction myFunc(){};// exposed public methodsreturn myFunc; });AMD講究的是前置執(zhí)行。稍微復(fù)雜的例子如下,foo模塊有多個(gè)依賴及方法暴漏,
// filename: foo.js define(['jquery', 'underscore'], function ($, _) {// methodsfunction a(){}; // private because it's not returned (see below)function b(){}; // public because it's returnedfunction c(){}; // public because it's returned// exposed public methodsreturn {b: b,c: c} });define是AMD規(guī)范用來(lái)聲明模塊的接口,示例中的第一個(gè)參數(shù)是一個(gè)數(shù)組,表示當(dāng)前模塊的依賴。第二個(gè)參數(shù)是一個(gè)回調(diào)函數(shù),表示此模塊的執(zhí)行體。只有當(dāng)依賴數(shù)組中的所有依賴模塊都是可用的時(shí),AMD模塊加載器(比如RequireJS)才會(huì)去執(zhí)行回調(diào)函數(shù)并返回此模塊的暴露接口。
注意,回調(diào)函數(shù)中參數(shù)的順序與依賴數(shù)組中的依賴順序一致。(即:jquery->$,underscore->_)
當(dāng)然,在這里我可以將回調(diào)函數(shù)的參數(shù)名稱改成任何我們想用的可用變量名,這并不會(huì)對(duì)模塊的聲明造成任何影響。
除此之外,你不能在模塊聲明的外部使用$或者_(dá),因?yàn)樗麄冎辉谀K的回調(diào)函數(shù)體中才有定義。
關(guān)于AMD規(guī)定聲明模塊的更多內(nèi)容,請(qǐng)參考這里。
CMD規(guī)范---通過(guò)require('加載依賴’)
CMD規(guī)范,全稱”Common Module Definition”,稱為通用模塊加載規(guī)范。一般也是用在瀏覽器端。瀏覽器端異步加載庫(kù)Sea.js實(shí)現(xiàn)的就是CMD規(guī)范。
下面是使用AMD規(guī)范定義一個(gè)名為foo模塊的方式,此模塊依賴jquery,
define(function (require, exports, module) {// load dependencevar $ = require('jquery');// methodsfunction myFunc(){};// exposed public methodsreturn myFunc; })CMD規(guī)范傾向依賴就近,稍微復(fù)雜一點(diǎn)例子
define(function (requie, exports, module) {// 依賴可以就近書(shū)寫(xiě)var a = require('./a');a.test();// ...// 軟依賴if (status) {var b = requie('./b');b.test();} });關(guān)于AMD和CMD的區(qū)別,可參考這篇文章,AMD/CMD與前端規(guī)范。
CommonJS規(guī)范---require('加載模塊')--module.exports?= 暴露的公共方法名稱
根據(jù)CommonJS規(guī)范,一個(gè)單獨(dú)的文件就是一個(gè)模塊。每一個(gè)模塊都是一個(gè)單獨(dú)的作用域,也就是說(shuō),在一個(gè)文件定義的變量(還包括函數(shù)和類(lèi)),都是私有的,對(duì)其他文件是不可見(jiàn)的。
如果你在Node.js平臺(tái)上寫(xiě)過(guò)東西,你應(yīng)該會(huì)比較熟悉CommonJS規(guī)范。與前面的AMD及CMD規(guī)范不一樣的是,CommonJS規(guī)范一般應(yīng)用于服務(wù)端(Node.js平臺(tái)),而且CommonJS加載模塊采用的是同步方式(這跟他適用的場(chǎng)景有關(guān)系)。同時(shí),得力于Browserify這樣的第三方工具,我們可以在瀏覽器端使用采用CommonJS規(guī)范的js文件。
下面是使用CommonJS規(guī)范聲明一個(gè)名為foo模塊的方式,同時(shí)依賴jquery模塊,
// filename: foo.js // dependencies var $ = require('jquery');// methods function myFunc(){};// exposed public method (single) module.exports = myFunc;稍微復(fù)雜一點(diǎn)的示例如下,擁有多個(gè)依賴以及拋出多個(gè)接口,
// filename: foo.js var $ = require('jquery'); var _ = require('underscore');// methods function a(){}; // private because it's omitted from module.exports (see below) function b(){}; // public because it's defined in module.exports function c(){}; // public because it's defined in module.exports// exposed public methods module.exports = {b: b,c: c };UMD規(guī)范--支持AMD和CommonJS規(guī)范
因?yàn)锳MD,CommonJS規(guī)范是兩種不一致的規(guī)范,雖然他們應(yīng)用的場(chǎng)景也不太一致,但是人們?nèi)匀皇瞧谕幸环N統(tǒng)一的規(guī)范來(lái)支持這兩種規(guī)范。于是,UMD(Universal Module Definition,稱之為通用模塊規(guī)范)規(guī)范誕生了。
客觀來(lái)說(shuō),這個(gè)UMD規(guī)范看起來(lái)的確沒(méi)有AMD和CommonJS規(guī)范簡(jiǎn)約。但是它支持AMD和CommonJS規(guī)范,同時(shí)還支持古老的全局模塊模式。
我們來(lái)看個(gè)示例,
(function (root, factory) {if (typeof define === 'function' && define.amd) {// AMDdefine(['jquery'], factory);} else if (typeof exports === 'object') {// Node, CommonJS-likemodule.exports = factory(require('jquery'));} else {// Browser globals (root is window)root.returnExports = factory(root.jQuery);} }(this, function ($) {// methodsfunction myFunc(){};// exposed public methodreturn myFunc; }));個(gè)人覺(jué)得UMD規(guī)范更像一個(gè)語(yǔ)法糖。應(yīng)用UMD規(guī)范的js文件其實(shí)就是一個(gè)立即執(zhí)行函數(shù)。函數(shù)有兩個(gè)參數(shù),第一個(gè)參數(shù)是當(dāng)前運(yùn)行時(shí)環(huán)境,第二個(gè)參數(shù)是模塊的定義體。在執(zhí)行UMD規(guī)范時(shí),會(huì)優(yōu)先判斷是當(dāng)前環(huán)境是否支持AMD環(huán)境,然后再檢驗(yàn)是否支持CommonJS環(huán)境,否則認(rèn)為當(dāng)前環(huán)境為瀏覽器環(huán)境(window)。當(dāng)然具體的判斷順序其實(shí)是可以調(diào)換的。
下面是一個(gè)更加復(fù)雜的示例,
(function (root, factory) {if (typeof define === 'function' && define.amd) {// AMDdefine(['jquery', 'underscore'], factory);} else if (typeof exports === 'object') {// Node, CommonJS-likemodule.exports = factory(require('jquery'), require('underscore'));} else {// Browser globals (root is window)root.returnExports = factory(root.jQuery, root._);} }(this, function ($, _) {// methodsfunction a(){}; // private because it's not returned (see below)function b(){}; // public because it's returnedfunction c(){}; // public because it's returned// exposed public methodsreturn {b: b,c: c} }));Tips: 如果你寫(xiě)了一個(gè)小工具庫(kù),你想讓它及支持AMD規(guī)范,又想讓他支持CommonJS規(guī)范,那么采用UMD規(guī)范對(duì)你的代碼進(jìn)行包裝吧,就像這樣。
轉(zhuǎn)載自:?前端模塊規(guī)范AMD/UMD/CommonJs - 綠色袋子 - 博客園
?
總結(jié)
以上是生活随笔為你收集整理的前端模块规范AMD/UMD/CommonJs的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 银行会倒闭吗,有可能会
- 下一篇: 如何炒股票入门知识 怎么炒股票的入门知识