• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            xiaoguozi's Blog
            Pay it forword - 我并不覺的自豪,我所嘗試的事情都失敗了······習慣原本生活的人不容易改變,就算現(xiàn)狀很糟,他們也很難改變,在過程中,他們還是放棄了······他們一放棄,大家就都是輸家······讓愛傳出去,很困難,也無法預料,人們需要更細心的觀察別人,要隨時注意才能保護別人,因為他們未必知道自己要什么·····

            JavaSript模塊化


                在了解AMD,CMD規(guī)范前,還是需要先來簡單地了解下什么是模塊化,模塊化開發(fā)?
                模塊化是指在解決某一個復雜問題或者一系列的雜糅問題時,依照一種分類的思維把問題進行系統(tǒng)性的分解以之處理。模塊化是一種處理復雜系統(tǒng)分解為代碼結構更合理,可維護性更高的可管理的模塊的方式。可以想象一個巨大的系統(tǒng)代碼,被整合優(yōu)化分割成邏輯性很強的模塊時,對于軟件是一種何等意義的存在。對于軟件行業(yè)來說:解耦軟件系統(tǒng)的復雜性,使得不管多么大的系統(tǒng),也可以將管理,開發(fā),維護變得“有理可循”。
                還有一些對于模塊化一些專業(yè)的定義為:模塊化是軟件系統(tǒng)的屬性,這個系統(tǒng)被分解為一組高內聚,低耦合的模塊。那么在理想狀態(tài)下我們只需要完成自己部分的核心業(yè)務邏輯代碼,其他方面的依賴可以通過直接加載被人已經寫好模塊進行使用即可。
            首先,既然是模塊化設計,那么作為一個模塊化系統(tǒng)所必須的能力:
                1. 定義封裝的模塊。
                2. 定義新模塊對其他模塊的依賴。
                3. 可對其他模塊的引入支持。
                好了,思想有了,那么總要有點什么來建立一個模塊化的規(guī)范制度吧,不然各式各樣的模塊加載方式只會將局攪得更為混亂。那么在JavaScript中出現(xiàn)了一些非傳統(tǒng)模塊開發(fā)方式的規(guī)范 CommonJS的模塊規(guī)范,AMD(Asynchronous Module Definition),CMD(Common Module Definition)等。



            AMD 與 RequireJS

            AMD

                Asynchronous Module Definition,用白話文講就是 異步模塊定義,對于 JSer 來說,異步是再也熟悉不過的詞了,所有的模塊將被異步加載,模塊加載不影響后面語句運行。所有依賴某些模塊的語句均放置在回調函數(shù)中。
                AMD規(guī)范定義了一個自由變量或者說是全局變量 define 的函數(shù)。

                define( id?, dependencies?, factory );    

                AMD規(guī)范  https://github.com/amdjs/amdjs-api/wiki/AMD
                第一個參數(shù) id 為字符串類型,表示了模塊標識,為可選參數(shù)。若不存在則模塊標識應該默認定義為在加載器中被請求腳本的標識。如果存在,那么模塊標識必須為頂層的或者一個絕對的標識。
                第二個參數(shù),dependencies ,是一個當前模塊依賴的,已被模塊定義的模塊標識的數(shù)組字面量。
                第三個參數(shù),factory,是一個需要進行實例化的函數(shù)或者一個對象。
                創(chuàng)建模塊標識為 alpha 的模塊,依賴于 require, export,和標識為 beta 的模塊  

            1. define("alpha", [ "require", "exports", "beta" ], function( require, exports, beta ){
            2.     export.verb = function(){
            3.         return beta.verb();
            4.         // or:
            5.         return require("beta").verb();
            6.     }
            7. });

                一個返回對象字面量的異步模塊

            1. define(["alpha"], function( alpha ){
            2.     return {
            3.         verb : function(){
            4.             return alpha.verb() + 1 ;
            5.         }
            6.     }
            7. });

                無依賴模塊可以直接使用對象字面量來定義

            1. define( {
            2.     add : function( x, y ){
            3.         return x + y ;
            4.     }
            5. } );

                類似與 CommonJS 方式定義

            1. define( function( require, exports, module){
            2.     var a = require('a'),
            3.           b = require('b');

            4.     exports.action = function(){};
            5. } );

                require();  

                require API 介紹 https://github.com/amdjs/amdjs-api/wiki/require
                在 AMD 規(guī)范中的 require 函數(shù)與一般的 CommonJS中的 require 不同。由于動態(tài)檢測依賴關系使加載異步,對于基于回調的 require 需求強烈。

                局部 與 全局 的require

                局部的 require 需要在AMD模式中的 define 工廠函數(shù)中傳入 require。

            1. define( ['require'], function( require ){
            2.   // ...
            3. } );
            4. or:
            5. define( function( require, exports, module ){
            6.   // ...
            7. } );

                局部的 require 需要其他特定的 API 來實現(xiàn)。
                全局的 require 函數(shù)是唯一全局作用域下的變量,像 define一樣。全局的 require 并不是規(guī)范要求的,但是如果實現(xiàn)全局的 require函數(shù),那么其需要具有與局部 require 函數(shù) 一樣的以下的限定:
                1. 模塊標識視為絕對的,而不是相對的對應另一個模塊標識。
                2. 只有在異步情況下,require的回調方式才被用來作為交互操作使用。因為他不可能在同步的情況下通過 require(String) 從頂層加載模塊。
                依賴相關的API會開始模塊加載。如果需要有互操作的多個加載器,那么全局的 reqiure 應該被加載頂層模塊來代替。

            1. require(String)
            2. define( function( require ){
            3.     var a = require('a'); // 加載模塊a
            4. } );

            5. require(Array, Function)
            6. define( function( require ){
            7.     require( ['a', 'b'], function( a,){ // 加載模塊a b 使用
            8.         // 依賴 a b 模塊的運行代碼
            9.     } ); 
            10. } );

            11. require.toUrl( Url )
            12. define( function( require ){
            13.     var temp = require.toUrl('./temp/a.html'); // 加載頁面
            14. } );

                amdjs 的API   https://github.com/amdjs/amdjs-api/wiki

            RequireJS

                官網 http://www.requirejs.org/
                API http://www.requirejs.org/docs/api.html
                RequireJS 是一個前端的模塊化管理的工具庫,遵循AMD規(guī)范,它的作者就是AMD規(guī)范的創(chuàng)始人 James Burke。所以說RequireJS是對AMD規(guī)范的闡述一點也不為過。
                RequireJS 的基本思想為:通過一個函數(shù)來將所有所需要的或者說所依賴的模塊實現(xiàn)裝載進來,然后返回一個新的函數(shù)(模塊),我們所有的關于新模塊的業(yè)務代碼都在這個函數(shù)內部操作,其內部也可無限制的使用已經加載進來的以來的模塊。

            1. <script data-main='scripts/main' src='scripts/require.js'></script>
                那么scripts下的main.js則是指定的主代碼腳本文件,所有的依賴模塊代碼文件都將從該文件開始異步加載進入執(zhí)行。
                defined用于定義模塊,RequireJS要求每個模塊均放在獨立的文件之中。按照是否有依賴其他模塊的情況分為獨立模塊和非獨立模塊。
                1. 獨立模塊,不依賴其他模塊。直接定義:

            1. define({
            2.     method1: function(){},
            3.     method2: function(){}
            4. });
                也等價于

            1. define(function(){
            2.     return{
            3.         method1: function(){},
            4.         method2: function(){}
            5.     }
            6. });
                2. 非獨立模塊,對其他模塊有依賴。

            1. define([ 'module1', 'module2' ], function(m1, m2){
            2.     ...
            3. });
                或者:

            1. define( function( require ){
            2.     var m1 = require( 'module1' ),
            3.           m2 = require( 'module2' );
            4.     ...
            5. });

                簡單看了一下RequireJS的實現(xiàn)方式,其 require 實現(xiàn)只不過是將 function 字符串然后提取 require 之后的模塊名,將其放入依賴關系之中。
                require方法調用模塊
                在require進行調用模塊時,其參數(shù)與define類似。

            1. require( ['foo', 'bar'], function( foo, bar ){
            2.     foo.func();
            3.     bar.func();
            4. } );
                在加載 foo 與 bar 兩個模塊之后執(zhí)行回調函數(shù)實現(xiàn)具體過程。
                當然還可以如之前的例子中的,在define定義模塊內部進行require調用模塊

            1. define( function( require ){
            2.     var m1 = require( 'module1' ),
            3.           m2 = require( 'module2' );
            4.     ...
            5. });
                define 和 require 這兩個定義模塊,調用模塊的方法合稱為AMD模式,定義模塊清晰,不會污染全局變量,清楚的顯示依賴關系。AMD模式可以用于瀏覽器環(huán)境并且允許非同步加載模塊,也可以按需動態(tài)加載模塊。

            CMD 與 seaJS

            CMD

                在CMD中,一個模塊就是一個文件,格式為:
                define( factory );
                全局函數(shù)define,用來定義模塊。
                參數(shù) factory  可以是一個函數(shù),也可以為對象或者字符串。
                當 factory 為對象、字符串時,表示模塊的接口就是該對象、字符串。
                定義JSON數(shù)據(jù)模塊:
            1. define({ "foo": "bar" });
                通過字符串定義模板模塊:

            1. define('this is {{data}}.');
                factory 為函數(shù)的時候,表示模塊的構造方法,執(zhí)行構造方法便可以得到模塊向外提供的接口。

            1. define( function(require, exports, module) { 
            2.     // 模塊代碼
            3. });

                define( id?, deps?, factory );
                define也可以接受兩個以上的參數(shù),字符串id為模塊標識,數(shù)組deps為模塊依賴:

            1. define( 'module', ['module1', 'module2'], function( require, exports, module ){
            2.     // 模塊代碼
            3. } );
                其與 AMD 規(guī)范用法不同。
                require 是 factory 的第一個參數(shù)。
                require( id );
                接受模塊標識作為唯一的參數(shù),用來獲取其他模塊提供的接口:

            1. define(function( require, exports ){
            2.     var a = require('./a');
            3.     a.doSomething();
            4. });
                require.async( id, callback? );
                require是同步往下執(zhí)行的,需要的異步加載模塊可以使用 require.async 來進行加載:

            1. define( function(require, exports, module) { 
            2.     require.async('.a', function(a){
            3.         a.doSomething();
            4.     });
            5. });
                require.resolve( id )
                可以使用模塊內部的路徑機制來返回模塊路徑,不會加載模塊。
                exports 是 factory 的第二個參數(shù),用來向外提供模塊接口。

            1. define(function( require, exports ){
            2.     exports.foo = 'bar'; // 向外提供的屬性
            3.     exports.do = function(){}; // 向外提供的方法
            4. });
                當然也可以使用 return 直接向外提供接口。

            1. define(function( require, exports ){
            2.     return{
            3.         foo : 'bar', // 向外提供的屬性
            4.         do : function(){} // 向外提供的方法
            5.     }
            6. });
                也可以簡化為直接對象字面量的形式:

            1. define({
            2.     foo : 'bar', // 向外提供的屬性
            3.     do : function(){} // 向外提供的方法
            4. });

                與nodeJS中一樣需要注意的是,一下方式是錯誤的:

            1. define(function( require, exports ){
            2.     exports = {
            3.         foo : 'bar', // 向外提供的屬性
            4.         do : function(){} // 向外提供的方法
            5.     }
            6. });

                需要這么做

            1. define(function( require, exports, module ){
            2.     module.exports = {
            3.         foo : 'bar', // 向外提供的屬性
            4.         do : function(){} // 向外提供的方法
            5.     }
            6. });
                傳入的對象引用可以添加屬性,一旦賦值一個新的對象,那么值錢傳遞進來的對象引用就會失效了。開始之初,exports 是作為 module.exports 的一個引用存在,一切行為只有在這個引用上 factory 才得以正常運行,賦值新的對象后就會斷開引用,exports就只是一個新的對象引用,對于factory來說毫無意義,就會出錯。
                module 是factory的第三個參數(shù),為一個對象,上面存儲了一些與當前模塊相關聯(lián)的屬性與方法。
                    module.id 為模塊的唯一標識。
                    module.uri 根據(jù)模塊系統(tǒng)的路徑解析規(guī)則得到模塊的絕對路徑。
                    module.dependencies 表示模塊的依賴。
                    module.exports 當前模塊對外提供的接口。

            seaJS

                官網 http://seajs.org/docs/
                API快速參考 https://github.com/seajs/seajs/issues/266
                sea.js 核心特征:
                    1. 遵循CMD規(guī)范,與NodeJS般的書寫模塊代碼。
                    2. 依賴自動加載,配置清晰簡潔。
                兼容 Chrome 3+,F(xiàn)irefox 2+,Safari 3.2+,Opera 10+,IE 5.5+。
                seajs.use 
                用來在頁面中加載一個或者多個模塊

            1. // 加載一個模塊 
            2. seajs.use('./a');
            3. // 加載模塊,加載完成時執(zhí)行回調
            4. seajs.use('./a',function(a){
            5.     a.doSomething();
            6. });
            7. // 加載多個模塊執(zhí)行回調
            8. seajs.use(['./a','./b'],function(, b){
            9.     a.doSomething();
            10.     b.doSomething();
            11. });
                其define 與 require 使用方式基本就是CMD規(guī)范中的示例。


            AMD 與 CMD 區(qū)別到底在哪里?


                看了以上 AMD,requireJS 與 CMD, seaJS的簡單介紹會有點感覺模糊,總感覺較為相似。因為像 requireJS 其并不是只是純粹的AMD固有思想,其也是有CMD規(guī)范的思想,只不過是推薦 AMD規(guī)范方式而已, seaJS也是一樣。
                下面是玉伯對于 AMD 與 CMD 區(qū)別的解釋:
                AMD 是 RequireJS 在推廣過程中對模塊定義的規(guī)范化產出。
                CMD 是 SeaJS 在推廣過程中對模塊定義的規(guī)范化產出。
                類似的還有 CommonJS Modules/2.0 規(guī)范,是 BravoJS 在推廣過程中對模塊定義的規(guī)范化產出還有不少??
                這些規(guī)范的目的都是為了 JavaScript 的模塊化開發(fā),特別是在瀏覽器端的。
                目前這些規(guī)范的實現(xiàn)都能達成瀏覽器端模塊化開發(fā)的目的。
                區(qū)別:
                1. 對于依賴的模塊,AMD 是提前執(zhí)行,CMD 是延遲執(zhí)行。不過 RequireJS 從 2.0 開始,也改成可以延遲執(zhí)行(根據(jù)寫法不同,處理方式不同)。CMD 推崇 as lazy as possible.
                2. CMD 推崇依賴就近,AMD 推崇依賴前置。看代碼:

            1. // CMD
            2. define(function(require, exports, module) {
            3.     var a = require('./a')
            4.     a.doSomething()
            5.     // 此處略去 100 行
            6.     var b = require('./b') // 依賴可以就近書寫
            7.     b.doSomething()
            8.     // ...
            9. })

            10. // AMD 默認推薦的是
            11. define(['./a', './b'], function(a, b) { // 依賴必須一開始就寫好
            12.     a.doSomething()
            13.     // 此處略去 100 行
            14.     b.doSomething()
            15.     // ...
            16. })
            雖然 AMD 也支持 CMD 的寫法,同時還支持將 require 作為依賴項傳遞,但 RequireJS 的作者默認是最喜歡上面的寫法,也是官方文檔里默認的模塊定義寫法。
                3. AMD 的 API 默認是一個當多個用,CMD 的 API 嚴格區(qū)分,推崇職責單一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,沒有全局 require,而是根據(jù)模塊系統(tǒng)的完備性,提供 seajs.use 來實現(xiàn)模塊系統(tǒng)的加載啟動。CMD 里,每個 API 都簡單純粹。
                4. 還有一些細節(jié)差異,具體看這個規(guī)范的定義就好,就不多說了。
            另外,SeaJS 和 RequireJS 的差異,可以參考:https://github.com/seajs/seajs/issues/277

            總結

                本文主要是介紹了一下 AMD CMD的規(guī)范,順便簡單的講述了一下 requireJS 與 seaJS。講的較為籠統(tǒng),下面的擴展閱讀可以更好的幫助你理解模塊化以及各個規(guī)范。
            擴展閱讀:
            AMD規(guī)范文檔 https://github.com/amdjs/amdjs-api/wiki/AMD
            amdjs 的 require 接口文檔 https://github.com/amdjs/amdjs-api/wiki/require
            amdjs 的接口文檔 https://github.com/amdjs/amdjs-api/wiki
            RequireJS官網接口文檔  http://www.requirejs.org/docs/api.html 
            模塊系統(tǒng) https://github.com/seajs/seajs/issues/240
            前端模塊化開發(fā)的價值 https://github.com/seajs/seajs/issues/547
            前端模塊化開發(fā)那點歷史 https://github.com/seajs/seajs/issues/588
            CMD 模塊定義規(guī)范 https://github.com/seajs/seajs/issues/242
            SeaJS API快速參考 https://github.com/seajs/seajs/issues/266
            從 CommonJS 到 Sea.js https://github.com/seajs/seajs/issues/269    

            RequireJS和AMD規(guī)范  http://javascript.ruanyifeng.com/tool/requirejs.html 
            CommonJS規(guī)范  http://javascript.ruanyifeng.com/nodejs/commonjs.html
            Javascript模塊化編程 http://www.ruanyifeng.com/blog/2012/10/javascript_module.html
            Javascript模塊化編程 http://www.ruanyifeng.com/blog/2012/10/asynchronous_module_definition.html

            知乎  AMD 和 CMD 的區(qū)別有哪些? http://www.zhihu.com/question/20351507 
            JavaScript模塊化開發(fā) - CommonJS規(guī)范 http://www.feeldesignstudio.com/2013/09/javascript-module-pattern-commonjs 
            JavaScript模塊化開發(fā) - AMD規(guī)范 http://www.feeldesignstudio.com/2013/09/javascript-module-pattern-amd

            模塊化設計 http://baike.baidu.com/view/189730.htm 
            模塊化  http://baike.baidu.com/view/182267.htm 
            posted on 2014-09-10 18:09 小果子 閱讀(2138) 評論(0)  編輯 收藏 引用
            精品久久一区二区| 日韩欧美亚洲综合久久影院Ds| 色老头网站久久网| 久久夜色精品国产噜噜亚洲a | 久久亚洲国产中v天仙www| 91精品观看91久久久久久 | 国产Av激情久久无码天堂| 久久99热国产这有精品| 精品久久久久久99人妻| 久久这里只有精品视频99| 久久精品中文无码资源站| 精品人妻久久久久久888| 999久久久国产精品| 伊人热热久久原色播放www| 久久不见久久见免费视频7| 成人a毛片久久免费播放| 精品久久久久成人码免费动漫| 久久99精品国产自在现线小黄鸭 | 久久精品综合一区二区三区| 久久无码国产专区精品| 国内精品久久久久影院日本| 93精91精品国产综合久久香蕉| 2021国内精品久久久久久影院| 国产亚洲色婷婷久久99精品| 欧美国产成人久久精品| 2022年国产精品久久久久| 麻豆国内精品久久久久久| 国产精品久久久久久福利69堂| 亚洲欧洲精品成人久久曰影片| 久久国产精品久久| 国产成人无码精品久久久性色 | 久久影院久久香蕉国产线看观看| 亚洲欧美日韩中文久久| 93精91精品国产综合久久香蕉| 99久久精品免费看国产一区二区三区 | 伊人久久大香线蕉精品| 亚洲精品tv久久久久久久久 | 久久久99精品一区二区| 久久精品国产亚洲AV香蕉| 久久人人爽人人爽人人片AV高清| 超级碰久久免费公开视频|