先创建一个项目
vue或者react都行,用来开发GUI视图功能
pnpm create vite my-vue-app --template vue
根目录新建bin文件夹
bin 文件夹下新建
index.js
和ui.js
,用commander库设置子命令,
// index.js
#!/usr/bin/env node
const program = require('commander')
program
.command('ui')
.description('start GUI🚀')
.action(()=>{
// 子命令执行的函数 这里通过ui.js文件导出该函数
require('./ui')()
})
// 同样的方式设置其它子命令
// program
// .command('other')
// .description('other')
// .action(()=>{
// fn()
// })
program.parse(process.argv);
使用 inquirer 库来实现询问式的交互
//ui.js
const inquirer = require('inquirer')
const chalk = require('chalk')
const path = require('path')
const spawn = require('cross-spawn') // 用于生成子进程
async function start () {
console.log(chalk.green('🚀 Starting GUI at localhost:8088, wait a moment'));
const serverDir = path.join(__dirname, '..', 'server')
let server;
server = spawn('node', [path.join(serverDir, 'app.js')])
// 捕获子进程的输出
server.stdout.on('data', (data) => {
console.log(`${data}`)
})
// 捕获子进程的错误
server.stderr.on('data', (data) => {
console.log(`${data}`)
})
// 跟踪子进程的状态
server.on('close', (code) => {
console.log(`子进程退出,退出码 ${code}`)
})
// 监听子进程的退出
process.on('exit', function() {
server.kill()
})
}
module.exports = async() => {
inquirer.prompt([
{
type: 'list',
name: 'department',
message: '请选择部门',
choices: [
'云平台',
'系统开发'
]
},
{
type: 'input',
name: 'username',
message: '请输入姓名'
}
]).then((answers)=>{
// 获取用户输入参数
const { department, username } = answers
// 执行
start()
})
}
根目录创建server文件夹
server下创建app.js,node框架我使用的是express,也可以换成你喜欢的koa、nest都行
const express = require('express')
const path = require('path')
const { openUrl } = require('./utils')
const app = express()
const PORT = 8088
const server = require('http').Server(app)
const CACHE_CONTROL = 'no-store, no-cache, must-revalidate, private'
app.use(express.static(path.resolve(__dirname, '../dist'), { setHeaders }))
function setHeaders(res, path, stat) {
res.set('Cache-Control', CACHE_CONTROL)
}
server.listen(PORT, () => {
openUrl(`http://localhost:${PORT}`);
})
module.exports = server
utils.js用来放开发用到的一些工具函数
const { exec } = require('child_process')
/**
* @description:
* @param {*} url
* @return {*}
*/
function openUrl (url) {
switch (process.platform) {
// window系统使用以下命令在浏览器打开url
case "win32":
exec(`start ${url}`)
break;
// mac系统使用以下命令在浏览器打开url
case "darwin":
exec(`open ${url}`)
break;
default:
exec(`open ${url}`)
}
}
module.exports = {
openUrl
}
package.json配置bin选项
package.json添加bin和files选项,配置如下:
{
"name": "lemon-box",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite --port 8088",
"build": "vite build",
"preview": "vite preview"
},
"bin": {
"lemon": "./bin/index.js"
},
"files": [
"bin",
"server",
"dist",
"package.json"
],
"dependencies": {
"chalk": "3.0.0",
"commander": "^11.0.0",
"cross-spawn": "^7.0.3",
"express": "^4.18.2",
"fs-extra": "^11.1.1",
"inquirer": "8.2.5",
"os": "^0.1.2",
"vue": "^3.3.4",
"vue-router": "^4.2.4"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.2.3",
"vite": "^4.4.5"
}
}
本地测试
npm link
生成软链接- 命令行执行
lemon ui
,shell面板出现以下 就ok
➜ lemon-box lemon ui
? 请选择部门 云平台
? 请输入姓名 please
🚀 Starting GUI at localhost:8088, wait a moment
其它更多丰富的功能在此基础上进行扩展就行