Files
Web_BLV_OA_Exam_Prod/scripts/build-deploy-bundle.mjs
XuJiacheng dbf9fdc01c feat: 修改部分导入文本的逻辑,添加部署脚本和样式文件,更新数据库迁移逻辑
- 新增部署脚本 `build-deploy-bundle.mjs`,用于构建和部署 web 和 server 目录。
- 新增样式文件 `index-acd65452.css`,包含基础样式和响应式设计。
- 新增脚本 `repro-import-text.mjs`,用于测试文本导入 API。
- 新增测试文件 `db-migration-score-zero.test.ts`,验证历史数据库中 questions.score 约束的迁移逻辑。
- 更新数据库初始化逻辑,允许插入 score=0 的问题。
2026-01-04 09:20:04 +08:00

89 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import fs from 'node:fs/promises';
import path from 'node:path';
const projectRoot = process.cwd();
const distDir = path.join(projectRoot, 'dist');
const deployDir = path.join(projectRoot, 'deploy_bundle');
const deployWebDir = path.join(deployDir, 'web');
const deployServerDir = path.join(deployDir, 'server');
const exists = async (p) => {
try {
await fs.access(p);
return true;
} catch {
return false;
}
};
const ensureDir = async (p) => {
await fs.mkdir(p, { recursive: true });
};
const emptyDir = async (p) => {
await fs.rm(p, { recursive: true, force: true });
await fs.mkdir(p, { recursive: true });
};
const copyDir = async (src, dest) => {
await fs.cp(src, dest, { recursive: true });
};
const copyFile = async (src, dest) => {
await ensureDir(path.dirname(dest));
await fs.copyFile(src, dest);
};
if (!(await exists(distDir))) {
throw new Error('未找到 dist/。请先执行npm run build');
}
// 1) web: dist/ 下除 api/ 之外所有内容
await emptyDir(deployWebDir);
const distEntries = await fs.readdir(distDir, { withFileTypes: true });
for (const entry of distEntries) {
if (entry.name === 'api') continue;
const src = path.join(distDir, entry.name);
const dest = path.join(deployWebDir, entry.name);
if (entry.isDirectory()) {
await copyDir(src, dest);
} else {
await copyFile(src, dest);
}
}
// 2) server: dist/api -> deploy_bundle/server/dist/api
await ensureDir(deployServerDir);
await ensureDir(path.join(deployServerDir, 'dist'));
const distApiDir = path.join(distDir, 'api');
if (!(await exists(distApiDir))) {
throw new Error('未找到 dist/api/。请确认 npm run build 已成功执行(包含 scripts/build-api.mjs。');
}
await emptyDir(path.join(deployServerDir, 'dist', 'api'));
await copyDir(distApiDir, path.join(deployServerDir, 'dist', 'api'));
// 3) 同步 server 运行所需文件
await copyFile(path.join(projectRoot, 'package.json'), path.join(deployServerDir, 'package.json'));
if (await exists(path.join(projectRoot, 'package-lock.json'))) {
await copyFile(path.join(projectRoot, 'package-lock.json'), path.join(deployServerDir, 'package-lock.json'));
}
// ecosystem.config.cjs以仓库根目录为准同步如需环境差异可在服务器上覆盖 env/cwd
if (await exists(path.join(projectRoot, 'ecosystem.config.cjs'))) {
await copyFile(path.join(projectRoot, 'ecosystem.config.cjs'), path.join(deployServerDir, 'ecosystem.config.cjs'));
}
// sanity check
const initSql = path.join(deployServerDir, 'dist', 'api', 'database', 'init.sql');
if (!(await exists(initSql))) {
throw new Error('缺少 deploy_bundle/server/dist/api/database/init.sqlpostbuild 应该会复制)。');
}
console.log('deploy_bundle 已生成:');
console.log('- deploy_bundle/web');
console.log('- deploy_bundle/server');