oak-cli/src/create.ts

350 lines
10 KiB
TypeScript

import {
copyFolder,
checkFileExistsAndCreate,
readFile,
checkFileExists,
} from './file-handle';
import { checkFileExistsAndCreateType } from './enum';
import {
CNPM_BASE_URL,
CLI_VERSION,
USER_CONFIG_FILE_NAME,
CLI_NAME,
MINI_VERSION_URL,
CLI_BIN_NAME,
} from './config';
import {
packageJsonContent,
tsConfigJsonContent,
tsConfigBuildJsonContent,
tsConfigBuildPathsJsonContent,
tsConfigPathsJsonContent,
tsConfigMpJsonContent,
tsConfigWebJsonContent,
appJsonContentWithWeChatMp,
projectConfigContentWithWeChatMp,
oakConfigContentWithWeChatMp,
appJsonContentWithWeb,
oakConfigContentWithWeb,
} from './template';
import { PromptInput } from './interface';
import { join } from 'path';
import inquirer from 'inquirer';
import axios from 'axios';
import {
Success,
Error,
error,
primary,
success,
warn,
Warn,
} from './tip-style';
import shell from 'shelljs';
import { renameProject } from './rename';
const DEFAULT_PROJECT_NAME = 'oak_template';
const DEFAULT_PROJECT_TITLE = 'oak template project';
const prompt = [
{
type: 'input',
name: 'version',
message: 'version',
default: '1.0.0',
},
{
type: 'input',
name: 'title',
message: 'title of the project shown in App/Html'
},
{
type: 'input',
name: 'description',
message: 'description',
},
];
/**
* @name 检查项目名是否已存在
* @param dirName
*/
function checkProjectName(dirName: string, exists?: true) {
// 项目根路径
const rootPath = process.cwd() + '/' + dirName;
const isExists = checkFileExists(rootPath);
if (isExists && !exists) {
throw new global.Error(`Cannot create a project named ${success(
`"${dirName}"`
)} because a path with the same name exists.\nPlease choose a different project name.`);
}
else if (!isExists && exists) {
throw new global.Error(`${success(dirName)} is not a valid project dir.\nPlease choose a different project name.`)
}
}
/**
* @name 获取oak-cli最新版本号
* @returns
*/
async function getOakCliVersion() {
const res = await axios.get(CNPM_BASE_URL);
return res.data['dist-tags']['latest'];
}
/**
* @name 获取微信小程序稳定基础版本库
* @returns
*/
async function getMiniVersion() {
const res = await axios.get(MINI_VERSION_URL);
const versions: Array<any> = JSON.parse(res.data['json_data'])['total'];
const versionsSort = versions.sort((a: any, b: any) => {
return b['percentage'] - a['percentage'];
});
return versionsSort[0]['sdkVer'];
}
async function createWechatMpBoilplate(dir: string, isDev: boolean, isUpdate?: boolean) {
// 获取微信小程序稳定基础版本库
const miniVersion = await getMiniVersion();
// 获取小程序项目app.json内容
const appJsonWithWeChatMp = appJsonContentWithWeChatMp(isDev);
// 获取小程序项目project.config.json内容
const projectConfigWithWeChatMp = projectConfigContentWithWeChatMp(
USER_CONFIG_FILE_NAME,
DEFAULT_PROJECT_TITLE,
miniVersion
);
// 获取小程序项目oak.config.json内容
const oakConfigWithWeChatMp = oakConfigContentWithWeChatMp();
const appJsonPathWithWeChatMp = join(dir, 'src', 'app.json');
// 小程序项目project.config.json路径
const projectConfigPathWithWeChatMp = join(dir, 'src', 'project.config.json');
// 小程序项目project.config.json路径
const oakConfigPathWithWeChatMp = join(dir, 'src', USER_CONFIG_FILE_NAME);
// 创建小程序项目project.config.json
checkFileExistsAndCreate(
projectConfigPathWithWeChatMp,
projectConfigWithWeChatMp,
checkFileExistsAndCreateType.FILE,
isUpdate
);
// 创建小程序项目app.json
checkFileExistsAndCreate(
appJsonPathWithWeChatMp,
appJsonWithWeChatMp,
checkFileExistsAndCreateType.FILE,
isUpdate
);
// 创建小程序项目oak.config.json
checkFileExistsAndCreate(
oakConfigPathWithWeChatMp,
oakConfigWithWeChatMp,
checkFileExistsAndCreateType.FILE,
isUpdate
);
}
async function createWebBoilplate(
dir: string,
isDev: boolean,
isUpdate?: boolean
) {
// 获取web项目app.json内容
const appJsonWithWeb = appJsonContentWithWeb(isDev);
// 获取web项目oak.config.json内容
const oakConfigWithWeb = oakConfigContentWithWeb();
const appJsonPathWithWeb = join(dir, 'src', 'app.json');
// web项目oak.config.json路径
const oakConfigPathWithWeb = join(dir, 'src', USER_CONFIG_FILE_NAME);
// 创建web项目app.json
// checkFileExistsAndCreate(
// appJsonPathWithWeb,
// appJsonWithWeb,
// checkFileExistsAndCreateType.FILE,
// isUpdate
// );
// 创建web项目oak.config.json
checkFileExistsAndCreate(
oakConfigPathWithWeb,
oakConfigWithWeb,
checkFileExistsAndCreateType.FILE,
isUpdate
);
}
export async function create(dirName: string, cmd: any) {
const nameOption = {
type: 'input',
name: 'name',
message: `name`,
default: dirName,
};
prompt.unshift(nameOption);
const isDev = cmd.dev ? true : false;
const { name, version, title, description }: PromptInput = await inquirer.prompt(
prompt
);
// 获取package.json内容
const packageJson = packageJsonContent({
name: DEFAULT_PROJECT_NAME, // 后面再统一rename
version,
description,
cliVersion: CLI_VERSION,
cliName: CLI_NAME,
cliBinName: CLI_BIN_NAME,
isDev,
});
// 获取tsconfig.json内容
const tsconfigJson = tsConfigJsonContent();
const tsConfigBuildJson = tsConfigBuildJsonContent();
const tsConfigBuildPathsJson = tsConfigBuildPathsJsonContent();
const tsConfigPathsJson = tsConfigPathsJsonContent();
const tsConfigMpJson = tsConfigMpJsonContent();
const tsConfigWebJson = tsConfigWebJsonContent();
// 项目根路径
const rootPath = process.cwd() + '/' + dirName;
// package.json路径
const packageJsonPath = `${rootPath}/package.json`;
// tsconfig.json路径
const tsconfigJsonPath = `${rootPath}/tsconfig.json`;
// tsconfig.build.json路径
const tsConfigBuildJsonPath = `${rootPath}/tsconfig.build.json`;
// tsconfig.build.paths.json路径
const tsConfigBuildPathsJsonPath = `${rootPath}/tsconfig.build.paths.json`;
// tsconfig.paths.json路径
const tsconfigPathsJsonPath = `${rootPath}/tsconfig.paths.json`;
// tsconfig.mp.json路径
const tsConfigMpJsonPath = `${rootPath}/tsconfig.mp.json`;
// tsconfig.web.json路径
const tsConfigWebJsonPath = `${rootPath}/tsconfig.web.json`;
// web项目根路径
const webRootPath = `${rootPath}/web`;
// 小程序项目根路径
const weChatMpRootPath = `${rootPath}/wechatMp`;
// 被复制的文件夹路径
const currentPath = join(__dirname, '..', 'template');
//检查项目名是否存在
checkProjectName(dirName);
try {
// 创建根目录
checkFileExistsAndCreate(rootPath);
// 创建package.json
checkFileExistsAndCreate(
packageJsonPath,
packageJson,
checkFileExistsAndCreateType.FILE
);
// 创建tsconfig.json
checkFileExistsAndCreate(
tsconfigJsonPath,
tsconfigJson,
checkFileExistsAndCreateType.FILE
);
// 创建tsconfig.build.json
checkFileExistsAndCreate(
tsConfigBuildJsonPath,
tsConfigBuildJson,
checkFileExistsAndCreateType.FILE
);
// 创建tsconfig.build.paths.json
checkFileExistsAndCreate(
tsConfigBuildPathsJsonPath,
tsConfigBuildPathsJson,
checkFileExistsAndCreateType.FILE
);
// 创建tsconfig.paths.json
checkFileExistsAndCreate(
tsconfigPathsJsonPath,
tsConfigPathsJson,
checkFileExistsAndCreateType.FILE
);
// 创建tsconfig.mp.json
checkFileExistsAndCreate(
tsConfigMpJsonPath,
tsConfigMpJson,
checkFileExistsAndCreateType.FILE
);
// 创建tsconfig.web.json
checkFileExistsAndCreate(
tsConfigWebJsonPath,
tsConfigWebJson,
checkFileExistsAndCreateType.FILE
);
// 复制项目文件
copyFolder(currentPath, rootPath);
await createWechatMpBoilplate(weChatMpRootPath, isDev);
await createWebBoilplate(webRootPath, isDev);
if (!shell.which('npm')) {
Warn(warn('Sorry, this script requires npm! Please install npm!'));
shell.exit(1);
}
/* Success(`${success(`Waiting...`)}`);
Success(`${success(`Dependencies are now being installed`)}`);
shell.cd(dirName).exec('npm install'); */
renameProject(rootPath, name, title, DEFAULT_PROJECT_NAME, DEFAULT_PROJECT_TITLE);
Success(
`${success(
`Successfully created project ${primary(
name
)}, directory name is ${primary(dirName)}`
)}`
);
} catch (err) {
Error(error('create error'));
Error(error(err));
}
}
export async function update(dirName: string, subDirName: string, cmd: any) {
const isDev = cmd.dev ? true : false;
try {
// 需要拷贝的路径
const destPath = join(process.cwd(), dirName, subDirName);
const templatePath = join(__dirname, '..', 'template');
//检查项目名是否存在
checkProjectName(dirName, true);
if (subDirName === 'src') {
const fromPath = join(templatePath, subDirName);
copyFolder(fromPath, destPath, true);
}
else if (subDirName.startsWith('wechatMp')) {
const fromPath = join(templatePath, 'wechatMp');
copyFolder(fromPath, destPath, true);
await createWechatMpBoilplate(destPath, isDev, true);
}
else {
throw new global.Error(`Cannot recoganize ${success(
`"${subDirName}"`
)} for update.\n Please choose src/wechatMp%.`);
}
Success(
`${success(
`Successfully update directory ${primary(subDirName)} for project ${primary(dirName)}}`
)}`
);
}
catch (err) {
console.error(error((err as Error).message));
}
}