UNPKG

mockm

Version:

Analog interface server, painless parallel development of front and back ends.

218 lines (186 loc) 6.58 kB
#!/usr/bin/env node /** * 要实现监控 js 文件修改后重新启动, 需要用到 nodemon 这个工具, 之前是通过 packge.scripts 中的命令行方式使用的. * 由于向系统注册 packge.bin 时, 这个文件只能由 node 执行, 即只能为 js. * 所以, 需要一个额外的 js 文件来监听 config.js 修改, 然后重启 server.js * 把 run.js 中收集的命令行参数, 以 base64 方式传入 server.js 中. */ "use strict"; var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault"); var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes")); var _stringify = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/json/stringify")); var _now = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/date/now")); var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise")); var _filter = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/filter")); var _slice = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/slice")); var _trim = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/trim")); var _context; const { logHelper, print } = require(`${__dirname}/util/log.js`); process.argv = require(`./lib/cross-argv@1.0.1.js`)(); (0, _includes.default)(_context = process.argv).call(_context, `--log-line`) && logHelper(); const fs = require(`fs`); const path = require(`path`); const { tool, business } = require(`${__dirname}/util/index.js`); const lib = require(`${__dirname}/util/lib.js`); const packageJson = require(`${__dirname}/package.json`); const cli = tool.cli; const cliArg = cli.parseArgv(); const serverPath = path.normalize(`${__dirname}/server.js`); // 转换为跨平台的路径 const { ProcessManager } = require(`@wll8/process-manager`); { // 尽早的, 无依赖的修改 cwd, 避免其他读取到旧值 const cwd = tool.cli.handlePathArg(typeof cliArg[`--cwd`] === `string` ? cliArg[`--cwd`] : process.cwd()); process.chdir(cwd); } { // 仅查看版本号 cliArg[`--version`] && (print(packageJson.version) || process.exit()); } const { initHandle, plugin, saveLog, build } = business; let shareConfig = {}; const { templateFn, configFileFn, checkEnv } = initHandle(); templateFn({ cliArg, version: packageJson.version }); const configFile = configFileFn({ cliArg }); const base64config = Buffer.from((0, _stringify.default)(cliArg)).toString(`base64`); // 以 base64 方式向 `node server.js` 传送命令行参数 const os = require(`os`); const sharePath = path.normalize(`${os.tmpdir}/publicStore_${(0, _now.default)()}.json`); // 此文件用于 run.js 与 server.js 共享变量 new _promise.default(async () => { var _context2; // 显示程序信息, 例如版本号, logo const vTag = `version: `; const logText = require(`fs`).readFileSync(`${__dirname}/util/logo.txt`, `utf8`); const versionLogo = logText.replace(new RegExp(`(${vTag})(.*)`), (match, $1, $2) => { const vStr = build.getBuildStr(packageJson); const vLength = vStr.length; const vLine = vLength > $2.length // 如果版本号替换到版本标志后面 ? `${$1}${vStr}` : match.replace(new RegExp(`(${vTag})(.{${vLength}})`), `$1${vStr}`); return vLine; }); (0, _includes.default)(_context2 = process.argv).call(_context2, `--log-line`) === false && print(versionLogo); }); new _promise.default(async () => { // 检查运行环境 if (checkEnv() === false) { print(cli.colors.red(`node 版本应大于 v10.12.0`)); process.exit(); } }); new _promise.default(async () => { // 检查更新 if (Boolean(cliArg[`--no-update`]) === false) { const { name, version } = packageJson; const { local, server } = await tool.npm.checkUpdate(name, { version }).catch(err => print(`Check for update failed: ${err}`)); if (server && lib.compareVersions.compare(local, server, `<`)) { const msg = tool.string.removeLeft(` New version has been released: ${server} Your current version is: ${local} View updated features: https://wll8.github.io/mockm/dev/change_log.html?update=${local},${server} `); print(cli.colors.yellow(msg)); } } }); new _promise.default(async () => { var _context3, _context4; // 启动 server.js let log = ``; const nodeArg = typeof cliArg[`--node-options`] === `string` ? cliArg[`--node-options`] : ``; const arr = (0, _filter.default)(_context3 = [nodeArg, serverPath, ...(0, _slice.default)(_context4 = process.argv).call(_context4, 2), `_base64=${base64config}`, `_share=${sharePath}`]).call(_context3, item => (0, _trim.default)(item).call(item) !== ``); const cp = new ProcessManager(arr); cp.on(`stdout`, data => { process.stdout.write(data); log = String(data); }); cp.on(`stderr`, data => { process.stderr.write(data); log = String(data); }); cp.on(`message`, ({ action, data } = {}) => { if (action === `reboot`) { cp.reboot(0); } if (action === `config`) { cp.autoReStart = data.guard; } }); cp.on(`close`, () => { if (log.match(/killProcess:/)) { // 保存错误日志 saveLog({ code: ``, logStr: log, logPath: shareConfig._errLog }); } }); function killProcess() { cp.kill(); process.exit(); } process.on(`SIGTERM`, killProcess); process.on(`SIGINT`, killProcess); process.on(`uncaughtException`, killProcess); process.on(`unhandledRejection`, killProcess); const { showLocalInfo, remoteServer } = plugin(); tool.control.awaitTrue({ // 等待 sharePath 文件存在, 期望 config 已经存入 condition: () => tool.file.hasFile(sharePath), timeout: 60e3 }).then(() => { const share = tool.file.fileStore(sharePath); shareConfig = share.get(`config`); const store = tool.file.fileStore(shareConfig._store); store.set(`note.remote`, {}); showLocalInfo({ store, shareConfig }); if (shareConfig.remote) { // 如果启用远程则进行相关功能处理 remoteServer({ store, shareConfig }).catch(err => console.log(`err`, err)); } }).catch(err => { console.log(`err`, err); print(`Start timeout, please check whether the environment or configuration is wrong`); process.exit(); }); });