chore: 统一代码格式并配置开发工具

- 添加 ESLint 和 Prettier 配置以统一代码风格
- 配置项目级 TypeScript 设置
- 更新前后端依赖版本
- 修复代码格式问题(引号、分号、尾随逗号等)
- 优化文件结构和导入路径
This commit is contained in:
2026-03-10 18:24:19 +08:00
parent 58373a15a9
commit 35d835f68c
58 changed files with 14240 additions and 922 deletions

View File

@@ -1,10 +1,11 @@
#!/usr/bin/env bun
import plugin from "bun-plugin-tailwind";
import { existsSync } from "fs";
import { rm } from "fs/promises";
import path from "path";
import plugin from 'bun-plugin-tailwind'
import { existsSync } from 'fs'
import { rm } from 'fs/promises'
import path from 'path'
if (process.argv.includes("--help") || process.argv.includes("-h")) {
if (process.argv.includes('--help') || process.argv.includes('-h')) {
console.log(`
🏗️ Bun Build Script
@@ -29,121 +30,129 @@ Common Options:
Example:
bun run build.ts --outdir=dist --minify --sourcemap=linked --external=react,react-dom
`);
process.exit(0);
`)
process.exit(0)
}
const toCamelCase = (str: string): string => str.replace(/-([a-z])/g, g => g[1].toUpperCase());
const toCamelCase = (str: string): string =>
str.replace(/-([a-z])/g, (g) => g[1].toUpperCase())
const parseValue = (value: string): any => {
if (value === "true") return true;
if (value === "false") return false;
const parseValue = (value: string): string | number | boolean | string[] => {
if (value === 'true') return true
if (value === 'false') return false
if (/^\d+$/.test(value)) return parseInt(value, 10);
if (/^\d*\.\d+$/.test(value)) return parseFloat(value);
if (/^\d+$/.test(value)) return parseInt(value, 10)
if (/^\d*\.\d+$/.test(value)) return parseFloat(value)
if (value.includes(",")) return value.split(",").map(v => v.trim());
if (value.includes(',')) return value.split(',').map((v) => v.trim())
return value;
};
return value
}
function parseArgs(): Partial<Bun.BuildConfig> {
const config: Partial<Bun.BuildConfig> = {};
const args = process.argv.slice(2);
const config: Record<string, unknown> = {}
const args = process.argv.slice(2)
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (arg === undefined) continue;
if (!arg.startsWith("--")) continue;
const arg = args[i]
if (arg === undefined) continue
if (!arg.startsWith('--')) continue
if (arg.startsWith("--no-")) {
const key = toCamelCase(arg.slice(5));
config[key] = false;
continue;
if (arg.startsWith('--no-')) {
const key = toCamelCase(arg.slice(5))
config[key] = false
continue
}
if (!arg.includes("=") && (i === args.length - 1 || args[i + 1]?.startsWith("--"))) {
const key = toCamelCase(arg.slice(2));
config[key] = true;
continue;
if (
!arg.includes('=') &&
(i === args.length - 1 || args[i + 1]?.startsWith('--'))
) {
const key = toCamelCase(arg.slice(2))
config[key] = true
continue
}
let key: string;
let value: string;
let key: string
let value: string
if (arg.includes("=")) {
[key, value] = arg.slice(2).split("=", 2) as [string, string];
if (arg.includes('=')) {
;[key, value] = arg.slice(2).split('=', 2) as [string, string]
} else {
key = arg.slice(2);
value = args[++i] ?? "";
key = arg.slice(2)
value = args[++i] ?? ''
}
key = toCamelCase(key);
key = toCamelCase(key)
if (key.includes(".")) {
const [parentKey, childKey] = key.split(".");
config[parentKey] = config[parentKey] || {};
config[parentKey][childKey] = parseValue(value);
if (key.includes('.')) {
const [parentKey, childKey] = key.split('.')
if (parentKey && childKey) {
config[parentKey] = config[parentKey] || {}
config[parentKey][childKey] = parseValue(value)
}
} else {
config[key] = parseValue(value);
config[key] = parseValue(value)
}
}
return config;
return config as Partial<Bun.BuildConfig>
}
const formatFileSize = (bytes: number): string => {
const units = ["B", "KB", "MB", "GB"];
let size = bytes;
let unitIndex = 0;
const units = ['B', 'KB', 'MB', 'GB']
let size = bytes
let unitIndex = 0
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024;
unitIndex++;
size /= 1024
unitIndex++
}
return `${size.toFixed(2)} ${units[unitIndex]}`;
};
console.log("\n🚀 Starting build process...\n");
const cliConfig = parseArgs();
const outdir = cliConfig.outdir || path.join(process.cwd(), "dist");
if (existsSync(outdir)) {
console.log(`🗑️ Cleaning previous build at ${outdir}`);
await rm(outdir, { recursive: true, force: true });
return `${size.toFixed(2)} ${units[unitIndex]}`
}
const start = performance.now();
console.log('\n🚀 Starting build process...\n')
const entrypoints = [...new Bun.Glob("**.html").scanSync("src")]
.map(a => path.resolve("src", a))
.filter(dir => !dir.includes("node_modules"));
console.log(`📄 Found ${entrypoints.length} HTML ${entrypoints.length === 1 ? "file" : "files"} to process\n`);
const cliConfig = parseArgs()
const outdir = cliConfig.outdir || path.join(process.cwd(), 'dist')
if (existsSync(outdir)) {
console.log(`🗑️ Cleaning previous build at ${outdir}`)
await rm(outdir, { recursive: true, force: true })
}
const start = performance.now()
const entrypoints = [...new Bun.Glob('**.html').scanSync('src')]
.map((a) => path.resolve('src', a))
.filter((dir) => !dir.includes('node_modules'))
console.log(
`📄 Found ${entrypoints.length} HTML ${entrypoints.length === 1 ? 'file' : 'files'} to process\n`,
)
const result = await Bun.build({
entrypoints,
outdir,
plugins: [plugin],
minify: true,
target: "browser",
sourcemap: "linked",
target: 'browser',
sourcemap: 'linked',
define: {
"process.env.NODE_ENV": JSON.stringify("production"),
'process.env.NODE_ENV': JSON.stringify('production'),
},
...cliConfig,
});
})
const end = performance.now();
const end = performance.now()
const outputTable = result.outputs.map(output => ({
const outputTable = result.outputs.map((output) => ({
File: path.relative(process.cwd(), output.path),
Type: output.kind,
Size: formatFileSize(output.size),
}));
}))
console.table(outputTable);
const buildTime = (end - start).toFixed(2);
console.table(outputTable)
const buildTime = (end - start).toFixed(2)
console.log(`\n✅ Build completed in ${buildTime}ms\n`);
console.log(`\n✅ Build completed in ${buildTime}ms\n`)