Files
UI/apps/demo/build.mjs
T
shawn 0de9b6e66e init: @ui-arch 私人组件库 monorepo
- core/table-core: Headless 表格内核(排序/筛选/分页/选择插件 + 冒烟 9 项)
- core/frame: signal/computed/effect + hyperscript 微框架(零依赖)
- skin/ui: 16 个 DOM 组件(含自绘 select、滑动指示条 tabs、行选择 dataTable、form 表单校验)
- design/tokens: --ua-* 设计令牌(light/dark)
- tools/cli: ua 命令行(index/list/info/docs/style/mcp)+ MCP 注册表服务
- apps: demo 演示站(esbuild 单文件)+ docs 双轨文档(人类版 + llms-full.txt)
2026-10-23 14:58:53 +08:00

76 lines
3.1 KiB
JavaScript

/**
* 演示站打包:esbuild 从 TS 源码打包(alias 直连各包 src),
* 连同 tokens.css / ui.css 内嵌进单文件 apps/demo/dist/demo.html。
*/
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { createRequire } from 'node:module';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const root = path.resolve(__dirname, '..', '..'); // apps/demo 上两级 = 仓库根
// esbuild 装在托管 node workspace,用 createRequire 指过去
const require = createRequire('C:/Users/shawn/.workbuddy/binaries/node/workspace/index.js');
const esbuild = require('esbuild');
const read = (p) => fs.readFileSync(path.join(root, p), 'utf8');
const result = await esbuild.build({
entryPoints: [path.join(root, 'apps/demo/main.ts')],
bundle: true,
format: 'iife',
target: 'es2020',
charset: 'utf8', // 中文保留原文,不转义为 \uXXXX
write: false,
legalComments: 'none',
alias: {
'@ui-arch/frame': path.join(root, 'packages/core/frame/src/index.ts'),
'@ui-arch/ui': path.join(root, 'packages/skin/ui/src/index.ts'),
'@ui-arch/table-core': path.join(root, 'packages/core/table-core/src/index.ts'),
},
});
const js = result.outputFiles[0].text.replace(/<\/script>/gi, '<\\/script>'); // 防提前闭合
const css = [read('packages/design/tokens/tokens.css'), read('packages/skin/ui/ui.css')].join('\n');
const html = `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>@ui-arch 组件库 · 现场演示</title>
<style>
${css}
:root{--page-bg:#ffffff;--page-text:#1c1e21;--page-muted:#6b7280;--page-border:rgba(0,0,0,.14)}
@media (prefers-color-scheme:dark){:root{--page-bg:#101216;--page-text:#e7e9ec;--page-muted:#888780;--page-border:rgba(255,255,255,.15)}}
*{box-sizing:border-box}
body{margin:0;background:var(--page-bg);color:var(--page-text);font:14px/1.7 -apple-system,"Segoe UI","Microsoft YaHei",sans-serif}
.page{max-width:880px;margin:0 auto;padding:36px 20px 80px}
header{margin-bottom:30px}
h1{font-size:20px;font-weight:500;margin:0}
.sub{color:var(--page-muted);font-size:13px;margin:8px 0 0}
.sec{margin-bottom:40px}
h2{font-size:16px;font-weight:500;margin:0 0 4px}
.desc{color:var(--page-muted);font-size:13px;margin:0 0 14px}
.stage{display:flex;flex-wrap:wrap;gap:12px;align-items:center;border:1px dashed var(--page-border);border-radius:12px;padding:18px 20px}
.row{display:flex;gap:12px;align-items:center;flex-wrap:wrap}
.stage .ua-table,.stage .ua-card{width:100%}
.out{color:var(--ua-color-accent,#185fa5);font-size:13px}
footer{color:var(--page-muted);font-size:12px;text-align:center;margin-top:50px}
</style>
</head>
<body>
<div id="app"></div>
<footer>由 @ui-arch/frame + @ui-arch/ui 驱动 · 构建产物单文件,无运行时依赖</footer>
<script>
${js}
</script>
</body>
</html>
`;
const outDir = path.join(root, 'apps/demo/dist');
fs.mkdirSync(outDir, { recursive: true });
fs.writeFileSync(path.join(outDir, 'demo.html'), html);
console.log(`demo built -> apps/demo/dist/demo.html (${Math.round(html.length / 1024)} KB)`);