类似于Java的package/import,在JavaScript中也有类似的define/require,它用来异步加载module化的js,从而提高运行效率。
- define 定义注册一个module
- require 加载使用一个module
模块化加载的必要性,起源于nodejs的出现。但是JavaScript并没有内置模块系统,所以就出现了很多规范。
主要有2种:
CommonJS和
AMD(Asynchronous Module Definition)。还有国内兴起的
CMD(Common Module Definition)
CommonJS主要面对的是服务器,代表是
Node.js;AMD针对浏览器进行了优化,主要实现
require.js;CMD是
seajs。
cordova-js最开始采用的是require.js作者写的
almond.js(兼容AMD和CommonJS),但之后由于特殊需求(比如模块不存在的时候要throw异常),最终从almond.js fork过来实现了一个简易CommonJS风格的模块系统,同时提供了和nodejs之间很好的交互。在cordova.js中可以直接使用define()和require(),在其他文件可以通过cordova.define()和cordova.require()来调用。所以src/scripts/require.js中定义的就是一个精简的JavaScript模块系统。
源码如下:
// file: src/scripts/require.js
// 定义2个cordova.js内部使用的全局函数require/define
var require,
define;
// 通过自调用的匿名函数来实例化全局函数require/define
(function () {
// 全部模块
var modules = {},
// 正在build中的模块ID的栈
requireStack = [],
// 标示正在build中模块ID的Map
inProgressModules = {},
SEPARATOR = ".";
// 模块build
function build(module) {
// 备份工厂方法
var factory = module.factory,
// 对require对象进行特殊处理
localRequire = function (id) {
var resultantId = id;
if (id.charAt(0) === ".") {
resultantId = module.id.slice(0, module.id.lastIndexOf(SEPARATOR)) + SEPARATOR + id.slice(2);
}
return require(resultantId);
};
// 给模块定义一个空的exports对象,防止工厂类方法中的空引用
module.exports = {};
// 删除工厂方法
delete module.factory;
// 调用备份的工厂方法(参数必须是require,exports,module)
factory(localRequire, module.exports, module);
// 返回工厂方法中实现的module.exports对象
return module.exports;
}
// 加载模块
require = function (id) {
// 如果模块不存在抛出异常
if (!modules[id]) {
throw "module " + id + " not found";
// 如果模块正在build中抛出异常
} else if (id in inProgressModules) {
var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
throw "Cycle in require graph: " + cycle;
}
// 如果模块存在工厂方法说明还未进行build(require嵌套)
if (modules[id].factory) {
try {
// 标示该模块正在build
inProgressModules[id] = requireStack.length;
// 将该模块压入请求栈
requireStack.push(id);
// 模块build,成功后返回module.exports
return build(modules[id]);
} finally {
// build完成后删除当前请求
delete inProgressModules[id];
requireStack.pop();
}
}
// build完的模块直接返回module.exports
return modules[id].exports;
};
// 定义模块
define = function (id, factory) {
// 如果已经存在抛出异常
if (modules[id]) {
throw "module " + id + " already defined";
}
// 模块以ID为索引包含ID和工厂方法
modules[id] = {
id: id,
factory: factory
};
};
// 移除模块
define.remove = function (id) {
delete modules[id];
};
// 返回所有模块
define.moduleMap = modules;
})();
// 如果处于nodejs环境的话,把require/define暴露给外部
if (typeof module === "object" && typeof require === "function") {
module.exports.require = require;
module.exports.define = define;
}
其中
factory(localRequire, module.exports, module);
第一个参数“localRequire”实质还是调用全局的require()函数,只是把ID稍微加工了一下支持相对路径。cordova.js没有用到相对路径的require,但在一些Plugin的js中有,比如Contact.js 中 ContactError = require('./ContactError');
不知道什么原因要把module.exports单做为工厂方法的第两个参数,cordova.js中除了个别地方用到第二个参数(base64.js、uilder.js、modulemapper.js、pluginloader.js、utils.js),大部分都是在用第三个参数在工厂方法里调用module.exports。Plugin的js代码中也基本是module.exports。
参考:
https://github.com/seajs/seajs/issues/588
http://phonegap.com/2012/03/21/introducing-cordova-js/
分享到:
相关推荐
NULL 博文链接:https://rensanning.iteye.com/blog/2047322
NULL 博文链接:https://rensanning.iteye.com/blog/2054646
NULL 博文链接:https://rensanning.iteye.com/blog/2023480
Cordova 3.x(aka PhoneGap)的基础知识、实用插件、源码分析、实例开发。
NULL 博文链接:https://rensanning.iteye.com/blog/2034061
Ionic3.x+、Angular4.x+ Cordova 介 绍以及Ionic3.x+环境搭建 一、Ionic 介绍............................................................................................................................1 二...
记录了我安全完成cordova工具后,用它生成apk的过程记录
NULL 博文链接:https://rensanning.iteye.com/blog/2072034
NULL 博文链接:https://rensanning.iteye.com/blog/2029362
NULL 博文链接:https://rensanning.iteye.com/blog/2032663
NULL 博文链接:https://rensanning.iteye.com/blog/2034026
js-css/超酷炫CSS3发光字体.html./html-js-css/ionic-cordova学习.txt./html-js-css/ant.html./html-js-css/nodejs学习.txt./html-js-css/blur.html./html-js-css/hihack.js./html-js-css/js常用.txt./...
NULL 博文链接:https://rensanning.iteye.com/blog/2163892
实实在在经过ant编译的cordova-2.9.1.jar 而不是有些人坑蒙拐骗的rar文件
1,cordova-android-3.3.0 源码 2,cordova-android-3.3.0 plugins源码 3,cordova-android-3.3.jar https://git-wip-us.apache.org/repos/asf?s=cordova config.xml请移步看文章:...
最新的cordova-js版本
NULL 博文链接:https://rensanning.iteye.com/blog/2042543