UNPKG

@opentiny/tiny-toolkit-pro

Version:

TinyPro Vue:开箱即用、前后端分离的 Vue 后台管理模板

428 lines 34.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (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.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 = 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 }; fs_extra_1.copySync(serverFrom, serverTo); fs_1.writeFileSync(path.join(serverTo, '.env'), envStr); const dockerComposeYaml = fs_1.readFileSync(path.join(serverTo, 'docker-compose.yml')).toString(); const yaml = yaml_1.parse(dockerComposeYaml); const { services } = yaml; const mysql = services.mysql; mysql.environment = overwriteDockerComposeConfig; fs_1.writeFileSync(path.join(serverTo, 'docker-compose.yml'), 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 => 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; 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); } }; // 安装依赖 exports.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.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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvaW5pdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsK0JBQXdDO0FBQ3hDLDJDQUE2QjtBQUM3QiwrQ0FBaUM7QUFDakMsdUNBQW9DO0FBQ3BDLGtEQUEwQjtBQUMxQiw4REFBZ0M7QUFDaEMsd0RBQXdEO0FBQ3hELHFEQUEyRDtBQUMzRCw2Q0FXc0I7QUFDdEIsb0RBQTRCO0FBQzVCLDJCQUFxRTtBQUVyRSxNQUFNLEdBQUcsR0FBRyxpQkFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFDckMsTUFBTSxpQkFBaUIsR0FBRyxTQUFTLENBQUM7QUFDcEMsTUFBTSxvQkFBb0IsR0FBRyxVQUFVLENBQUM7QUFFeEM7Ozs7R0FJRztBQUNILE1BQU0sY0FBYyxHQUFHLEdBQXlCLEVBQUU7SUFDaEQsTUFBTSxRQUFRLEdBQW9DO1FBQ2hEO1lBQ0UsSUFBSSxFQUFFLE9BQU87WUFDYixJQUFJLEVBQUUsTUFBTTtZQUNaLE9BQU8sRUFBRSxVQUFVO1lBQ25CLE9BQU8sRUFBRSxvQkFBb0I7WUFDN0IsT0FBTztZQUNQLFFBQVEsRUFBRSxDQUFDLEtBQWEsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztTQUM1QztRQUNEO1lBQ0UsSUFBSSxFQUFFLE9BQU87WUFDYixJQUFJLEVBQUUsYUFBYTtZQUNuQixPQUFPLEVBQUUsVUFBVTtZQUNuQixPQUFPLEVBQUUscUJBQXFCO1NBQy9CO1FBQ0Q7WUFDRSxJQUFJLEVBQUUsTUFBTTtZQUNaLElBQUksRUFBRSxXQUFXO1lBQ2pCLE9BQU8sRUFBRSxrQkFBa0I7WUFDM0IsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxDQUFDO1lBQ3BELE9BQU8sRUFBRSxpQkFBaUI7WUFDMUIsTUFBTSxFQUFFLEdBQUc7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