build(ui): enahnce cross-platform dx

This commit is contained in:
ReaJason
2025-02-26 20:20:49 +08:00
parent e10673ab38
commit 881587dccf
4 changed files with 78 additions and 67 deletions
BIN
View File
Binary file not shown.
+63
View File
@@ -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);
});
-56
View File
@@ -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"
+15 -11
View File
@@ -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",