refactor: remove assemble scripts, build directly to final dirs

去掉 .dist 中间层和组装脚本,admin 和 portal 各自直接构建到最终目录:

- admin 构建到 web/dist/admin/(后端直接读取)
- portal 构建到 portal/dist/(后端默认主题从此目录读取)
- 删除 web/scripts/(assemble-web.mjs + verify-dist.mjs)
- Makefile build-web 不再调用组装/校验脚本
- 后端 defaultThemeDir 从 web/dist/default-theme 改为 portal
This commit is contained in:
dushixiang committed 2026-08-09 23:05:07 +08:00
1 parent 1dd07117a3
commit 62a0f28b21
6 files changed
+4 -62

No files matched your search

+1 -3
View File
@@ -23,8 +23,6 @@ build-web:
npm run build --prefix web
npm ci --prefix portal
npm run build --prefix portal
node web/scripts/assemble-web.mjs
node web/scripts/verify-dist.mjs
# 构建服务端(开发)
build-server:
@@ -76,7 +74,7 @@ build-release:
# 清理编译产物
clean:
rm -rf bin/*
rm -rf web/dist web/.dist portal/dist
rm -rf web/dist portal/dist
# 运行测试
test:
+1 -1
View File
@@ -123,7 +123,7 @@ func NewThemeService(logger *zap.Logger, propertyService *PropertyService, cfg *
logger: logger,
propertyService: propertyService,
themeDir: themeDir,
defaultThemeDir: filepath.Join(assets.WebDir(), "default-theme"),
defaultThemeDir: "portal",
}
if err := os.MkdirAll(filepath.Join(themeDir, ".staging"), 0755); err != nil {
return nil, fmt.Errorf("创建主题目录失败: %w", err)
+1 -9
View File
@@ -15,15 +15,7 @@ cd portal && npm ci && npm run dev # 默认主题,http://localhost:5173/
## 构建
`make build-web` 分别构建 `web/`(管理后台)和 `portal/`(默认主题),再由 `web/scripts/assemble-web.mjs` 组装、`verify-dist.mjs` 校验以下产物:
```text
web/dist/admin/index.html
web/dist/admin/assets/*
web/dist/default-theme/pika-theme.json
web/dist/default-theme/dist/index.html
web/dist/default-theme/dist/assets/*
```
`make build-web` 分别构建 `web/`(管理后台 → `web/dist/admin/`)和 `portal/`(默认主题 → `portal/dist/`)。后端直接从这两个目录读取,无需组装脚本。
## 运行路径
-16
View File
@@ -1,16 +0,0 @@
import {access, copyFile, cp, mkdir, rm} from 'node:fs/promises';
import {resolve} from 'node:path';
const repoRoot = resolve(import.meta.dirname, '..', '..');
const adminDist = resolve(repoRoot, 'web/.dist');
const portalDist = resolve(repoRoot, 'portal/dist');
const output = resolve(repoRoot, 'web/dist');
await access(resolve(adminDist, 'index.html'));
await access(resolve(portalDist, 'index.html'));
await rm(output, {recursive: true, force: true});
await mkdir(resolve(output, 'default-theme'), {recursive: true});
await cp(adminDist, resolve(output, 'admin'), {recursive: true});
await cp(portalDist, resolve(output, 'default-theme/dist'), {recursive: true});
await copyFile(resolve(repoRoot, 'portal/pika-theme.json'), resolve(output, 'default-theme/pika-theme.json'));
await copyFile(resolve(repoRoot, 'portal/public/logo.png'), resolve(output, 'logo.png'));
-32
View File
@@ -1,32 +0,0 @@
import {access, readFile, stat} from 'node:fs/promises';
import {resolve} from 'node:path';
const root = resolve(import.meta.dirname, '..');
const requiredFiles = [
'dist/admin/index.html',
'dist/default-theme/pika-theme.json',
'dist/default-theme/dist/index.html',
];
const requiredDirectories = ['dist/admin/assets', 'dist/default-theme/dist/assets'];
for (const relative of requiredFiles) {
const target = resolve(root, relative);
await access(target);
if (!(await stat(target)).isFile()) throw new Error(`构建产物不是文件: ${relative}`);
}
for (const relative of requiredDirectories) {
const target = resolve(root, relative);
await access(target);
if (!(await stat(target)).isDirectory()) throw new Error(`构建产物不是目录: ${relative}`);
}
const adminHTML = await readFile(resolve(root, 'dist/admin/index.html'), 'utf8');
const portalHTML = await readFile(resolve(root, 'dist/default-theme/dist/index.html'), 'utf8');
if (!adminHTML.includes('/admin/assets/') || adminHTML.includes('/theme-assets/')) {
throw new Error('管理 SPA 的资源前缀未与公开主题隔离');
}
if (!portalHTML.includes('/theme-assets/') || portalHTML.includes('/admin/assets/')) {
throw new Error('默认公开主题的资源前缀未与管理 SPA 隔离');
}
console.log('admin SPA 与 default-theme SPA 构建产物校验通过');
+1 -1
View File
@@ -12,7 +12,7 @@ export default defineConfig({
'@admin': path.resolve(__dirname, './src/admin'),
}},
build: {
outDir: path.resolve(__dirname, '.dist'),
outDir: path.resolve(__dirname, 'dist/admin'),
emptyOutDir: true,
assetsDir: 'assets',
},