From cd189a74f7c007dfdcb5be68a0c39ab2db99e68e Mon Sep 17 00:00:00 2001 From: ReaJason Date: Wed, 26 Feb 2025 20:20:49 +0800 Subject: [PATCH] build(ui): enahnce cross-platform dx --- web/bun.lockb | Bin 187524 -> 207420 bytes web/copy-build.js | 63 ++++++++++++++++++++++++++++++++++++++++++++++ web/copy-build.sh | 56 ----------------------------------------- web/package.json | 26 +++++++++++-------- 4 files changed, 78 insertions(+), 67 deletions(-) create mode 100644 web/copy-build.js delete mode 100755 web/copy-build.sh diff --git a/web/bun.lockb b/web/bun.lockb index 2cbe9a270dd27bc7767aa3d0709d3edfdaec85a7..7cc671c71eb7399cf5ffcfcda032279800adf0d9 100755 GIT binary patch delta 40208 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 F{{x4F!d?IX 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",