From b631ff4a093f2af28fa4529d8d6f5ce5b6c1b1c8 Mon Sep 17 00:00:00 2001 From: xion Date: Thu, 5 Dec 2024 20:53:21 +0800 Subject: [PATCH] add pm2 --- package.json | 2 +- rollup.config.js | 5 ++++- src/command/config.ts | 20 +++++++++++++++----- src/command/init.ts | 29 +++++++++++++++++++++++++---- src/uitls/npm.ts | 29 +++++++++++++++++++++++++++++ 5 files changed, 74 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 2ef09ec..b7b6d9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kevisual/envision-cli", - "version": "0.0.13", + "version": "0.0.14", "description": "envision command tools", "main": "dist/index.js", "type": "module", diff --git a/rollup.config.js b/rollup.config.js index f94e4fe..9ee172a 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -5,10 +5,13 @@ import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; import path from 'path'; +import fs from 'fs'; + import esbuild from 'rollup-plugin-esbuild'; import alias from '@rollup/plugin-alias'; import replace from '@rollup/plugin-replace'; +const pkgs = JSON.parse(fs.readFileSync('./package.json', 'utf-8')); /** * @type {import('rollup').RollupOptions} */ @@ -23,7 +26,7 @@ const config = { plugins: [ replace({ preventAssignment: true, // 防止意外赋值 - VERSION: JSON.stringify('1.0.0'), + VERSION: JSON.stringify(pkgs.version || '1.0.0'), }), alias({ // only esbuild needs to be configured diff --git a/src/command/config.ts b/src/command/config.ts index 23a7f49..59c1ff0 100644 --- a/src/command/config.ts +++ b/src/command/config.ts @@ -146,14 +146,27 @@ const setCommand = new Command('set') when: () => value === 'not_input', }, ]); - if (answer.value === 'not_input') { + if (value === 'not_input' && !answer.value) { value = ''; } - value = answer.value || value; if (key === 'workdir') { await setWorkdir({ workdir: value }); return; } + const transformValue = (value: string) => { + if (value === 'true') { + return true; + } + if (value === 'false') { + return false; + } + // 如果是数字 + if (!isNaN(Number(value))) { + return Number(value); + } + return value; + }; + const newValue = transformValue(value); if (key && value) { flag = true; if (key === 'dev') { @@ -166,9 +179,6 @@ const setCommand = new Command('set') config[key] = value; } console.log(chalk.green(`set ${key} success:`, config.key)); - } else if (key) { - flag = true; - delete config[key]; } if (flag) { writeConfig(config); diff --git a/src/command/init.ts b/src/command/init.ts index 4046954..07e5000 100644 --- a/src/command/init.ts +++ b/src/command/init.ts @@ -4,8 +4,8 @@ import path from 'path'; import fs from 'fs'; import { chalk } from '@/module/chalk.ts'; import inquirer from 'inquirer'; -import { spawn } from 'child_process'; -import { installDeps } from '@/uitls/npm.ts'; +import { spawn, spawnSync } from 'child_process'; +import { checkPm2, installDep, installDeps } from '@/uitls/npm.ts'; const command = new Command('init').description('初始化应用').action((optison) => { console.log('init'); @@ -31,6 +31,7 @@ const initMain = async () => { main: 'dist/app.mjs', scripts: { start: 'node dist/app.mjs', + pm2: 'pm2 start dist/app.mjs --name main-app', }, dependencies: { '@kevisual/router': 'latest', @@ -118,6 +119,7 @@ const mainApp = new Command('main') .option('-s, --start', '启动main应用') .option('-r, --restart', '重启main应用') .option('-e, --exit', '停止main应用') + .option('-p, --pm2', '使用pm2管理,只作为启动') .action(async (options) => { if (options.init) { await initMain(); @@ -142,13 +144,24 @@ const mainApp = new Command('main') } // 打开日志文件(追加模式) const logStream = fs.openSync(logFile, 'a'); - const childProcess = spawn('node', ['dist/app.mjs'], { + if (options.pm2) { + if (!checkPm2()) { + console.log('安装pm2'); + installDep({ isGlobal: true, sync: true, dep: 'pm2' }); + console.log(chalk.green('安装pm2成功')); + } + } + let comm = options.pm2 ? 'pm2' : 'node'; + const args = options.pm2 ? ['start', 'dist/app.mjs', '--name', 'main-app'] : ['dist/app.mjs']; + const childProcess = spawn(comm, args, { cwd: getConfig().mainAppPath, stdio: ['ignore', logStream, logStream], // 忽略 stdio, 重定向到文件 detached: true, // 使子进程独立运行 }); childProcess.unref(); // 使子进程独立运行 - writeConfig({ ...getConfig(), mainAppPid: childProcess.pid }); + if (!options.pm2) { + writeConfig({ ...getConfig(), mainAppPid: childProcess.pid }); + } }; const config = getConfig(); if (!config.mainAppPath) { @@ -180,9 +193,17 @@ const mainApp = new Command('main') process.kill(config.mainAppPid); } writeConfig({ ...config, mainAppPid: null }); + console.log('main app 已经停止'); } } }); +const mainPathCommand = new Command('path').action(() => { + const config = getConfig(); + const appPath = path.resolve(config.mainAppPath); + + console.log(`cd ${appPath}`); +}); +mainApp.addCommand(mainPathCommand); const mainLogCommand = new Command('log') .option('-t, --tail', '查看日志') diff --git a/src/uitls/npm.ts b/src/uitls/npm.ts index 150d036..d8d85d8 100644 --- a/src/uitls/npm.ts +++ b/src/uitls/npm.ts @@ -8,7 +8,36 @@ export const checkPnpm = () => { return false; } }; +export const checkPm2 = () => { + try { + spawnSync('pm2', ['--version']); + return true; + } catch (e) { + return false; + } +}; +type InstallDepOptions = { + appPath?: string; + dep: string; + isGlobal?: boolean; + sync?: boolean; +}; +export const installDep = (opts: InstallDepOptions) => { + const { appPath, dep } = opts; + const params = []; + const syncSpawn = opts.sync ? spawnSync : spawn; + if (opts.isGlobal) { + params.push('-g'); + } + if (checkPnpm()) { + params.push('add', dep); + syncSpawn('pnpm', params, { cwd: appPath, stdio: 'inherit', env: process.env }); + } else { + params.push('install', dep); + syncSpawn('npm', params, { cwd: appPath, stdio: 'inherit', env: process.env }); + } +}; type InstallDepsOptions = { appPath: string; isProduction?: boolean;