@opentiny/tiny-toolkit-pro
Version:
TinyPro Vue:开箱即用、前后端分离的 Vue 后台管理模板
435 lines • 34.5 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.installDependencies = void 0;
const yaml_1 = require("yaml");
const path = __importStar(require("path"));
const dotenv = __importStar(require("dotenv"));
const fs_extra_1 = require("fs-extra");
const chalk_1 = __importDefault(require("chalk"));
const cross_spawn_1 = __importDefault(require("cross-spawn"));
const inquirer_1 = __importDefault(require("inquirer"));
const cli_devkit_1 = require("@opentiny/cli-devkit");
const interfaces_1 = require("./interfaces");
const utils_1 = __importDefault(require("./utils"));
const fs_1 = require("fs");
const log = (0, cli_devkit_1.logs)('tiny-toolkit-pro');
const VUE_TEMPLATE_PATH = 'tinyvue';
const DEFAULT_PROJECT_NAME = 'tiny-pro';
/**
* 询问创建项目的描述,使用的技术栈
*
* @returns object { description: 项目描述,framework: 框架, name: 项目名称 ,serverFramework:使用技术栈, dialect:数据库,DB_host:数据库地址,DB_port:数据库端口,database:数据库名称,username:数据库用户名,password:数据库密码,}
*/
const getProjectInfo = () => {
const question = [
{
type: 'input',
name: 'name',
message: '请输入项目名称:',
default: DEFAULT_PROJECT_NAME,
// 必填校验
validate: (input) => Boolean(input),
},
{
type: 'input',
name: 'description',
message: '请输入项目描述:',
default: '基于TinyPro套件创建的中后台系统',
},
{
type: 'list',
name: 'framework',
message: '请选择您希望使用的客户端技术栈:',
choices: [{ name: 'vue', value: VUE_TEMPLATE_PATH }],
default: VUE_TEMPLATE_PATH,
prefix: '*',
},
{
type: 'list',
name: 'serverFramework',
message: '请选择您希望使用的服务端技术栈:',
choices: [
// { name: 'Egg.js', value: ServerFrameworks.EggJs },
// { name: 'Spring Cloud', value: ServerFrameworks.SpringCloud },
{ name: 'Nest.js', value: interfaces_1.ServerFrameworks.NestJs },
{ name: '暂不配置', value: interfaces_1.ServerFrameworks.Skip },
],
default: interfaces_1.ServerFrameworks.NestJs,
prefix: '*',
when: (answers) => answers.framework === VUE_TEMPLATE_PATH,
},
{
type: 'list',
name: 'buildTool',
message: '请选择你想要的构建工具: ',
choices: [
{ name: 'Vite', value: interfaces_1.BuildTool.Vite },
{ name: 'Webpack', value: interfaces_1.BuildTool.Webpack },
{ name: 'Rspack', value: interfaces_1.BuildTool.Rspack },
{ name: 'Farm', value: interfaces_1.BuildTool.Farm },
],
default: interfaces_1.BuildTool.Vite,
prefix: '*',
},
{
type: 'list',
name: 'serverConfirm',
message: '请确保已安装数据库服务(参考文档 https://www.opentiny.design/tiny-cli/docs/toolkits/pro#database):',
choices: [
{ name: '已完成数据库服务安装,开始配置', value: true },
{ name: '暂不配置服务端', value: false },
],
prefix: '*',
when: (answers) => answers.framework === VUE_TEMPLATE_PATH &&
answers.serverFramework !== interfaces_1.ServerFrameworks.Skip,
},
{
type: 'input',
name: 'redisHost',
message: '请输入Redis地址:',
default: 'localhost',
prefix: '*',
when: (answers) => answers.serverConfirm,
},
{
type: 'input',
name: 'redisPort',
message: '请输入Redis端口:',
default: 6379,
prefix: '*',
when: (answers) => answers.serverConfirm,
},
{
type: 'list',
name: 'dialect',
message: '请选择数据库类型:',
choices: [
{ name: 'MySql', value: 'mysql' },
{ name: '暂不配置', value: '' },
],
default: 'mysql',
prefix: '*',
when: (answers) => answers.serverConfirm,
},
{
type: 'input',
name: 'host',
message: '请输入数据库地址:',
default: 'localhost',
prefix: '*',
when: (answers) => answers.dialect,
},
{
type: 'input',
name: 'port',
message: '请输入数据库端口:',
default: 3306,
prefix: '*',
when: (answers) => answers.host,
},
{
type: 'input',
name: 'database',
message: '请输入数据库名称:',
prefix: '*',
validate: (input) => Boolean(input),
when: (answers) => answers.host,
},
{
type: 'input',
name: 'username',
message: '请输入登录用户名:',
default: 'root',
prefix: '*',
when: (answers) => answers.host,
},
{
type: 'password',
name: 'password',
message: '请输入密码:',
prefix: '*',
when: (answers) => answers.host,
},
];
return inquirer_1.default.prompt(question);
};
/**
* 同步创建服务端项目文件目录、文件
* @answers 询问客户端问题的选择值
* @dbAnswers 询问服务端配置的选择值
*/
const createServerSync = (answers) => {
var _a, _b, _c, _d, _e, _f;
const { name, serverFramework } = answers;
// 复制服务端相关目录
const serverFrom = utils_1.default.getTemplatePath(`${serverFramework}`);
const serverTo = utils_1.default.getDistPath(`${name}/${serverFramework}`);
const config = {
DATABASE_HOST: answers.dialect && ((_a = answers.host) !== null && _a !== void 0 ? _a : 'localhost'),
DATABASE_PORT: answers.dialect && Number((_b = answers.port) !== null && _b !== void 0 ? _b : 3306),
DATABASE_USERNAME: answers.dialect && ((_c = answers.username) !== null && _c !== void 0 ? _c : 'root'),
DATABASE_PASSWORD: answers.dialect && ((_d = answers.password) !== null && _d !== void 0 ? _d : 'root'),
DATABASE_NAME: answers.dialect && answers.database,
DATABASE_SYNCHRONIZE: false,
DATABASE_AUTOLOADENTITIES: true,
AUTH_SECRET: 'secret',
REDIS_SECONDS: 7200,
REDIS_HOST: (_e = answers.redisHost) !== null && _e !== void 0 ? _e : 'localhost',
REDIS_PORT: Number((_f = answers.redisPort) !== null && _f !== void 0 ? _f : 6379),
EXPIRES_IN: '2h',
PAGINATION_PAGE: 1,
PAGINATION_LIMIT: 10,
};
const envStr = objToEnv(config);
const overwriteDockerComposeConfig = {
// @see https://hub.docker.com/_/mysql
// This variable is mandatory and specifies the password that will be set for the MySQL root superuser account.
MYSQL_ROOT_PASSWORD: config.DATABASE_PASSWORD,
MYSQL_DATABASE: config.DATABASE_NAME,
MYSQL_USER: config.DATABASE_USERNAME === 'root' ? undefined : config.DATABASE_NAME,
MYSQL_PASSWORD: config.DATABASE_USERNAME === 'root'
? undefined
: config.DATABASE_PASSWORD,
};
(0, fs_extra_1.copySync)(serverFrom, serverTo);
(0, fs_1.writeFileSync)(path.join(serverTo, '.env'), envStr);
const dockerComposeYaml = (0, fs_1.readFileSync)(path.join(serverTo, 'docker-compose.yml')).toString();
const yaml = (0, yaml_1.parse)(dockerComposeYaml);
const { services } = yaml;
const mysql = services.mysql;
mysql.environment = overwriteDockerComposeConfig;
(0, fs_1.writeFileSync)(path.join(serverTo, 'docker-compose.yml'), (0, yaml_1.stringify)(yaml));
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const objToEnv = (obj) => {
return Object.entries(obj)
.map(([key, value]) => {
const v = typeof value === 'string' ? `'${value}'` : value;
return [key, '=', v].join(' ');
})
.join('\n');
};
const packageJsonProcess = (buildTool, packages, currentPath) => {
const match = (pattern, items) => {
return items.filter((item) => pattern.test(item));
};
const removeDeps = () => {
const devDeps = interfaces_1.devDependencies[buildTool];
devDeps.forEach((devDep) => {
if (typeof devDep === 'string') {
packages.devDependencies[devDep] = undefined;
}
if (devDep instanceof RegExp) {
const deps = match(devDep, Object.keys(packages.devDependencies));
if (!deps.length) {
return;
}
deps.forEach((dep) => {
if (packages.devDependencies[dep]) {
packages.devDependencies[dep] = undefined;
}
});
}
});
const dependencies = interfaces_1.removeDependencies[buildTool];
dependencies.forEach((dep) => {
if (typeof dep === 'string') {
if (!packages.dependencies[dep]) {
return;
}
packages.dependencies[dep] = undefined;
}
if (dep instanceof RegExp) {
const keys = match(dep, Object.keys(packages.devDependencies));
keys.forEach((key) => {
if (!packages.dependencies[key]) {
return;
}
packages.dependencies[key] = undefined;
});
}
});
};
const replaceScript = (name, command) => {
packages.scripts[name] = command;
};
const removeScripts = () => {
const scripts = interfaces_1.removedCommand;
scripts.forEach((script) => {
replaceScript(script, undefined);
});
};
const replaceBuildCommand = () => {
const command = interfaces_1.buildCommand[buildTool];
replaceScript('build', command);
};
const replaceDevCommand = () => {
const command = interfaces_1.devCommand[buildTool];
replaceScript('start', command);
};
const remove = () => {
const removedPaths = interfaces_1.buildConfigs[buildTool];
const paths = removedPaths
.filter((removedPath) => (0, fs_1.existsSync)(path.join(currentPath, removedPath)))
.map((p) => path.join(currentPath, p));
if (!paths.length) {
return;
}
let willRemovePath = '';
try {
paths.forEach((removePath) => {
willRemovePath = removePath;
(0, fs_1.rmSync)(removePath, { recursive: true, force: true });
});
}
catch (_a) {
log.error(`删除${willRemovePath}错误`);
}
};
removeDeps();
removeScripts();
replaceBuildCommand();
replaceDevCommand();
return remove;
};
/**
* 同步创建客户端项目文件目录、文件
* @answers 询问客户端问题的选择值
* @dbAnswers 询问服务端配置的选择值
*/
const createProjectSync = (answers) => {
const { description, name, serverConfirm, buildTool } = answers;
const templatePath = interfaces_1.VueVersion.Vue3;
// 模板来源目录
const from = utils_1.default.getTemplatePath(templatePath);
// 复制模板的目标目录
const to = utils_1.default.getDistPath(serverConfirm ? `${name}/web` : name);
cli_devkit_1.fs.copyTpl(from, to);
// 将项目名称、描述写入 package.json中
try {
const packageJsonPath = path.join(to, 'package.json');
let packageJson = JSON.parse(cli_devkit_1.fs.readFileSync(packageJsonPath, { encoding: 'utf8' }));
packageJson = Object.assign(Object.assign({}, packageJson), { name, description });
const remove = packageJsonProcess(buildTool, packageJson, to);
cli_devkit_1.fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), {
encoding: 'utf8',
});
remove();
}
catch (e) {
log.error(e);
log.error('配置项目信息创建失败');
}
// 如果不对接服务端,全部接口采用mock
if (!serverConfirm) {
try {
const envPath = path.join(to, '.env');
const envConfig = dotenv.parse(cli_devkit_1.fs.readFileSync(envPath, { encoding: 'utf8' }));
delete envConfig.VITE_MOCK_IGNORE;
const config = Object.keys(envConfig)
.map((key) => `${key} = ${envConfig[key]}`)
.join('\n');
cli_devkit_1.fs.writeFileSync(envPath, config);
}
catch (e) {
log.error(e);
log.error('开启mock模式失败');
log.info('请手动配置env信息');
}
}
else {
// 如果对接服务端,执行文件复制及相关配置( WIP: 后台接口暂未全量完成,部分接口还是使用mock )
createServerSync(answers);
}
};
// 安装依赖
const installDependencies = (answers) => {
const prefix = cli_devkit_1.cliConfig.getBinName();
const { name, serverFramework, serverConfirm } = answers;
// egg服务端 安装依赖并启动
if (serverConfirm && serverFramework === interfaces_1.ServerFrameworks.EggJs) {
log.info('正在安装服务端 npm 依赖,安装过程需要几十秒,请耐心等待...');
const installServiceResult = cross_spawn_1.default.sync('npm', ['install'], {
cwd: `${name}/${serverFramework}/`,
stdio: 'inherit',
});
if (installServiceResult.status === 0) {
log.success('服务端 npm 依赖安装成功');
}
else {
throw new Error(installServiceResult.error);
}
}
// npm 依赖安装
log.info('正在安装客户端 npm 依赖,安装过程需要几十秒,请耐心等待...');
const installClientResult = cross_spawn_1.default.sync('npm', ['install'], {
cwd: serverConfirm ? `${name}/web` : `${name}/`,
stdio: 'inherit',
});
if (installClientResult.status === 0) {
log.success('客户端 npm 依赖安装成功');
}
else {
throw new Error(installClientResult.error);
}
/* prettier-ignore-start */
console.log(chalk_1.default.yellow('\n--------------------初始化成功,请按下面提示进行操作--------------------\n'));
if (serverConfirm) {
console.log(chalk_1.default.green(`${chalk_1.default.yellow(`$ cd ${name}/web && npm run start`)} # 开启web开发环境`));
console.log(chalk_1.default.green(`${chalk_1.default.yellow(serverFramework === interfaces_1.ServerFrameworks.SpringCloud
? `请查看 ${name}/${serverFramework}/README_CN.md `
: `$ cd ${name}/${serverFramework} && npm run dev`)} # 开启server开发环境`));
}
else {
console.log(chalk_1.default.green(`${chalk_1.default.yellow(`$ cd ${name} && ${prefix} start`)} # 可一键开启项目开发环境`));
}
console.log(chalk_1.default.green(`${chalk_1.default.yellow(`$ ${prefix} help`)} # 可查看当前套件的详细帮助`));
console.log(chalk_1.default.green(`\n建议将现有初始化的代码提交一次到master分支, 方便后续切换到 ${chalk_1.default.yellow('daily/x.y.z')} 分支进行开发`));
console.log(chalk_1.default.yellow('\n-------------------- 技术支持:官方小助手微信opentiny-official --------------------\n'));
};
exports.installDependencies = installDependencies;
exports.default = async () => {
// 拷贝模板到当前目录
let projectInfo;
try {
// 创建项目文件夹及文件
projectInfo = await getProjectInfo();
createProjectSync(projectInfo);
}
catch (e) {
log.error(e);
log.error('项目模板创建失败');
return;
}
// 初始化数据库
// 初始化不应该在cli做,而是在后端
// 安装依赖
log.info('初始化成功,请运行npm i或tiny i 安装依赖');
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvaW5pdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtCQUF3QztBQUN4QywyQ0FBNkI7QUFDN0IsK0NBQWlDO0FBQ2pDLHVDQUFvQztBQUNwQyxrREFBMEI7QUFDMUIsOERBQWdDO0FBQ2hDLHdEQUF3RDtBQUN4RCxxREFBMkQ7QUFDM0QsNkNBV3NCO0FBQ3RCLG9EQUE0QjtBQUM1QiwyQkFBcUU7QUFFckUsTUFBTSxHQUFHLEdBQUcsSUFBQSxpQkFBSSxFQUFDLGtCQUFrQixDQUFDLENBQUM7QUFDckMsTUFBTSxpQkFBaUIsR0FBRyxTQUFTLENBQUM7QUFDcEMsTUFBTSxvQkFBb0IsR0FBRyxVQUFVLENBQUM7QUFFeEM7Ozs7R0FJRztBQUNILE1BQU0sY0FBYyxHQUFHLEdBQXlCLEVBQUU7SUFDaEQsTUFBTSxRQUFRLEdBQW9DO1FBQ2hEO1lBQ0UsSUFBSSxFQUFFLE9BQU87WUFDYixJQUFJLEVBQUUsTUFBTTtZQUNaLE9BQU8sRUFBRSxVQUFVO1lBQ25CLE9BQU8sRUFBRSxvQkFBb0I7WUFDN0IsT0FBTztZQUNQLFFBQVEsRUFBRSxDQUFDLEtBQWEsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztTQUM1QztRQUNEO1lBQ0UsSUFBSSxFQUFFLE9BQU87WUFDYixJQUFJLEVBQUUsYUFBYTtZQUNuQixPQUFPLEVBQUUsVUFBVTtZQUNuQixPQUFPLEVBQUUscUJBQXFCO1NBQy9CO1FBQ0Q7WUFDRSxJQUFJLEVBQUUsTUFBTTtZQUNaLElBQUksRUFBRSxXQUFXO1lBQ2pCLE9BQU8sRUFBRSxrQkFBa0I7WUFDM0IsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxDQUFDO1lBQ3BELE9BQU8sRUFBRSxpQkFBaUI7WUFDMUIsTUFBTSxF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