一、操作流程
# 编译模式 mode
# start 本地调试
# publish 发布代码
# 启动脚本 file
# dev.js 本地调试
# build.js 发布代码
执行npm run [mode]
回车后,通过键盘上下按键选择要编译的具体项目,如下所示:
选择完项目后直接回车,会出现选择运营的环境,选完回车即可
编译完成后,界面会显示项目运行中,就是项目在本地调试已启动成功
二、npm run start|publish
执行命令npm run [mode]
即可唤起可视化编译界面,实际就是执行script
目录下的js
文件,如下所示:
{
"name": "uniapp",
"scripts": {
"start": "node ./script/dev.js", // 本地调试
"publish": "node ./script/build.js" // 发布代码
}
}
三、可视化执行代码
整体逻辑就是跟deploy.sh
文件的一致,修改manifest.json
=>打包代码=>上传代码,这里主要涉及到3个npm
库。
3.1、inquirer
(文档)
交互核心就是使用inquirer
来展现可供用户操作的选项,返回的内容就是list
中选中的value
值
// 选择运行项目
const { project } = await inquirer.prompt([
{
type: 'list',
message: '请选择您要运行的项目:',
name: 'project',
choices: [
{
key: '0',
name: '项目',
value: 'xx'
}
]
}
])
// 选择运行环境
const { environment } = await inquirer.prompt([
{
type: 'list',
message: '请选择您要运行的环境:',
name: 'environment',
choices: [
{
key: '0',
name: '测试环境',
value: 'stage'
},
{
key: '1',
name: '仿真环境',
value: 'simula'
},
{
key: '2',
name: '生产环境',
value: 'prod'
}
]
}
])
3.2、execa
(文档)
命令执行核心就是使用execa
,比如npm
、scp
、node
这些都可以通过execa
来实现运行。类似用法如下所示:
/**
* 修改mainifest.json
* @param environment
* @param project
* @param type
* @returns {Promise<void>}
*/
async function runManifest (environment, project, type) {
const manifestName = `./key/manifest_${environment}_${project}_${type}.js`
const execaManifest = () => execa('node', [manifestName], { stdio: 'inherit' })
await runTask('修改配置', execaManifest)
}
/**
* 启动项目
* @param project
* @returns {Promise<void>}
*/
async function runNpm (environment, project) {
const npmCli = `${environment}:${npmTypeMap[project]}-${project}`
const execaNpm = () => execa('npm run', [npmCli], { stdio: 'inherit' })
await runTask('打包项目', execaNpm)
}
/**
* 发布微信小程序代码
* @returns {Promise<void>}
*/
async function uploadWeixin () {
const execaUpload = () => execa('node', ['./key/upload.js'], { stdio: 'inherit' })
await runTask('发布代码', execaUpload)
}
/**
* H5上传代码到服务器
* @param environment
* @param project
* @returns {Promise<void>}
*/
async function uploadH5 (environment, project) {
const ip = h5Ip[environment]
const uploadPath = `root@${ip}:/app/poseidon/html/${project}`
console.log('uploadH5=>uploadPath=>', uploadPath)
const execaUpload = () => execa('scp', ['-r', './dist/build/h5/*', uploadPath], { stdio: 'inherit' })
await runTask('上传代码到服务器', execaUpload)
}
3.3、ora
(文档)
打印信息的作用,调用ora().start()
提示某环节已启动,实例调用succeed
打印该环节已成功结束,实例调用fail
打印该环节执行失败,可参考如下写好的方法:
/**
* 执行任务
* @param taskName
* @param task
* @returns {Promise<void>}
*/
async function runTask (taskName, task) {
const s = ora().start(`${taskName} 执行中 `)
try {
await task()
s.succeed(`${taskName} 执行完成!`)
} catch (e) {
s.fail(`${taskName} 执行失败!`)
console.error(`失败原因:${e.toString()}`)
}
}