天天看點

js應用子產品化

近來參與的一個GIS項目,類似黑闆系統。所有功能都往GIS上展示,是以不可能預先寫好全部的JS引用,而采用類似動态注冊的方式。我就應用了一回JS的AMD規範。

AMD規範最大的好處,我認為是解決了JS依賴的問題。這個JS檔案,需要依賴另一個JS檔案的内容。如果大家都在一個頁面上引用,當然沒有問題。但動态取舍的情況就不一樣了。

利用AMD規範能夠較好地解決這個問題。凡符合AMD規範,或者在裡面注冊的,都可以友善地動态引用。而不必預先聲明在頁面上。詳細步驟和注意事項如下:

一、注冊符合AMD規範或能應用AMD規範的的js檔案

js/modules.js,各路js注冊檔案,要能被别人引用,首先要在這裡注冊。一般命名為main.js,但這個不是固定的,像本例就命名為modules.js。

require.config({//require.config是require.js裡定義的,套路如此,知道就行
    baseUrl: "js",//咱們要使用的這些js檔案,從這個目錄開始算
    shim: {//非AMD規範JS檔案聲明,裡面這3個都不符合AMD規範。testObj,CanvasWindy都是函數名
        'test': {
            deps: [],
            exports: 'testObj'//函數名
        },
        'gWindy':{
            deps: [],
            exports: 'CanvasWindy'//函數名
        },
        'gCurrent':{
            deps: [],
            exports: 'CanvasWindy'//函數名
        }
    },
    paths: {//給每一個js檔案賦一個ID,注意"global/windy/Windy"等同于"global/windy/Windy.js",檔案字尾被省略了
        "gWindy": "global/windy/Windy",//這些檔案,根目錄是/js(對應上面的baseUrl: "js")
        "gCurrent": "global/windy/Current",
        "wind":"global/windy/wind",
        "current":"global/windy/currentLoader",
        "test": "testAMD"
});      
js應用子產品化
js/testAMD.js
var testObj = (function(){
  return {
    hi:function(){
      alert("Hello World!");
    }
  };
})();      

二、聲明require.js

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

require.js是AMD規範庫。data-main訓示注冊檔案是./js/modules.js。

注意,在頁面上放置這個require.js,很可能會引起沖突。require裡面,其實就定義了一個define函數。但現在許多js庫都有同名函數,極其容易引起沖突。怎麼辦呢?我用​

​<iframe>​

​來解決。将聲明require.js放置在一個相對比較幹淨,不會引起沖突的iframe裡,然後通過iframe引用它就行了。比如:

var require = window.top.require;
function wind(){
  require(['wind'],function(windjs){
    windjs.go(containerId,viewer,window,Cesium);
  });
}      

三、引用AMD規範js

var require = window.top.require;
function wind(){
  require(['wind'],function(windjs){//‘wind ’是一個ID,在modules.js裡定義了,參考上面例子
    windjs.go(containerId,viewer,window,Cesium);
  });
}      

附錄、一個符合AMD規範的js

js/global/windy/wind.js

define(['gWindy'],function(CanvasWindy){
    
    function go(containerId,viewer,window,Cesium) {
        var canvasId = "windycanvas";
        var windy = null,windycanvas=null;
        var document = window.document;
        
        ...
    }
    
    return {
        go:go
    };
});      

注意裡面有用到window,document這些對象的話,它們是相對require.js所在頁面而言的。在本例子中,require.js放置在了最外層的頁面(window.top),而使用AMD規範的JS如果想用本頁面對應的window這類對象的話,最好通過參數傳進去。

繼續閱讀