2017-09-23 09:42:16 +00:00
|
|
|
/**
|
|
|
|
* 符合 CommonJS 规范的 模块化加载
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
/*global Java, base*/
|
|
|
|
(function (parent, core_dir, miao_module_dir) {
|
|
|
|
'use strict';
|
|
|
|
var File = Java.type("java.io.File");
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 解析模块名称为文件
|
|
|
|
* 按照下列顺序查找
|
|
|
|
* 当前目录 ./
|
|
|
|
* 父目录 ../
|
|
|
|
* 核心目录 /core
|
|
|
|
* 模块目录 /modules
|
|
|
|
* @param name 模块名称
|
|
|
|
*/
|
|
|
|
function findModule(name) {
|
|
|
|
if (_canonical(name)) {
|
|
|
|
name = _canonical(name);
|
|
|
|
}
|
|
|
|
if (!name.match(/.*\.js/)) {
|
|
|
|
name += ".js";
|
|
|
|
}
|
|
|
|
var jsFile = new File(name);
|
|
|
|
if (jsFile.exists()) {
|
|
|
|
return jsFile;
|
|
|
|
}
|
|
|
|
var parentFile = new File(parent, name);
|
|
|
|
if (parentFile.exists()) {
|
|
|
|
return parentFile;
|
|
|
|
}
|
|
|
|
var coreFile = new File(core_dir, name);
|
|
|
|
if (coreFile.exists()) {
|
|
|
|
return coreFile;
|
|
|
|
}
|
|
|
|
var moduleFile = new File(miao_module_dir, name);
|
|
|
|
if (moduleFile.exists()) {
|
|
|
|
return moduleFile;
|
|
|
|
}
|
|
|
|
log.w("模块 %s 加载失败! 下列目录中未找到该模块!", name);
|
|
|
|
log.w("当前目录: %s", _canonical(jsFile));
|
|
|
|
log.w("上级目录: %s", _canonical(parentFile));
|
|
|
|
log.w("核心目录: %s", _canonical(coreFile));
|
|
|
|
log.w("模块目录: %s", _canonical(moduleFile));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 预编译模块
|
2017-09-27 12:40:57 +00:00
|
|
|
* @param file
|
2017-09-23 09:42:16 +00:00
|
|
|
* @returns {Object}
|
|
|
|
*/
|
2017-09-27 12:40:57 +00:00
|
|
|
function compileJs(file) {
|
|
|
|
var cacheFile = _cacheFile(file);
|
|
|
|
base.save(cacheFile, "(function (module, exports, require) {" + base.read(file) + "});");
|
|
|
|
var obj = load(cacheFile);
|
|
|
|
base.delete(cacheFile);
|
|
|
|
return obj;
|
2017-09-23 09:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 获得文件规范路径
|
|
|
|
* @param file
|
|
|
|
* @returns {*}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
function _canonical(file) {
|
|
|
|
// noinspection JSUnresolvedVariable
|
|
|
|
return file.canonicalPath;
|
|
|
|
}
|
|
|
|
|
2017-09-27 12:40:57 +00:00
|
|
|
function _cacheFile(file) {
|
|
|
|
return cacheDir + "/" + file.name;
|
|
|
|
}
|
|
|
|
|
2017-09-23 09:42:16 +00:00
|
|
|
/**
|
|
|
|
* 加载模块
|
|
|
|
* @param name 模块名称
|
|
|
|
* @param parent 父目录
|
|
|
|
* @returns {*}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
function _require(name, parent) {
|
|
|
|
var file = findModule(name, parent);
|
|
|
|
// 重定向文件名称
|
|
|
|
name = file.name.split(".")[0];
|
|
|
|
var id = _canonical(file);
|
|
|
|
var module = cacheModules[id];
|
|
|
|
if (module) {
|
|
|
|
return module;
|
|
|
|
}
|
|
|
|
log.d('加载模块 %s 位于 %s', name, id);
|
|
|
|
module = {
|
|
|
|
loaded: false,
|
|
|
|
id: id,
|
|
|
|
exports: {},
|
|
|
|
require: exports(file.parentFile)
|
|
|
|
};
|
|
|
|
try {
|
|
|
|
// 预编译模块
|
2017-09-27 12:40:57 +00:00
|
|
|
var compiledWrapper = compileJs(file);
|
2017-09-23 09:42:16 +00:00
|
|
|
compiledWrapper.apply(module.exports, [
|
|
|
|
module, module.exports, module.require
|
|
|
|
]);
|
2017-09-27 12:40:57 +00:00
|
|
|
log.d('模块 %s 编译成功!', name);
|
|
|
|
module.loaded = true;
|
2017-09-23 09:42:16 +00:00
|
|
|
} catch (ex) {
|
|
|
|
log.w("模块 %s 编译失败!", name);
|
2017-09-23 10:30:14 +00:00
|
|
|
log.d(ex);
|
2017-09-23 09:42:16 +00:00
|
|
|
}
|
|
|
|
cacheModules[id] = module;
|
|
|
|
return cacheModules[id];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 闭包方法
|
|
|
|
* @param parent 父目录
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
function exports(parent) {
|
|
|
|
return function (path) {
|
|
|
|
return _require(path, parent).exports;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-09-23 10:30:14 +00:00
|
|
|
var cacheDir = parent + "/cache";
|
|
|
|
|
2017-09-23 09:42:16 +00:00
|
|
|
// 等于 undefined 说明 parent 是一个字符串 需要转成File
|
2017-09-27 12:40:57 +00:00
|
|
|
// 可能有更加准确的方案
|
2017-09-23 09:42:16 +00:00
|
|
|
if (_canonical(parent) === undefined) {
|
|
|
|
parent = new File(parent);
|
|
|
|
}
|
|
|
|
var cacheModules = [];
|
|
|
|
log.d("初始化 require 模块组件 父目录 %s", _canonical(parent));
|
|
|
|
return exports(parent);
|
|
|
|
});
|