随着互联网的飞速发展,前端开发越来越复杂,导致开发经常出现两个问题:

  • 恼人的命名冲突
  • 烦琐的文件依赖

针对这两个问题,可以使用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#define

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),目录结构如下:
js
图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插件:
codovar
图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”开头的相对路径;
  • 资源路径允许指向一个目录或一个文件,如果是文件时,必须带文件扩展名;