import fs from 'fs'; import path from 'path'; import { execSync } from 'child_process'; import { fileURLToPath } from 'url'; import crypto from 'crypto'; // 获取 __dirname 等效值 const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // 确保目标目录存在 const templatesDir = path.resolve(__dirname, '../app/templates'); const assetsDir = path.resolve(templatesDir, 'assets'); // 清空目标目录 console.log('清空目标目录...'); if (fs.existsSync(assetsDir)) { // 删除assets目录中的所有文件 const files = fs.readdirSync(assetsDir); for (const file of files) { const filePath = path.join(assetsDir, file); if (fs.lstatSync(filePath).isDirectory()) { // 如果是目录,递归删除 fs.rmSync(filePath, { recursive: true, force: true }); } else { // 如果是文件,直接删除 fs.unlinkSync(filePath); } } console.log(`已清空目录: ${assetsDir}`); } else { // 如果目录不存在,创建它 fs.mkdirSync(assetsDir, { recursive: true }); console.log(`已创建目录: ${assetsDir}`); } // 确保templates目录存在 if (!fs.existsSync(templatesDir)) { fs.mkdirSync(templatesDir, { recursive: true }); console.log(`已创建目录: ${templatesDir}`); } // 构建 Vue 应用 console.log('正在构建 Vue 应用...'); execSync('npx vite build', { stdio: 'inherit' }); // 生成随机文件名 function generateRandomFileName(extension) { // 生成16字节的随机数据并转换为十六进制字符串 const randomBytes = crypto.randomBytes(16).toString('hex'); return `${randomBytes}.${extension}`; } // 重命名文件并返回新文件名 function renameFileWithRandomName(directory, originalName, extension) { // 不重命名favicon.ico文件 if (originalName === 'favicon.ico') { return originalName; } const newFileName = generateRandomFileName(extension); const oldPath = path.join(directory, originalName); const newPath = path.join(directory, newFileName); if (fs.existsSync(oldPath)) { fs.renameSync(oldPath, newPath); console.log(`文件已重命名: ${originalName} -> ${newFileName}`); return newFileName; } else { console.warn(`警告: 文件 ${originalName} 不存在,无法重命名`); return originalName; } } // 查找所有资源文件 const allFiles = fs.readdirSync(assetsDir); const jsFiles = allFiles.filter(file => file.endsWith('.js')); const cssFiles = allFiles.filter(file => file.endsWith('.css')); const imageFiles = allFiles.filter(file => /\.(png|jpg|jpeg|gif|svg|webp)$/.test(file)); const otherFiles = allFiles.filter(file => !file.endsWith('.js') && !file.endsWith('.css') && !/\.(png|jpg|jpeg|gif|svg|webp)$/.test(file) && file !== 'favicon.ico' ); // 重命名所有JS文件 const jsFileMap = {}; jsFiles.forEach(file => { const extension = path.extname(file).substring(1); const newFileName = renameFileWithRandomName(assetsDir, file, extension); jsFileMap[file] = newFileName; }); // 重命名所有CSS文件 const cssFileMap = {}; cssFiles.forEach(file => { const extension = path.extname(file).substring(1); const newFileName = renameFileWithRandomName(assetsDir, file, extension); cssFileMap[file] = newFileName; }); // 重命名所有图片文件 const imageFileMap = {}; imageFiles.forEach(file => { const extension = path.extname(file).substring(1); const newFileName = renameFileWithRandomName(assetsDir, file, extension); imageFileMap[file] = newFileName; }); // 重命名其他文件 const otherFileMap = {}; otherFiles.forEach(file => { const extension = path.extname(file).substring(1); const newFileName = renameFileWithRandomName(assetsDir, file, extension); otherFileMap[file] = newFileName; }); console.log(`检测到并重命名了文件:`); console.log(`- JS文件: ${Object.keys(jsFileMap).length} 个`); console.log(`- CSS文件: ${Object.keys(cssFileMap).length} 个`); console.log(`- 图片文件: ${Object.keys(imageFileMap).length} 个`); console.log(`- 其他文件: ${Object.keys(otherFileMap).length} 个`); // 创建一个简单的 index.html 文件,引用构建后的资源 const indexContent = ` Gemini API 代理服务 ${Object.values(jsFileMap).map(file => ``).join('\n ')} ${Object.values(cssFileMap).map(file => ``).join('\n ')}
`; // 将 index.html 写入到 app/templates 目录 const targetIndexPath = path.resolve(templatesDir, 'index.html'); fs.writeFileSync(targetIndexPath, indexContent); console.log('构建完成!'); console.log(`- index.html 已创建到: ${targetIndexPath}`); console.log(`- 静态资源已输出到: ${assetsDir}`);