From 51fc4549da6d42a3de70dbf1742fac706fe90e9b Mon Sep 17 00:00:00 2001 From: MiaoWoo Date: Thu, 17 Dec 2020 16:17:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E5=AF=BB=E6=89=BE=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MiaoWoo --- pom.xml | 7 +- .../pw/yumc/MiaoScript/JavaScriptTask.java | 17 ++++- .../java/pw/yumc/MiaoScript/ScriptEngine.java | 2 +- src/main/resources/core/require.js | 71 ++++++++++++------- 4 files changed, 69 insertions(+), 28 deletions(-) diff --git a/pom.xml b/pom.xml index 0775308..4d6d5b9 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 pw.yumc MiaoScript - 0.9.7 + 0.10.0 502647092 @@ -54,7 +54,10 @@ DEV - §620-12-07 §afix: 修复 Windows 环境 重载异常; + §620-12-17 §afeat: JavaScriptTask 新增任务ID 并通过ID比较优先级; + §620-12-16 §afeat: 优化 require 路径寻找速度; + §620-12-15 §cfix: 修复 非主线程重载时发生的异常; + §620-12-07 §cfix: 修复 Windows 环境 重载异常; §620-11-19 §afeat: 新增 JavaScriptTask 类; §620-11-11 §afeat: 新增 package 版本锁定逻辑; §620-09-21 §afeat: 完善 upgrade 逻辑; diff --git a/src/main/java/pw/yumc/MiaoScript/JavaScriptTask.java b/src/main/java/pw/yumc/MiaoScript/JavaScriptTask.java index 4579e67..9a6fe8b 100644 --- a/src/main/java/pw/yumc/MiaoScript/JavaScriptTask.java +++ b/src/main/java/pw/yumc/MiaoScript/JavaScriptTask.java @@ -4,11 +4,17 @@ import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; public class JavaScriptTask implements Delayed { + private final long id; private final Object task; private final long startTime; private final long executeTime; public JavaScriptTask(Object task, long ms) { + this(0, task, ms); + } + + public JavaScriptTask(long id, Object task, long ms) { + this.id = id; this.task = task; this.startTime = System.currentTimeMillis(); this.executeTime = ms; @@ -22,7 +28,16 @@ public class JavaScriptTask implements Delayed { @Override public int compareTo(Delayed delayed) { JavaScriptTask task = (JavaScriptTask) delayed; - return (int) ((this.startTime + this.executeTime) - (task.getStartTime() + task.getExecuteTime())); + int delay = (int) ((this.startTime + this.executeTime) - (task.getStartTime() + task.getExecuteTime())); + if (delay != 0) { + return delay; + } else { + return (int) (this.id - task.getId()); + } + } + + public long getId() { + return this.id; } public Object getTask() { diff --git a/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java b/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java index 8a55185..62bc5d7 100644 --- a/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java +++ b/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java @@ -39,9 +39,9 @@ public class ScriptEngine { @SneakyThrows public void enableEngine() { - createEngine(); ClassLoader originLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(this.loader); + createEngine(); Path bios = Paths.get(root, "bios.js"); // 如果存在自定义bios就加载自定义的 if (Files.exists(bios)) { diff --git a/src/main/resources/core/require.js b/src/main/resources/core/require.js index 2ef52e9..defa3a5 100644 --- a/src/main/resources/core/require.js +++ b/src/main/resources/core/require.js @@ -125,22 +125,20 @@ * 寻找 ${NODE_PATH} * @param {string} name 模块名称 * @param {string} parent 父目录 + * @param {any} optional 附加参数 */ - function resolve(name, parent) { + function resolve(name, parent, optional) { name = _canonical(name) || name - if (cacheModuleIds[name]) return cacheModuleIds[name] // 解析本地目录 - if (name.startsWith('./') || name.startsWith('../')) { - var moduleId = parent + '/' + name - if (cacheModuleIds[moduleId]) return cacheModuleIds[moduleId] - return cacheModuleIds[moduleId] = resolveAsFile(name, parent) || resolveAsDirectory(name, parent) || undefined + if (optional.local) { + return resolveAsFile(name, parent) || resolveAsDirectory(name, parent) || undefined } else { // 解析Node目录 var dir = [parent, 'node_modules'].join(separatorChar) - return cacheModuleIds[name] = resolveAsFile(name, dir) || resolveAsDirectory(name, dir) || + return resolveAsFile(name, dir) || resolveAsDirectory(name, dir) || // @ts-ignore (parent && parent.toString().startsWith(root) ? - resolve(name, new File(parent).getParent()) : resolveAsDirectory(name, NODE_PATH) || undefined) + resolve(name, new File(parent).getParent(), optional) : resolveAsDirectory(name, NODE_PATH) || undefined) } } @@ -341,7 +339,7 @@ * @param {string} name * @param {string} path */ - function checkCoreModule(name, path) { + function checkCoreModule(name, path, optional) { if (name.startsWith('@ms') && lastModule.endsWith('.js')) { // @ts-ignore console.warn(lastModule + ' load deprecated module ' + name + ' auto replace to ' + (name = name.replace('@ms', global.scope)) + '...') @@ -352,7 +350,7 @@ if (CoreModules.indexOf(name) !== -1) { // @ts-ignore var newName = global.scope + '/nodejs/dist/' + name - if (resolve(newName, path) !== undefined) { + if (resolve(newName, path, optional) !== undefined) { return newName } // @ts-ignore @@ -360,7 +358,12 @@ } return name } - + /** + * 检查缓存模块 + */ + function checkCacheModule(optional) { + return !optional.path.startsWith('/') && cacheModuleIds[optional.parentId] && cacheModuleIds[optional.parentId][optional.path] + } /** * 加载模块 * @param {string} name 模块名称 @@ -369,17 +372,18 @@ * @returns {*} */ function _require(name, path, optional) { - name = checkCoreModule(name, path) + var cachePath = checkCacheModule(optional) + if (cachePath) { return _requireFile(new File(cachePath), optional) } + name = checkCoreModule(name, path, optional) var file = new File(name) - file = _isFile(file) ? file : resolve(name, path) - optional = __assign({ cache: true }, optional) + file = _isFile(file) ? file : resolve(name, path, optional) if (file === undefined) { + // excloud local dir, prevent too many recursive call and cache not found module + if (optional.local || optional.recursive || notFoundModules[name]) { + console.log(name, path, optional, notFoundModules[name]) + throw new Error("Can't found module " + name + '(' + JSON.stringify(optional) + ') at local ' + path + ' or network!') + } try { - // excloud local dir, prevent too many recursive call and cache not found module - if (name.startsWith('.') || name.startsWith('/') || optional.recursive || notFoundModules[name]) { - console.log(name, path, optional, notFoundModules[name]) - throw new Error("Can't found module " + name + '(' + JSON.stringify(optional) + ') at local ' + path + ' or network!') - } optional.recursive = true return _require(download(name), path, optional) } catch (ex) { @@ -387,6 +391,13 @@ throw new FileNotFoundException("Can't found module " + name + ' in directory ' + path + ' ERROR: ' + ex) } } + var parent = cacheModuleIds[optional.parentId] + if (!parent) { cacheModuleIds[optional.parentId] = {} } + cacheModuleIds[optional.parentId][optional.path] = _canonical(file) + return _requireFile(file, optional) + } + + function _requireFile(file, optional) { // 重定向文件名称和类型 return getCacheModule(_canonical(file), file.name.split('.')[0], file, optional) } @@ -403,15 +414,16 @@ * @param {any} optional */ return function __DynamicRequire__(path, optional) { - return _require(path, parent, __assign({ parentId: parentId }, optional)).exports + return _require(path, parent, __assign({ cache: true, parentId: parentId, parent: parent, path: path, local: path.startsWith('.') || path.startsWith('/') }, optional)).exports } } /** * @param {string} name + * @param {any} optional 附加选项 */ - function __DynamicResolve__(name) { - return _canonical(new File(resolve(name, parent))) + function __DynamicResolve__(name, optional) { + return _canonical(new File(resolve(name, parent, __assign({ cache: true, parent: parent, local: name.startsWith('.') || name.startsWith('/') }, optional)))) } /** @@ -427,6 +439,8 @@ } function __DynamicDisable__() { + // @ts-ignore + base.save(cacheModuleIdsFile, JSON.stringify(cacheModuleIds)) for (var cacheModule in cacheModules) { delete cacheModules[cacheModule] } @@ -461,8 +475,9 @@ * @type {{[key:string]:any}} cacheModules */ var cacheModules = {} + var cacheModuleIdsFile = _canonical(new File(NODE_PATH, 'cacheModuleIds.json')) /** - * @type {{[key:string]:string}} cacheModuleIds + * @type {{[key:string]:{[key:string]:string}}} cacheModuleIds */ var cacheModuleIds = {} /** @@ -474,6 +489,14 @@ console.info('- NODE_PATH:', NODE_PATH) console.info('- NODE_REGISTRY:', NODE_REGISTRY) console.info('- MS_NODE_REGISTRY:', MS_NODE_REGISTRY) + try { + // @ts-ignore + cacheModuleIds = JSON.parse(base.read(cacheModuleIdsFile)) + console.log('Read cacheModuleIds from file ' + cacheModuleIdsFile) + } catch (error) { + cacheModuleIds = {} + console.log('Initialization new cacheModuleIds') + } try { ModulesVersionLock = JSON.parse(fetchContent('http://ms.yumc.pw/api/plugin/download/name/version_lock', 'version_lock')) console.info('Lock module version List:') @@ -484,5 +507,5 @@ console.debug(error) ModulesVersionLock = {} } - return getRequire(parent, "null") + return getRequire(parent, "") })