diff --git a/pom.xml b/pom.xml index dbaf405..405255e 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 pw.yumc MiaoScript - 0.7.0 + 0.7.3 502647092 @@ -53,6 +53,8 @@ DEV + §620-06-23 §afeat: 支持自定义参数; + §620-06-22 §afeat: 优化 require 加载逻辑; §620-05-28 §afeat: 新增 Spring 的支持; §620-05-02 §afeat: 调整 scope 为 @ccms; §620-04-10 §afeat: 默认从 classpath 加载内建的js模块; diff --git a/src/main/resources/bios.js b/src/main/resources/bios.js index 2ea2e2b..adef27a 100644 --- a/src/main/resources/bios.js +++ b/src/main/resources/bios.js @@ -6,7 +6,7 @@ var global = this; (function () { var loader; global.boot = function (root, logger) { - global.scope = "@ccms"; + global.scope = java.lang.System.getenv("MS_NODE_CORE_SCOPE") || "@ccms"; global.log = logger; // Development Env Detect global.root = root || "src/main/resources"; @@ -27,8 +27,10 @@ var global = this; // Async Loading MiaoScript Engine new java.lang.Thread(function () { java.lang.Thread.currentThread().contextClassLoader = loader; - load('classpath:core/ployfill.js')(root, logger); - global.engineDisable = require(global.scope + '/core').default || function () { logger.info('Error: abnormal Initialization MiaoScript Engine. Skip disable step...') }; + load(java.lang.System.getenv("MS_NODE_CORE_PLOYFILL") || 'classpath:core/ployfill.js')(root, logger); + global.engineDisable = require(java.lang.System.getenv("MS_NODE_CORE_MODULE") || global.scope + '/core').default || function () { + logger.info('Error: abnormal Initialization MiaoScript Engine. Skip disable step...') + }; }, "MiaoScript thread").start() }; diff --git a/src/main/resources/core/ployfill.js b/src/main/resources/core/ployfill.js index ebd40bd..8eaf2f0 100644 --- a/src/main/resources/core/ployfill.js +++ b/src/main/resources/core/ployfill.js @@ -20,10 +20,9 @@ } }; // Init console and require - global.console = engineLoad('classpath:core/console.js')(logger); + global.console = engineLoad(java.lang.System.getenv("MS_NODE_CORE_CONSOLE") || 'classpath:core/console.js')(logger); console.log("Loading Engine at Thread", java.lang.Thread.currentThread().name) - global.require = engineLoad('classpath:core/require.js')(root); + global.require = engineLoad(java.lang.System.getenv("MS_NODE_CORE_REQUIRE") || 'classpath:core/require.js')(root); require(global.scope + '/ployfill') - require(global.scope + '/nodejs') } ) diff --git a/src/main/resources/core/require.js b/src/main/resources/core/require.js index 5986696..ae0c035 100644 --- a/src/main/resources/core/require.js +++ b/src/main/resources/core/require.js @@ -27,7 +27,7 @@ // @ts-check ( /** - * @param {any} parent + * @param {string} parent */ function (parent) { 'use strict'; @@ -55,6 +55,13 @@ var JavaString = Java.type('java.lang.String') var separatorChar = File.separatorChar; + // @ts-ignore + var NODE_PATH = java.lang.System.getenv("NODE_PATH") || root + separatorChar + 'node_modules' + // @ts-ignore + var NODE_REGISTRY = java.lang.System.getenv("NODE_REGISTRY") || 'https://registry.npm.taobao.org' + // @ts-ignore + var MS_NODE_REGISTRY = java.lang.System.getenv("MS_NODE_REGISTRY") || 'https://repo.yumc.pw/repository/npm' + var CoreModules = [ "assert", "async_hooks", "Buffer", "child_process", "cluster", "crypto", "dgram", "dns", "domain", "events", "fs", "http", "http2", "https", @@ -70,13 +77,16 @@ function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; - if (s === undefined) { continue; }; + if (s === undefined) { + continue; + } for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; - }; + } + // noinspection JSValidateJSDoc /** * 判断是否为一个文件 * @param {any} file @@ -109,23 +119,26 @@ * 按照下列顺序查找 * 当前目录 ./ * 父目录 ../ - * 模块目录 /node_modules + * 递归模块目录 ../node_modules 到root + * 寻找 ${NODE_PATH} * @param {string} name 模块名称 * @param {string} parent 父目录 */ function resolve(name, parent) { name = _canonical(name) || name; + if (cacheModuleIds[name]) return cacheModuleIds[name] // 解析本地目录 if (name.startsWith('./') || name.startsWith('../')) { - return resolveAsFile(name, parent) || resolveAsDirectory(name, parent) || undefined; + var moduleId = parent + '||' + name + if (cacheModuleIds[moduleId]) return cacheModuleIds[moduleId] + return cacheModuleIds[moduleId] = resolveAsFile(name, parent) || resolveAsDirectory(name, parent) || undefined; } else { // 解析Node目录 var dir = [parent, 'node_modules'].join(separatorChar); - if (cacheModuleIds[name]) return cacheModuleIds[name] - cacheModuleIds[name] = resolveAsFile(name, dir) || resolveAsDirectory(name, dir) || + return cacheModuleIds[name] = resolveAsFile(name, dir) || resolveAsDirectory(name, dir) || // @ts-ignore - (parent && parent.toString().startsWith(root) ? resolve(name, new File(parent).getParent()) : undefined); - return cacheModuleIds[name]; + (parent && parent.toString().startsWith(root) ? + resolve(name, new File(parent).getParent()) : resolveAsDirectory(name, NODE_PATH) || undefined); } } @@ -136,7 +149,7 @@ * @returns {*} */ function resolveAsFile(file, dir) { - file = dir != undefined ? new File(dir, file) : new File(file); + file = dir !== undefined ? new File(dir, file) : new File(file); // 直接文件 // @ts-ignore if (file.isFile()) { @@ -161,7 +174,7 @@ * @returns {*} */ function resolveAsDirectory(file, dir) { - dir = dir != undefined ? new File(dir, file) : new File(file); + dir = dir !== undefined ? new File(dir, file) : new File(file); var _package = new File(dir, 'package.json'); if (_package.exists()) { // @ts-ignore @@ -250,7 +263,10 @@ // 2019-09-19 使用 扩展函数直接 load 无需保存/删除文件 // 2020-02-16 结尾新增换行 防止有注释导致加载失败 // @ts-ignore - var compiledWrapper = engineLoad({ script: '(function $(module, exports, require, __dirname, __filename) {' + origin + '\n});', name: optional.id }); + var compiledWrapper = engineLoad({ + script: '(function $(module, exports, require, __dirname, __filename) {' + origin + '\n});', + name: optional.id + }); compiledWrapper.apply(module.exports, [ module, module.exports, module.require, file.parentFile, file ]); @@ -278,7 +294,7 @@ var name_arr = name.split('/'); var module_name = name.startsWith('@') ? name_arr[0] + '/' + name_arr[1] : name_arr[0]; // @ts-ignore - var target = root + separatorChar + 'node_modules' + separatorChar + module_name; + var target = NODE_PATH + separatorChar + module_name; var _package = new File(target, 'package.json'); if (_package.exists()) { return } // at windows need replace file name java.lang.IllegalArgumentException: Invalid prefix or suffix @@ -302,10 +318,10 @@ function fetchPackageInfo(module_name) { var tempFile = Files.createTempFile(module_name.replace('/', '_'), '.json'); try { - Files.copy(new URL('https://registry.npm.taobao.org/' + module_name).openStream(), tempFile, StandardCopyOption.REPLACE_EXISTING); + Files.copy(new URL(NODE_REGISTRY + '/' + module_name).openStream(), tempFile, StandardCopyOption.REPLACE_EXISTING); } catch (ex) { - console.debug('can\'t fetch package ' + module_name + ' from taobao registry. try fetch from yumc registry...') - Files.copy(new URL('https://repo.yumc.pw/repository/npm/' + module_name).openStream(), tempFile, StandardCopyOption.REPLACE_EXISTING); + console.debug('can\'t fetch package ' + module_name + ' from ' + NODE_REGISTRY + ' registry. try fetch from ' + MS_NODE_REGISTRY + ' registry...') + Files.copy(new URL(MS_NODE_REGISTRY + '/' + module_name).openStream(), tempFile, StandardCopyOption.REPLACE_EXISTING); } tempFile.toFile().deleteOnExit(); return JSON.parse(new JavaString(Files.readAllBytes(tempFile), 'UTF-8')); @@ -325,7 +341,7 @@ } else { lastModule = name } - if (CoreModules.indexOf(name) != -1) { + if (CoreModules.indexOf(name) !== -1) { // @ts-ignore var newName = global.scope + '/nodejs/dist/' + name if (resolve(newName, path) !== undefined) { @@ -374,44 +390,46 @@ * @returns {Function} */ function exports(parent, parentId) { - var __DynamicRequire__ = - /** - * @param {string} path - * @param {any} optional - */ - function __DynamicRequire__(path, optional) { - return _require(path, parent, __assign({ parentId: parentId }, optional)).exports; - } - return __DynamicRequire__ + /** + * @param {string} path + * @param {any} optional + */ + return function __DynamicRequire__(path, optional) { + return _require(path, parent, __assign({ parentId: parentId }, optional)).exports; + } } + /** * @param {string} name */ function __DynamicResolve__(name) { return _canonical(new File(resolve(name, parent))) } + /** * @param {string} name */ function __DynamicClear__(name) { for (var cacheModule in cacheModules) { - if (cacheModule.indexOf(name) != -1) { + if (cacheModule.indexOf(name) !== -1) { console.trace('Clear module ' + cacheModule + ' ...') delete cacheModules[cacheModule] } } } + function __DynamicDisable__() { for (var cacheModule in cacheModules) { delete cacheModules[cacheModule] } cacheModules = undefined; - for (var cacheModule in cacheModuleIds) { - delete cacheModuleIds[cacheModule] + for (var cacheModuleId in cacheModuleIds) { + delete cacheModuleIds[cacheModuleId] } cacheModuleIds = undefined; notFoundModules = undefined; } + /** * @param {string} parent * @param {string} parentId @@ -444,5 +462,9 @@ */ var notFoundModules = {}; console.info('Initialization require module. ParentDir:', _canonical(parent)); + console.info('Require module env list:'); + console.info('- NODE_PATH:', NODE_PATH); + console.info('- NODE_REGISTRY:', NODE_REGISTRY); + console.info('- MS_NODE_REGISTRY:', MS_NODE_REGISTRY); return getRequire(parent, "null"); });