js模塊化AMD、CMD、ES6

  • AMD
  • CMD
  • ES6模塊化
  • 各個模塊化規範對比理解

 1、AMD

在上一篇js模塊化入門與commonjs解析與應用中詳細的解析了關於commonjs模塊化規範,commonjs採用的用同步加載方式,這致使它並非瀏覽器理想的模塊化規範。由於瀏覽器須要到服務器加載文件,請求事件遠遠大於本機讀取的時間,若是文件較多,網絡遲緩就會致使頁面癱瘓,因此瀏覽器更但願可以實現異步加載的方式。css

AMD規範則是異步加載模塊,用於指定回調函數。等模塊加載完成之後便可調用回調函數。AMD規範得意的產出就是require.js。html

https://requirejs.org/node

先經過示例來感覺如下AMD規範實現的requirejs的應用:jquery

1.1定義工做區間文件結構webpack

1 cmd//工做區間
2     modules-->依賴模塊
3         m1.js-->模塊1
4         m2.js-->模塊2
5     demo.html-->結構文本
6     demo.js-->js主入口文件
7     require.js-->CMD模塊化工具

1.2.1依賴模塊代碼(m1):web

1 define(function (){
2    var name = 'm1-amd';
3    function getName(){
4        return name;
5      }
6      return {getName};//{getName}同等與{getName:getName} 
7 })

1.2.2依賴模塊代碼(m2):api

1 define(['m1'],function(m1){
2     var msg = 'm2-amd';
3     function show(){
4         console.log(msg,m1.getName());
5     }
6     return {show};
7 })

1.3JS主入口文件:數組

 1 (function (){
 2     require.config({
 3         paths:{
 4             m2:'./modules/m2',
 5             m1:'./modules/m1'
 6         }
 7     });
 8     require(['m2','jquery'],function(m2,$){
 9         m2.show();
10     });
11 })();

1.4在結構文本中引入AMD規範模塊化處理工具require.js,並將主入口文件經過自定義屬性data-main='主入口文件路徑'的方式引入工具中進行處理:瀏覽器

<script src="./require.js" data-main="./demo.js"></script>

AMD的基本規範的全稱「Asynchronous Module Definition」的縮寫,意思是「異步加載模塊」。它採用異步方式加載模塊,模塊的加載不影響後面語句的運行。全部依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成後,這個回調函數纔會運行。服務器

 

AMD規範其實是requirejs項目在推廣過程當中造成的一個產物,先來看看requirejs的基本使用:

  requirejs模塊定義:define(id?,dependencies?,factory);==>id:可選參數,用來定義模塊的標識,若是沒有提供該參數,模塊標識就取腳本文件名(去掉擴展名)。==>dependencies:用來傳入當前模塊依賴的模塊名稱數組。==>factory:工廠方法,模塊初始化要執行的函數或對象,若是是函數,它只被執行一次。若是是對象,此對象應該爲模塊的輸出值。

  requirejs模塊主入口(模塊加載):require.config({paths:{foo:'路徑'}});==>faths:配置全部依賴模塊的路徑。在路徑配置代碼的下方,再經過require(dependencies?,factory)定義主入口文件的依賴關係和回調函數。

 

在requirejs中還能夠實現依賴其餘庫和插件,有些插件和庫定義了requirejs的標準接口,好比jQuery,可是有些沒有標準接口,requirejs官方都給出解決方案,能夠參考這篇博客:http://www.javashuo.com/article/p-wgendvdq-dh.html。例如我在示例中也測試了jQuery的使用:

 1 (function (){
 2     require.config({
 3         paths:{
 4             m2:'./modules/m2',
 5             m1:'./modules/m1',
 6             jquery:'./jquery-2.0.3'
 7         }
 8     });
 9     require(['m2','jquery'],function(m2,$){
10         m2.show();
11         $('body').css('backgroundColor','#000');
12     });
13 })();

關於requirejs更多API能夠查看官網的API示例:https://requirejs.org/docs/api.html

 2、CMD

 在上面一節介紹了AMD規範以及規範實現的requirejs的基本使用,其中提到了AMD相對於Commonjs的優點在於異步加載模塊,可是我沒由說明這個異步加載在何時觸發,到了CMD這裏有必要提一下了,AMD規範很重要的一個思想就是依賴前置,意思就是在模塊執行前將全部依賴的模塊先所有加載到本地。而CMD的加載方式也是異步加載,可是觸發加載的時間是在須要某個依賴模塊時再去加載,也有人將CMD說成是同步的,這種同步並非表如今資源加載上,而是觸發加載的指令與代碼執行是同步的,資源加載仍是異步加載模式。

關於Commonjs、AMD、CMD、ES6模塊化的異同在最後會由詳細的對比分析。

 

2.1.先來看CMD的基本應用:https://www.zhangxinxu.com/sp/seajs/

2.1.1.定義工做區間文件結構

CMD//工做區間
    -->modules//依賴模塊
        -->m1.js
        -->m2.js
        -->m3.js
        -->m4.js
    dome.html//結構文本
    demo.js//JS主入入口文件
    sea.js//模塊化工具

2.1.2.m1模塊代碼

1 define(function(require,exports,module){
2     var msg = 'm1';
3     function foo(){
4         console.log(msg);
5     }
6     module.exports = {
7         foo:foo
8     }
9 })

2.1.3.m2模塊代碼

1 define(function(require,exports,module){
2     var msg = 'm2';
3     function bar(){
4         console.log(msg);
5     }
6     module.exports = bar;
7 })

2.1.4.m3模塊代碼

1 define(function(require,exports,module){
2     var msg = 'm3';
3     function foo(){
4         console.log(msg);
5     }
6     exports.foo = foo;
7 })

2.1.5.m4模塊代碼

 1 define(function(require,exports,module){
 2     var msg = 'm4';
 3     // 同步加載
 4     var m2 = require('./m2');
 5     m2();
 6     // 異步加載
 7     require.async('./m3',function(m3){
 8         m3.foo();
 9     });
10     function fun(){
11         console.log(msg);
12     }
13     exports.fun = fun;
14 })

2.1.6.JS主入口文件demo代碼

1 define(function(require,exports,module){
2     var m1 = require('./modules/m1');
3     m1.foo();
4     var m4 = require('./modules/m4');
5     m4.fun();
6 })

2.1.7.結構文本demo.html引入模塊化處理工具sea.js,使用seajs工具對象方法user找到主入口文件並解析執行==>seajs.use('主入口文件路徑'):

1 <script src="./sea.js"></script>
2 <script>
3     seajs.use('./demo.js');
4 </script>

最後代碼打印結果:

這裏值得咱們關注的是m4打印在m3的前面,這就是CMD依賴就近原則產生的,在執行隊列中異步請求須要等主線程執行完成之後纔會調用執行,因此m3做爲異步加載模塊,在這個代碼結構中要最後執行。

值得咱們注意的seajs也有同步加載模式直接使用require('模塊路徑')獲取模塊,異步模塊加載方式須要使用require.async('模塊路徑',function(模塊名稱){回調執行內容})。

 3、ES6模塊化

 ES6自帶模塊化,可使用import關鍵字引入模塊,經過export關鍵字處處模塊,功能較以前幾個方案更爲強大,可是因爲ES6目前沒法在瀏覽器中執行,因此,須要經過babel將不支持的import編譯爲當前收到普遍支持的require。

 1 //  引入默認變量及方法和模塊導入的m1 m2變量或方法
 2 import theDefault,{m1,m2} from 'lib';
 3 //  引入默認變量及方法
 4 import theDefault from 'lib';
 5 //  引入模塊導出的m1 m2變量或方法
 6 import {m1,m2} from 'lib';
 7 //  引入模塊導出的m1而且將m1重命名myName m2變量或者方法
 8 import * as myLib from 'lib';
 9 // 只將lib加載進來 沒有用來lib中暴露的接口
10 import 'lib';
11 
12 
13 //  暴露變量
14 export var a = '123';
15 //  暴露函數
16 export function myFun(){
17 
18 }
19 //  默認暴露變量函數等
20 export default a = '123';
21 export function myFun(){}

關於ES6的模塊化會在ES6的相關博客中來詳細解析,這裏只作一些基本介紹。

 4、各個模塊化規範對比理解

1.什麼是模塊化?

答:模塊化是指將一個複雜的系統分解爲多個模塊,方便編碼。

2.爲何要用模塊化?

答:下降複雜性,下降代碼耦合度,部署方便,提升效率。

3.模塊化的好處?

答:3.1.避免命名衝突,減小變量空間污染;

  3.2.更好的分離代碼,按序加載;

  3.3.更高複用性;

  3.4.更高可維護性;

4.Webpack支持性:

AMD、ES Modules(推薦使用)、CommonJS由於webpack是基於nodeJS的,因此有必要了解學習。

 

5.AMD、CMD、CommonJS模塊規範的對比分析:

  AMD、CMD可使用插件引入的方式實現JS代碼模塊化管理,CommonJS不兼容瀏覽器須要Browserify工具在nodejs環境下轉換成瀏覽器可執行的JS文件。

  Commonjs採用同步加載,會在必定程度上增長頁面載入時間,若是在這個過程當中出現某個模塊錯誤,會致使頁面加載失敗。

  AMD、CMD採用異步加載,二者的區別就是AMD採用前置預加載模式,CMD採用就近原則加載模式。AMD的體驗更好,CMD的性能更優,可是CMD須要考慮異步隊列的執行順序問題,因此這裏的更好和更優要相對而言。

  (後續深刻研究後再來補充)

相關文章
相關標籤/搜索