模块框架
随着互联网的飞速发展,前端开发越来越复杂,导致开发经常出现两个问题:
- 恼人的命名冲突
- 烦琐的文件依赖
针对这两个问题,可以使用js模块化技术来解决。当前主流的js模块化有两大规范CMD(Seajs)和AMD规范(RequireJS)。WeX5采用RequireJS(AMD规范)来实现,关于RequireJS的详细说明参考:http://www.requirejs.org/
接下来我们介绍在WeX5中,如何使用模块化?
2.3.1 定义模块
在WeX5中,定义模块时需要符合以下规则:
- 一个文件定义一个模块;
- 所有模块都定义为匿名模块,按模块路径的方式引用,例如“$UI/system/lib/justep”表示“/UI2/system/lib/justep.js”文件;
在WeX5中,最常用的是一个模块定义一个js类,例如:
define(function(require){ var $ = require("jquery"); var justep = require("$UI/system/lib/justep"); var Model = function(){ this.callParent(); }; return Model; });
如上所示,这个模块定义了一个js类Model。
关于定义模块的详细说明请参考:http://www.requirejs.org/docs/api.html
2.3.2 引用模块
根据不同的模块类型,使用不同的引用方式,以下将介绍js模块、css模块、text模块和资源模块的引用方式。
引用js模块
在WeX5中,有两种方式引用js模块:
- require(‘模块路径’)
先加载被引用的模块,再加载当前模块;
- require( [‘文件路径’], successCallback, errorCallback)
当执行到require语句时,才异步加载指定的模块;指定的模块加载成功后,执行successCallback,如果加载失败则执行errorCallback。
js模块引用方式 | require(‘模块路径’) | require([‘文件路径’], successCallback, errorCallback) |
模块加载时机 | 先加载被引用的载,再加载当前模块; | 执行到require语句时,才异步加载指定的js文件; |
模块路径 | 绝对路径: http或https开头的; 相对路径:$UI开头(相对UI根目录); “.”或“..”开头(相对当前文件); | 绝对路径: http或https开头的; 相对路径:$UI开头(相对UI根目录); “.”或“..”开头(相对当前文件); |
模块路径是否支持变量 | 不支持 | 支持 |
相对路径是否需要扩展名 | 不需要 | 需要 |
我们来看看在WeX5中,如何实现:
1、 如何引用符合AMD规范的js模块?
2、 如何引用不符合AMD规范的js模块?
在WeX5版本中,自带了一个引用js模块的案例(/UI2/demo/misc/importJs),目录结构如下:
图2-14 引用js模块
1、如何引用符合AMD规范的js模块?
方式一:require(‘模块路径’)
例如,在/UI2/demo/misc/importJs/importJs.js文件中:
// 加载UI2下, 符合AMD规范的文件 var amd1 = require("./AMD1"); // 加载外网, 符合AMD规范的文件 var outterAMD1 = require("http://wex5.com/cn/wp-content/uploads/2015/04/outterAMD1.js");
通过以上代码,引用/UI2/demo/misc/importJs/AMD1.js和http://wex5.com/cn/wp-content/uploads/2015/04/outterAMD1.js模块,在当前模块的后续代码中,可以通过变量amd1和outterAMD1调用被引用js模块中的方法。
方式二:require([‘文件路径’], successCallback, errorCallback)
例如,在/UI2/demo/misc/importJs/importJs.js文件中:
Model.prototype.importInnerBtnClick = function(event){ // 加载UI2下, 符合AMD规范的文件 var path = "./AMD2"; require([path], function(m){ m.fnOfAMD2(); }); }; Model.prototype.importOutterBtnClick = function(event){ // 加载外网, 符合AMD规范的文件 var path = "http://wex5.com/cn/wp-content/uploads/2015/04/outterAMD2.js"; require([path], function(m){ m.fnOfOutterAMD2(); }) };
通过以上代码,引用 /UI2/demo/misc/importJs/AMD2.js和http://wex5.com/cn/wp-content/uploads/2015/04/outterAMD2.js模块,在引用模块成功的回调函数中通过参数名m调用被引用js模块中的方法。
2、如何引用不符合AMD规范的js模块?
对于不符合AMD规范js模块,可以改造成符合AMD规范的js模块,也可以通过以下的方式引用不符合AMD规范的js模块:
方式一:require(‘模块路径’)
例如,在/UI2/demo/misc/importJs/importJs.js文件中:
// 加载UI2下, 不符合AMD规范的文件 require("./noneAMD1"); // 加载外网, 不符合AMD规范的文件 require("http://wex5.com/cn/wp-content/uploads/2015/04/outterNoneAMD1.js");
通过以上代码,引用/UI2/demo/misc/importJs/noneAMD1.js和http://wex5.com/cn/wp-content/uploads/2015/04/outterNoneAMD1.js模块,在当前模块的后续代码中,可以直接使用这两个模块中定义的全局函数和变量。
方式二:require([‘文件路径’], successCallback, errorCallback)
Model.prototype.importInnerNoneAMDBtnClick = function(event){ // 加载UI2下, 不符合AMD规范的文件 var path = "./noneAMD2"; require([path], function(){ fnOfNoneAMD2(); }); }; Model.prototype.importOutterNoneAMDBtnClick = function(event){ // 加载外网, 不符合AMD规范的文件 var path = "http://wex5.com/cn/wp-content/uploads/2015/04/outterNoneAMD2.js"; require([path], function(){ fnOfOutterNoneAMD2(); }) };
通过以上代码,引用/UI2/demo/misc/importJs/noneAMD2.js和http://wex5.com/cn/wp-content/uploads/2015/04/outterNoneAMD2.js模块,在引用模块成功的回调函数中,可以调用被引用模块中定义的全局变量和函数。
引用css模块
在js中,可以通过以下语法来引用js模块:
require(‘css!模块路径’).load();
其中模块路径必须符合以下规则:
1、支持“.”或“..”或“$UI”开头的相对路径,相对于当前模块所在的路径;
2、支持“http”或“https”开头的绝对路径;
3、如果是相对路径,不需要带文件的扩展名;如果是绝对路径,必须带文件扩展名;
4、模块路径只支持常量,不支持变量;
例如,在/UI2/demo/misc/importCss/importCss.js中:
//加载UI2下的css文件 require("css!./innerCss1").load(); require("css!$UI/demo/misc/importCss/innerCss2").load(); //加载外网的css文件 require("css!http://wex5.com/cn/wp-content/uploads/2015/04/outterCss1.css").load();
通过以上代码,引用了以下三个css文件:
- /UI2/demo/misc/importCss/innerCss1.css
- /UI2/demo/misc/importCss/innerCss2.css
- http://wex5.com/cn/wp-content/uploads/2015/04/outterCss1.css
对于css模块,除了可以使用上述代码的方式引用之外,还可以在w文件中直接引用,具体请参考“页面样式”章节。
引用text模块
对于text模块,可以通过以下方式来引用:
方式一,require(‘text!文件路径’)
先加载指定的text模块,再加载当前模块。
方式二,require([‘text!文件路径’], successCallback, errorCallback)
当执行到require语句时,才异步加载指定的text模块;指定的text模块加载成功后,执行successCallback,如果加载失败则执行errorCallback。
引用text模块时,文件路径必须符合以下规则:
1、支持以“.”或“..”或“$UI”开头相对路径;
2、支持以“http”或“https”开头的绝对路径;
3、文件路径必须是带扩展名,无论是相对路径还是绝对路径(和js模块或css模块的引用不同);
4、方式一中,文件路径必须是常量;方式二中,文件路径可以是变量;
例如,在/UI2/demo/misc/importCss/importCss.js中:
//加载UI2下的text文件 var innerText1 = require("text!./innerText1.txt"); //动态加载UI2下的text文件 Model.prototype.innerTextBtnClick = function(event){ var path = "text!./innerText2.txt"; require([path], function(content){ alert("innerText2 content: " + content); });
通过以上代码,引用了以下text模块:
- /UI2/demo/misc/importCss/innerText1.txt
- /UI2/demo/misc/importCss/innerText2.txt
声明资源依赖
WeX5打包生成app时,会自动将app依赖的资源打到app中,这里所说的资源包括:cordova插件、w文件、图片等等。
1、声明cordova插件依赖
在WeX5开发的移动应用中,可以使用cordova插件调用手机提供的本地功能或服务(例如照相机功能、录音功能等等)。WeX5内置支持了丰富的cordova插件:
图2-16 cordova插件
在页面中,不仅可以直接使用这些内置的cordova插件,也可以自定义cordova插件,具体请参考“WeX5扩展”中的“自定义cordova插件”。
有这么多的cordova插件,页面中如何引用呢?引用cordova插件的语法:
require(‘cordova!插件包名’)
其中“插件包名”就是cordova插件所在的目录名,例如:“com.justep.cordova.plugin.aplipay”
在/UI2/demo/device/camera/mainActivity.js文件中,
require(“cordova!org.apache.cordova.camera”);
通过以上代码,引用了照相机插件,在当前模块的后续代码中,可以调用照相机功能,如下:
//拍照 Model.prototype.cameraBtnClick = function(event) { var operateLabel = this.getElementByXid("operateLabel"); var resultLabel = this.getElementByXid("resultLabel"); $(operateLabel).text("开始拍照!"); $(resultLabel).text(""); var data = this.comp("fileData"); function onSuccess(imageURI) { data.newData({index : 0}); data.setValue("filePath", imageURI); data.setValue("fileName", imageURI.substr(imageURI.lastIndexOf('/') + 1)); data.setValue('createTime', justep.Date.toString(new Date(), justep.Date.DEFAULT_FORMAT )); $(resultLabel).text("成功"+imageURI); } function onFail(message) { $(resultLabel).text("失败:"+message); } navigator.camera.getPicture(onSuccess, onFail, {quality : 50}); };
其中navigator.camera.getPicture调用了照相机的拍照功能。
2、声明window文件依赖
语法:require(‘w!window文件路径’)
window文件路径必须符合以下规则:
- 支持以“.”或“..”或“$UI”开头的相对路径;
- 路径必须带文件扩展名;
3、声明res资源依赖
语法:require(‘res!资源路径’)
资源路径必须符合以下规则:
- 支持以“.”或“..”或“$UI”开头的相对路径;
- 资源路径允许指向一个目录或一个文件,如果是文件时,必须带文件扩展名;