diff --git a/web/bun.lockb b/web/bun.lockb index 2cbe9a27..7cc671c7 100755 Binary files a/web/bun.lockb and b/web/bun.lockb differ diff --git a/web/copy-build.js b/web/copy-build.js new file mode 100644 index 00000000..27f3d3de --- /dev/null +++ b/web/copy-build.js @@ -0,0 +1,63 @@ +import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs"; +import { cp } from "node:fs/promises"; +import { join, resolve } from "node:path"; + +const BASE_DIR = resolve("../boot/src/main/resources"); +const STATIC_DIR = join(BASE_DIR, "static"); +const ASSETS_DIR = join(STATIC_DIR, "assets"); +const TEMPLATES_DIR = join(BASE_DIR, "templates"); +const SRC_DIR = resolve("dist"); + +async function main() { + console.log("Copy assets into SpringBoot resources"); + + if (!existsSync(SRC_DIR)) { + console.error(`Error: ${SRC_DIR} does not exist`); + process.exit(1); + } + + mkdirSync(ASSETS_DIR, { recursive: true }); + mkdirSync(TEMPLATES_DIR, { recursive: true }); + + if (existsSync(ASSETS_DIR)) { + const files = readdirSync(ASSETS_DIR); + for (const file of files) { + rmSync(join(ASSETS_DIR, file), { recursive: true, force: true }); + } + } + + try { + if (existsSync(join(SRC_DIR, "vite.svg"))) { + await cp(join(SRC_DIR, "vite.svg"), join(STATIC_DIR, "vite.svg")); + } + + const assetsSourceDir = join(SRC_DIR, "assets"); + if (existsSync(assetsSourceDir)) { + await cp(assetsSourceDir, ASSETS_DIR, { recursive: true }); + } + } catch (err) { + console.error("Error copying assets:", err); + process.exit(1); + } + + const INDEX_SRC = join(SRC_DIR, "index.html"); + const INDEX_DEST = join(TEMPLATES_DIR, "index.html"); + + if (!existsSync(INDEX_SRC)) { + console.error(`Error: ${INDEX_SRC} does not exist. Make sure you built the frontend project first.`); + process.exit(1); + } + + const htmlContent = readFileSync(INDEX_SRC, "utf8"); + const updatedHtml = htmlContent + .replace(/href="([^"]*)"/g, 'th:href="@{$1}"') + .replace(/src="([^"]*)"/g, 'th:src="@{$1}"'); + + writeFileSync(INDEX_DEST, updatedHtml); + console.log("SpringBoot resources updated successfully"); +} + +main().catch((err) => { + console.error("Error:", err); + process.exit(1); +}); diff --git a/web/copy-build.sh b/web/copy-build.sh deleted file mode 100755 index 7dbc7d4c..00000000 --- a/web/copy-build.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/bash - -echo "Copy asserts into SpringBoot resources" -# 定义目标路径 -BASE_DIR="../boot/src/main/resources" -STATIC_DIR="$BASE_DIR/static" -ASSETS_DIR="$STATIC_DIR/assets" -TEMPLATES_DIR="$BASE_DIR/templates" -SRC_DIR="dist" - -# 检查 dist 目录是否存在 -if [ ! -d "$SRC_DIR" ]; then - echo "fail: $SRC_DIR not exists" - exit 1 -fi - -# 确定使用 sed 还是 gsed -if [[ "$OSTYPE" == "darwin"* ]]; then - SED_CMD="gsed" - if ! command -v gsed &> /dev/null; then - echo "fail: macOS need install gsed (by 'brew install gnu-sed')" - exit 1 - fi -else - SED_CMD="sed" -fi - -# 创建目录(如果不存在) -mkdir -p "$ASSETS_DIR" "$TEMPLATES_DIR" - -# 检查并清理 assets 目录 -rm -rf "$ASSETS_DIR"/* - -# 复制静态文件 -cp "$SRC_DIR/vite.svg" "$STATIC_DIR/" -cp -R "$SRC_DIR/assets/"* "$ASSETS_DIR/" - -# 处理 index.html -INDEX_SRC="$SRC_DIR/index.html" -INDEX_DEST="$TEMPLATES_DIR/index.html" - -if [ ! -f "$INDEX_SRC" ]; then - echo "fail: $INDEX_SRC not exists, make sure you had built frontend project with bun run build" - exit 1 -fi - -# 创建临时文件进行 thymeleaf 语法转换 -TEMP_FILE=$(mktemp) -cp "$INDEX_SRC" "$TEMP_FILE" - -"$SED_CMD" -i 's/href="\([^"]*\)"/th:href="@{\1}"/g' "$TEMP_FILE" -"$SED_CMD" -i 's/src="\([^"]*\)"/th:src="@{\1}"/g' "$TEMP_FILE" - -cp "$TEMP_FILE" "$INDEX_DEST" -rm "$TEMP_FILE" -echo "SpringBoot resources update successfully" \ No newline at end of file diff --git a/web/package.json b/web/package.json index 188a6fdc..653534fd 100644 --- a/web/package.json +++ b/web/package.json @@ -4,25 +4,29 @@ "private": true, "type": "module", "scripts": { - "typecheck": "tsc --noEmit", + "typecheck": "tsc -b --noEmit", "dev": "vite --port=3001", - "build": "tsc -b && vite build --mode production && bash copy-build.sh", - "serve": "vite preview", - "check": "bunx @biomejs/biome check ./ --write", - "start": "vite" + "build": "tsc -b && vite build --mode production && bun run copy-build.js", + "build:analyze": "vite build --mode production --outDir dist/analyze && npx vite-bundle-visualizer", + "preview": "vite preview", + "clean": "rimraf dist", + "lint": "bunx @biomejs/biome check ./", + "lint:fix": "bunx @biomejs/biome check ./ --write" }, "devDependencies": { "@biomejs/biome": "1.9.4", - "@tanstack/router-plugin": "^1.111.3", + "@tanstack/router-plugin": "^1.111.7", "@types/node": "^22.13.5", "@types/react": "^19.0.10", - "@types/react-dom": "^19.0.4", - "@vitejs/plugin-react": "^4.3.4", "@types/react-copy-to-clipboard": "^5.0.7", + "@types/react-dom": "^19.0.4", "@types/react-syntax-highlighter": "^15.5.13", + "@vitejs/plugin-react": "^4.3.4", + "rimraf": "^6.0.1", "tailwindcss": "^4.0.8", "typescript": "^5.7.3", - "vite": "^6.1.1" + "vite": "^6.2.0", + "vite-bundle-visualizer": "^1.2.1" }, "dependencies": { "@hookform/resolvers": "^4.1.2", @@ -39,8 +43,8 @@ "@radix-ui/react-tooltip": "^1.1.8", "@tailwindcss/vite": "^4.0.8", "@tanstack/react-query": "^5.66.9", - "@tanstack/react-router": "^1.111.3", - "@tanstack/router-devtools": "^1.111.3", + "@tanstack/react-router": "^1.111.7", + "@tanstack/router-devtools": "^1.111.7", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "i18next": "^24.2.2",