#!/usr/bin/env node /** * 将 data 目录内容拷贝到指定目录(本地开发或服务器),并生成对应 nginx 配置。 * * 用法: * node scripts/deploy-assets.js # 默认:拷贝到本地 pipi-assets * node scripts/deploy-assets.js --local # 同上 * node scripts/deploy-assets.js --server # 拷贝到 /var/www/pipi-assets/ * node scripts/deploy-assets.js --target /path/to/dir # 自定义目标目录 * * 每次运行都会生成 nginx 配置(root 为当前目标目录),默认输出到 scripts/nginx-pipi-assets.conf。 * 使用 --nginx /path/to/file 可指定 nginx 配置输出路径。 */ const fs = require('fs'); const path = require('path'); const PACKAGE_ROOT = path.resolve(__dirname, '..'); const DATA_DIR = path.join(PACKAGE_ROOT, 'data'); const LOCAL_TARGET = path.join(PACKAGE_ROOT, 'pipi-assets'); const SERVER_TARGET = '/var/www/pipi-assets'; const DEFAULT_NGINX_OUTPUT = path.join(__dirname, 'nginx-pipi-assets.conf'); function parseArgs() { const args = process.argv.slice(2); let target = null; let nginxOutput = null; for (let i = 0; i < args.length; i++) { if (args[i] === '--local' || args[i] === '--server') { if (target) { console.warn('警告: 多次指定目标,以最后一次为准'); } target = args[i] === '--local' ? LOCAL_TARGET : SERVER_TARGET; } else if (args[i] === '--target' && args[i + 1]) { target = path.resolve(args[++i]); } else if (args[i] === '--nginx' && args[i + 1] && !args[i + 1].startsWith('--')) { nginxOutput = path.resolve(args[++i]); } } if (target === null) { target = LOCAL_TARGET; } return { target, nginxOutput }; } function copyDirRecursive(src, dest) { if (!fs.existsSync(src)) return; fs.mkdirSync(dest, { recursive: true }); const entries = fs.readdirSync(src, { withFileTypes: true }); for (const entry of entries) { const srcPath = path.join(src, entry.name); const destPath = path.join(dest, entry.name); if (entry.isDirectory()) { copyDirRecursive(srcPath, destPath); } else { fs.copyFileSync(srcPath, destPath); } } } function deployDataToTarget(targetDir) { if (!fs.existsSync(DATA_DIR)) { console.error('错误: data 目录不存在:', DATA_DIR); process.exit(1); } const entries = fs.readdirSync(DATA_DIR, { withFileTypes: true }); if (entries.length === 0) { console.log('data 目录为空,跳过拷贝'); return; } fs.mkdirSync(targetDir, { recursive: true }); for (const entry of entries) { const srcPath = path.join(DATA_DIR, entry.name); const destPath = path.join(targetDir, entry.name); if (entry.isDirectory()) { if (fs.existsSync(destPath)) { fs.rmSync(destPath, { recursive: true }); } copyDirRecursive(srcPath, destPath); console.log(' 已拷贝:', entry.name + '/'); } else { fs.copyFileSync(srcPath, destPath); console.log(' 已拷贝:', entry.name); } } console.log('资源已拷贝到:', targetDir); } function generateNginxConfig(rootPath, serverName = 'assets.yourdomain.com') { return `# pipi-assets 静态资源站点 # 生成后请将 server_name 改为你的二级域名,并视需放到 /etc/nginx/sites-available/ 后启用 server { listen 80; server_name ${serverName}; root ${rootPath}; autoindex off; location /voice/ { alias ${rootPath}/voice/; add_header Cache-Control "public, max-age=86400"; } location /char/ { alias ${rootPath}/char/; add_header Cache-Control "public, max-age=3600"; add_header Access-Control-Allow-Origin "*"; } location /image/ { alias ${rootPath}/image/; add_header Cache-Control "public, max-age=86400"; } location /health { return 200 "ok"; add_header Content-Type text/plain; } } `; } function main() { const { target, nginxOutput } = parseArgs(); console.log('目标目录:', target); deployDataToTarget(target); const nginxPath = nginxOutput ?? DEFAULT_NGINX_OUTPUT; const config = generateNginxConfig(target); fs.writeFileSync(nginxPath, config, 'utf8'); console.log('Nginx 配置已写入:', nginxPath); } main();