@fxext/cli
Version:
fanxing miniapp cli
233 lines (219 loc) • 5.85 kB
JavaScript
const log = require('./log');
const fs = require('fs-extra');
const path = require('path');
const { spawn } = require('child_process');
const ora = require('ora');
const inquirer = require('inquirer');
const { errorHandler } = require('./utils');
const projectConfig = require('./project.config.json');
const packageTpl = require('./package_tpl.json');
const appJson = require('./app.json');
async function main(projectName) {
const { miniAppMode, miniAppId } = await selectAppMode();
let layout = [];
if (miniAppMode === '主播模式') {
layout = await selectLayoutType();
}
const buildConfig = await selectFramework(layout);
if (!buildConfig.length) {
process.exit(0);
}
fs.ensureDirSync(projectName);
process.chdir(projectName);
const ROOT = process.cwd();
log.hint(`\n初始化项目目录 ${ROOT}`);
try {
await generateFiles(ROOT, projectName, buildConfig, miniAppMode, miniAppId);
} catch (error) {
log.error(error);
return;
}
const spinner = ora('正在安装酷狗直播小程序依赖').start();
try {
await installDep(ROOT);
spinner.succeed('依赖安装完毕.');
} catch (err) {
spinner.fail('依赖安装失败.');
throw err;
}
log.hint(`\n初始化项目目录完成`);
const cocosProjectItems = buildConfig.filter(item => item.framework === 'cocos').map(item => item.layoutType);
if (cocosProjectItems.length) {
log.hint(`\n请将Cocos游戏项目初始化在${cocosProjectItems.join(',')}目录下`);
}
}
// 选择小程序模式
async function selectAppMode() {
const { miniAppMode, miniAppId } = await inquirer.prompt([
{
type: 'input',
message: '请输入小程序appId',
name: 'miniAppId',
validate: (value) => {
const appIdStr = String(value).trim();
if (appIdStr.length) {
return true;
}
return '请输入小程序appId';
}
},
{
type: 'list',
message: '请选项小程序模式',
name: 'miniAppMode',
choices: [
{
name: '主播模式'
},
{
name: '用户模式'
}
]
}
]);
return { miniAppMode, miniAppId };
}
// 选择布局类型
async function selectLayoutType() {
const { layout } = await inquirer.prompt([
{
type: 'checkbox',
message: '请选择终端的布局类型(可多选)',
name: 'layout',
choices: [
new inquirer.Separator('主播端'),
{
name: 'Web面板',
value: 'm',
},
{
name: '伴侣面板',
value: 'streamer_pc'
},
new inquirer.Separator('观众端'),
{
name: 'Web面板或浮窗',
value: 'm'
},
]
}
]);
return layout;
}
// 选择框架
async function selectFramework(layout) {
const choices = [
{
name: 'react'
},
{
name: 'vue'
},
{
name: 'cocos'
}
];
let buildConfig = [];
if (layout.length) {
if (layout.includes('m')) {
const { framework } = await inquirer.prompt([
{
type: 'list',
message: '请选项Web面板类型(m)使用框架',
name: 'framework',
choices
}
]);
buildConfig.push({
layoutType: 'm',
framework
});
}
if (layout.includes('streamer_pc')) {
const { framework } = await inquirer.prompt([
{
type: 'list',
message: '请选项伴侣面板类型(streamer_pc)使用框架',
name: 'framework',
choices
}
]);
buildConfig.push({
layoutType: 'streamer_pc',
framework
});
}
} else {
const { framework } = await inquirer.prompt([
{
type: 'list',
message: '请选择项目使用框架',
name: 'framework',
choices
}
]);
buildConfig.push(...[
{
layoutType: 'm',
framework
},
{
layoutType: 'streamer_pc',
framework
}
]);
}
return buildConfig;
}
// 安装项目依赖
async function installDep(projectDir) {
return new Promise((resolve, reject) => {
const installation = spawn('npm', ['install'], {
cwd: projectDir,
stdio: 'ignore',
shell: process.platform === 'win32',
});
installation.on('close', code => {
if (code === 0) {
resolve();
} else {
reject(code);
}
});
});
}
async function generateFiles(projectDir, projectName, buildConfig, miniAppMode, miniAppId) {
try {
for (const item of buildConfig) {
const { framework, layoutType } = item;
fs.ensureDirSync(path.join(projectDir, layoutType));
if (framework !== 'cocos') {
const TEMPLATE_PATH = path.join(__filename, `../template/${framework}/${layoutType}`);
fs.copySync(TEMPLATE_PATH, path.join(projectDir, layoutType));
}
fs.writeJsonSync(path.join(projectDir, layoutType, 'app.json'), appJson, { spaces: 2 });
}
const appIdStr = String(miniAppId).trim();
// 替换项目名
projectConfig.name = projectName;
packageTpl.name = projectName;
// 替换项目配置builder信息
projectConfig.builder = {
...projectConfig.builder,
buildConfig,
appMode: miniAppMode === '主播模式' ? 0 : 1,
appId: appIdStr,
}
fs.writeJsonSync(path.join(projectDir, 'project.config.json'), projectConfig, { spaces: 2 });
fs.writeJsonSync(path.join(projectDir, 'package.json'), packageTpl, { spaces: 2 });
// 生成gitignore
fs.writeFileSync(path.join(projectDir, '.gitignore'),
`node_modules
dist
release`);
} catch (error) {
console.error(error);
errorHandler(`生成项目文件失败`, err.message);
}
}
module.exports = main;