天天看点

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这类对象的话,最好通过参数传进去。

继续阅读