|
import fs from 'fs'; |
|
import path from 'path'; |
|
import { execSync } from 'child_process'; |
|
import { fileURLToPath } from 'url'; |
|
import crypto from 'crypto'; |
|
|
|
|
|
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)) { |
|
|
|
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}`); |
|
} |
|
|
|
|
|
if (!fs.existsSync(templatesDir)) { |
|
fs.mkdirSync(templatesDir, { recursive: true }); |
|
console.log(`已创建目录: ${templatesDir}`); |
|
} |
|
|
|
|
|
console.log('正在构建 Vue 应用...'); |
|
execSync('npm run build', { stdio: 'inherit' }); |
|
|
|
|
|
function generateRandomFileName(extension) { |
|
|
|
const randomBytes = crypto.randomBytes(16).toString('hex'); |
|
return `${randomBytes}.${extension}`; |
|
} |
|
|
|
|
|
function renameFileWithRandomName(directory, originalName, extension) { |
|
|
|
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' |
|
); |
|
|
|
|
|
const jsFileMap = {}; |
|
jsFiles.forEach(file => { |
|
const extension = path.extname(file).substring(1); |
|
const newFileName = renameFileWithRandomName(assetsDir, file, extension); |
|
jsFileMap[file] = newFileName; |
|
}); |
|
|
|
|
|
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} 个`); |
|
|
|
|
|
const indexContent = ` |
|
<!DOCTYPE html> |
|
<html lang="zh-CN"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<link rel="icon" href="/assets/favicon.ico"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Gemini API 代理服务</title> |
|
${Object.values(jsFileMap).map(file => `<script type="module" crossorigin src="/assets/${file}"></script>`).join('\n ')} |
|
${Object.values(cssFileMap).map(file => `<link rel="stylesheet" href="/assets/${file}">`).join('\n ')} |
|
</head> |
|
<body> |
|
<div id="app"></div> |
|
</body> |
|
</html> |
|
`; |
|
|
|
|
|
const targetIndexPath = path.resolve(templatesDir, 'index.html'); |
|
fs.writeFileSync(targetIndexPath, indexContent); |
|
|
|
console.log('构建完成!'); |
|
console.log(`- index.html 已创建到: ${targetIndexPath}`); |
|
console.log(`- 静态资源已输出到: ${assetsDir}`); |