|
@@ -6,6 +6,9 @@ import chalk from 'chalk'
|
|
|
import fs from 'fs'
|
|
|
import { loadEnv } from 'vite'
|
|
|
|
|
|
+// 存储原始的 接口请求地址
|
|
|
+let originalApiUrl = '';
|
|
|
+
|
|
|
// 创建分隔线
|
|
|
const createSeparator = (text) => {
|
|
|
const width = 60;
|
|
@@ -48,6 +51,33 @@ const interval = setInterval(() => {
|
|
|
}
|
|
|
}, 100)
|
|
|
const env = loadEnv('', process.cwd())
|
|
|
+
|
|
|
+const updateProxyConfig = (url) => {
|
|
|
+ try {
|
|
|
+ const envPath = '.env';
|
|
|
+ let content = fs.readFileSync(envPath, 'utf-8');
|
|
|
+
|
|
|
+ // 提取当前的 apiBaseUrl (如果需要)
|
|
|
+ const match = content.match(/VITE_API_URL = (.*)/);
|
|
|
+ if (!originalApiUrl && match && match[1]) {
|
|
|
+ originalApiUrl = match[1];
|
|
|
+ console.log(chalk.gray(`原始 API 地址已保存: ${originalApiUrl}`));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用正则表达式替换apiBaseUrl的值,但保留注释
|
|
|
+ content = content.replace(
|
|
|
+ /VITE_API_URL = (.*)/,
|
|
|
+ `VITE_API_URL = ${url}`
|
|
|
+ );
|
|
|
+
|
|
|
+ fs.writeFileSync(envPath, content, 'utf-8');
|
|
|
+ console.log(chalk.green('✓'), chalk.blue(`已更新 API 地址为: ${url}`));
|
|
|
+ } catch (error) {
|
|
|
+ console.error(chalk.red('✗'), chalk.red('更新 API 地址失败:'), error);
|
|
|
+ process.exit(1);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
const command = (list, config, host) => {
|
|
|
return new Promise((resolveCommand, rejectCommand) => {
|
|
|
const ssh = new SSHClient();
|
|
@@ -122,8 +152,10 @@ const updateFiles = async () => {
|
|
|
await sftp.connect(config);
|
|
|
spinner.succeed(chalk.green('服务器连接成功'));
|
|
|
console.log(chalk.blue('→'), chalk.gray('开始上传文件...'));
|
|
|
- await sftp.uploadDir('dist', '/data/seo-vue/dist');
|
|
|
+ await sftp.uploadDir('dist_6888', '/data/seo-vue/dist');
|
|
|
console.log(chalk.green('✓'), chalk.blue('6888端口文件上传完成'));
|
|
|
+ await sftp.uploadDir('dist_16888', '/data/seo-vue-test/dist');
|
|
|
+ console.log(chalk.green('✓'), chalk.blue('16888端口文件上传完成'));
|
|
|
|
|
|
|
|
|
sftp.end();
|
|
@@ -137,7 +169,18 @@ const updateFiles = async () => {
|
|
|
"cd /data/seo-vue && docker build -t seo-vue .",
|
|
|
"cd /data/seo-vue && docker run -d --name seo-vue -p 6888:80 seo-vue"
|
|
|
], config, "6888");
|
|
|
+ console.log(createSeparator('6888 端口部署完成'));
|
|
|
|
|
|
+ console.log(createSeparator('开始部署 16888 端口'));
|
|
|
+ await command([
|
|
|
+ "cd /data/seo-vue-test && pwd",
|
|
|
+ "cd /data/seo-vue-test && ls -la",
|
|
|
+ "cd /data/seo-vue-test && docker rm -f seo-vue-test",
|
|
|
+ "cd /data/seo-vue-test && docker rmi seo-vue-test",
|
|
|
+ "cd /data/seo-vue-test && docker build -t seo-vue-test .",
|
|
|
+ "cd /data/seo-vue-test && docker run -d --name seo-vue-test -p 16888:80 seo-vue-test"
|
|
|
+ ], config, "16888");
|
|
|
+ console.log(createSeparator('16888 端口部署完成'));
|
|
|
|
|
|
|
|
|
} catch (err) {
|
|
@@ -152,8 +195,11 @@ const updateFiles = async () => {
|
|
|
console.log(createSeparator('开始构建项目'));
|
|
|
|
|
|
// 使用 Promise 包装构建过程
|
|
|
-const buildWithProgress = () => {
|
|
|
+const buildWithProgress = (port, apiUrl) => {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
+ console.log(chalk.blue(`\n构建 ${port} 端口版本`));
|
|
|
+ console.log(chalk.gray(`API 地址: ${apiUrl}`));
|
|
|
+ updateProxyConfig(apiUrl);
|
|
|
// 重置进度条
|
|
|
speed = 20;
|
|
|
time = 20;
|
|
@@ -175,7 +221,24 @@ const buildWithProgress = () => {
|
|
|
|
|
|
buildProcess.on('close', async (code) => {
|
|
|
if (code === 0) {
|
|
|
-
|
|
|
+ // 构建成功后,将dist目录复制到对应的端口目录
|
|
|
+ const distDir = 'dist';
|
|
|
+ const targetDir = `dist_${port}`;
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 如果目标目录已存在,先删除
|
|
|
+ if (fs.existsSync(targetDir)) {
|
|
|
+ fs.rmSync(targetDir, { recursive: true, force: true });
|
|
|
+ }
|
|
|
+ // 复制dist目录到目标目录
|
|
|
+ fs.cpSync(distDir, targetDir, { recursive: true });
|
|
|
+ console.log(chalk.green('✓'), chalk.blue(`已保存 ${port} 端口构建文件到 ${targetDir}`));
|
|
|
+ } catch (err) {
|
|
|
+ console.error(chalk.red('✗'), chalk.red(`保存构建文件失败: ${err}`));
|
|
|
+ reject(err);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
spinner.succeed(chalk.green(`构建成功`));
|
|
|
resolve(buildOutput);
|
|
@@ -191,9 +254,19 @@ const buildWithProgress = () => {
|
|
|
const main = async () => {
|
|
|
spinner.start(); // 在主流程开始时启动 spinner,用于总体的进度指示
|
|
|
try {
|
|
|
- console.log(createSeparator('开始构建 6888 端口'));
|
|
|
+ const envPath = '.env';
|
|
|
+ const content = fs.readFileSync(envPath, 'utf-8');
|
|
|
+ const match = content.match(/VITE_API_URL = (.*)/);
|
|
|
+ if (match && match[1]) {
|
|
|
+ originalApiUrl = match[1];
|
|
|
+ } else {
|
|
|
+ console.warn(chalk.yellow('!'), chalk.yellow('无法从 env 中读取原始 VITE_API_URL,可能无法还原。'));
|
|
|
+ }
|
|
|
+
|
|
|
// 构建 6888 端口版本
|
|
|
- await buildWithProgress();
|
|
|
+ await buildWithProgress('6888', 'http://192.168.10.101:9999');
|
|
|
+ // 构建 16888 端口版本
|
|
|
+ await buildWithProgress('16888', 'http://192.168.3.17:9999');
|
|
|
|
|
|
// 开始部署
|
|
|
await updateFiles();
|
|
@@ -201,7 +274,18 @@ const main = async () => {
|
|
|
// 所有任务完成后,打印最终访问路径并停止 spinner
|
|
|
clearInterval(interval); // 在所有任务完成后停止进度条动画
|
|
|
console.log(createSeparator('部署完成'));
|
|
|
+ console.log(chalk.green('🎉'), chalk.cyan('所有环境部署成功!'));
|
|
|
console.log(chalk.green('🚀'), chalk.cyan(`6888 端口访问地址: http://${env.VITE_HOST}:6888`));
|
|
|
+ console.log(chalk.green('🚀'), chalk.cyan(`16888 端口访问地址: http://${env.VITE_HOST}:16888`));
|
|
|
+ // 还原 VITE_API_URL 到原始值
|
|
|
+ if (originalApiUrl) {
|
|
|
+ console.log(createSeparator('还原配置'));
|
|
|
+ updateProxyConfig(originalApiUrl);
|
|
|
+ } else {
|
|
|
+ console.warn(chalk.yellow('!'), chalk.yellow('未找到原始 VITE_API_URL,跳过还原。'));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
spinner.stopAndPersist({ text: '' }); // 停止并清理 spinner,返回控制台
|
|
|
process.exit(0); // 正常退出,返回控制台
|
|
|
} catch (error) {
|