@yarch/create-admin 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -26
- package/bin/create-admin.mjs +112 -20
- package/bin/gen-registry-snapshot.mjs +32 -0
- package/bin/registry-snapshot.json +13 -0
- package/bin/registry.mjs +19 -0
- package/package.json +2 -2
- package/templates/admin-antd/AGENTS.md +33 -0
- package/templates/admin-arco/AGENTS.md +33 -0
- package/templates/admin-semi/AGENTS.md +33 -0
- package/templates/base-semi/AGENTS.md +30 -0
- package/templates/base-semi/README.md +35 -0
- package/templates/base-semi/archetype.json +13 -0
- package/templates/base-semi/conf/nginx.conf.example +19 -0
- package/templates/base-semi/index.html +11 -0
- package/templates/base-semi/package.json +29 -0
- package/templates/base-semi/src/app/micro-apps.config.ts +16 -0
- package/templates/base-semi/src/app/router.tsx +44 -0
- package/templates/base-semi/src/layouts/basic-layout.tsx +51 -0
- package/templates/base-semi/src/main.tsx +22 -0
- package/templates/base-semi/src/micro/shared.ts +43 -0
- package/templates/base-semi/src/micro/sub-app.tsx +65 -0
- package/templates/base-semi/src/pages/dashboard.tsx +16 -0
- package/templates/base-semi/src/pages/login.tsx +18 -0
- package/templates/base-semi/src/pages/not-found.tsx +13 -0
- package/templates/base-semi/src/stores/auth.ts +13 -0
- package/templates/base-semi/src/ui/theme.ts +7 -0
- package/templates/base-semi/src/vite-env.d.ts +1 -0
- package/templates/base-semi/tsconfig.json +16 -0
- package/templates/base-semi/vite.config.ts +17 -0
- package/templates/sub-semi/AGENTS.md +33 -0
- package/templates/sub-semi/README.md +28 -0
- package/templates/sub-semi/archetype.json +13 -0
- package/templates/sub-semi/index.html +11 -0
- package/templates/sub-semi/package.json +34 -0
- package/templates/sub-semi/src/app/root.tsx +23 -0
- package/templates/sub-semi/src/app/router.tsx +26 -0
- package/templates/sub-semi/src/events.ts +4 -0
- package/templates/sub-semi/src/features/invoices/api.ts +19 -0
- package/templates/sub-semi/src/features/invoices/hooks/use-invoices.ts +18 -0
- package/templates/sub-semi/src/layouts/sub-layout.tsx +12 -0
- package/templates/sub-semi/src/main.tsx +28 -0
- package/templates/sub-semi/src/pages/invoices.tsx +49 -0
- package/templates/sub-semi/src/supply/integrated.ts +48 -0
- package/templates/sub-semi/src/supply/shims/contract.ts +25 -0
- package/templates/sub-semi/src/supply/standalone.ts +38 -0
- package/templates/sub-semi/src/supply/types.ts +18 -0
- package/templates/sub-semi/src/types/index.ts +6 -0
- package/templates/sub-semi/src/ui/popup.ts +13 -0
- package/templates/sub-semi/src/vite-env.d.ts +1 -0
- package/templates/sub-semi/tsconfig.json +20 -0
- package/templates/sub-semi/vite.config.ts +96 -0
package/README.md
CHANGED
|
@@ -1,42 +1,110 @@
|
|
|
1
|
-
# @yarch/create-admin
|
|
1
|
+
# @yarch/create-admin
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
>
|
|
3
|
+
> 一条命令生成**生成即合规**的中后台工程——契约底座、命名标准、结构纪律全部预置,三档 UI 任选。
|
|
4
|
+
> npm:[@yarch/create-admin](https://www.npmjs.com/package/@yarch/create-admin)(v0.1.0+)
|
|
5
5
|
|
|
6
|
-
##
|
|
6
|
+
## 优势:比裸脚手架(create-vite)多给什么
|
|
7
|
+
|
|
8
|
+
| 维度 | 裸脚手架 | 本生成器 |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| 接口层 | 空壳,信封/错误码自己搭 | `@yarch/contract` 预接线:RestResponse 信封解包 · 13 码错误码表 · traceId 透传 · 401 自动跳登录 |
|
|
11
|
+
| 工程名 | 随手起 | 强制 registry 标准(小写短横线 + 禁裸通用词);工程名 = npm 包名 = 服务名,生成即登记提醒 |
|
|
12
|
+
| UI 库 | 自己选、自己集成 | **三档一键选**:Semi / antd / Arco——契约底座与结构不变,只换 UI 壳 |
|
|
13
|
+
| 升级 | 模板拷走即断亲 | 底座是 npm 版本依赖:`pnpm update @yarch/contract @yarch/react` 一行跟进平台修复 |
|
|
14
|
+
| 结构 | 分层靠自觉 | feature-first 分层 + depcruise 同款机检口径(pages 薄入口、禁反向依赖) |
|
|
15
|
+
| 跨栈 | — | 与 java / golang 栈同一套契约:一个 traceId 前后端拉通,错误码语义唯一 |
|
|
16
|
+
|
|
17
|
+
## 创建:三档 UI,各一条命令
|
|
7
18
|
|
|
8
19
|
```bash
|
|
9
|
-
#
|
|
10
|
-
npm create @yarch/admin@latest ysaas-console
|
|
20
|
+
# Semi 档(默认 · 抖音系)
|
|
21
|
+
npm create @yarch/admin@latest ysaas-console
|
|
22
|
+
|
|
23
|
+
# antd 档(蚂蚁系)
|
|
11
24
|
npm create @yarch/admin@latest ysaas-console -- --ui antd
|
|
12
25
|
|
|
13
|
-
#
|
|
14
|
-
|
|
26
|
+
# Arco 档(字节系)
|
|
27
|
+
npm create @yarch/admin@latest ysaas-console -- --ui arco
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
不传 `--ui` 则交互三选一(回车落默认 Semi);交互同时问描述 / 端口 / API 代理目标 / GitLab 分组,全部有默认值。三档底座与目录结构完全一致,切换档位 = 换个名字重新生成。
|
|
31
|
+
|
|
32
|
+
## 起跑(两分钟)
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
cd ysaas-console
|
|
36
|
+
pnpm install
|
|
37
|
+
pnpm dev # http://localhost:5173
|
|
38
|
+
pnpm build # tsc --noEmit + vite build
|
|
15
39
|
```
|
|
16
40
|
|
|
17
|
-
|
|
41
|
+
- **接后端**:`vite.config.ts` 已预配 `/api/v1` 反向代理,改 target 即指向你的服务;
|
|
42
|
+
- **升级底座**:`pnpm update @yarch/contract @yarch/react`;
|
|
43
|
+
- **登记**:按生成后的控制台提醒,去 yarch 仓 `contract/registry.md` 登记服务名(PR 即登记)。
|
|
18
44
|
|
|
19
|
-
##
|
|
45
|
+
## 微前端:一条命令生成基座 / 子应用
|
|
20
46
|
|
|
21
|
-
|
|
47
|
+
```bash
|
|
48
|
+
# 基座(布局/菜单/登录态/路由分发/错误兜底,全局唯一)
|
|
49
|
+
npm create @yarch/admin@latest ysaas-console -- --micro base
|
|
50
|
+
|
|
51
|
+
# 子应用(独立·集成双运行形态,只做域内页面)
|
|
52
|
+
npm create @yarch/admin@latest ysaas-billing -- --micro sub --port 5174
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
与单应用档的差异(规约:[micro-frontend.md](../../../contract/web/micro-frontend.md)):
|
|
56
|
+
|
|
57
|
+
- **应用名双重校验**:在服务名规则之上加「服务名-用途」两段式 + `contract/registry.md` 登记表核对(重名/未登记当场拒绝;登记表离线时可用包内快照);
|
|
58
|
+
- **基座**:`micro-apps.config.ts` 登记表声明式装配菜单与路由分发(禁硬编码子应用路由)、登录态唯一持有、共享运行时注册(`src/micro/shared.ts`)、加载失败重试页;
|
|
59
|
+
- **子应用**:`src/supply/` 供给层实现独立·集成双运行(十一-2)——独立模式全量自足可单独 `pnpm dev`,集成构建(`pnpm build:micro` → `dist-micro/`)react 系与 contract 由基座 window 全局提供,产物体积里框架消失;
|
|
60
|
+
- **UI 档**:本批仅 Semi(`--ui` 其余档触发式扩展)。
|
|
61
|
+
|
|
62
|
+
仓内活案例:[examples/ysaas-console](../examples/ysaas-console)(基座)+ [examples/ysaas-billing](../examples/ysaas-billing)(子应用),事件上行/双模式/e2e 全链路。
|
|
63
|
+
|
|
64
|
+
<details>
|
|
65
|
+
<summary><b>附录:交互问答明细 · flags 全表 · 命名规则 · 原理 · 发布(点开)</b></summary>
|
|
66
|
+
|
|
67
|
+
### 交互问答(单应用 6 项;微前端形态在最前多一项「工程形态」)
|
|
68
|
+
|
|
69
|
+
| # | 问题 | 默认 |
|
|
22
70
|
|---|---|---|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
71
|
+
| 0 | 工程形态:1) 单应用(默认)2) 微前端基座 3) 微前端子应用 | 单应用 |
|
|
72
|
+
| 1 | 工程名(= npm 包名 = registry 服务名,须过校验) | 必填 |
|
|
73
|
+
| 2 | UI 档:1) Semi(默认)2) antd 3) Arco | semi |
|
|
74
|
+
| 3 | 工程描述 | `<工程名>:基于 yarch web 脚手架生成的中后台工程` |
|
|
75
|
+
| 4 | dev 端口 | 5173 |
|
|
76
|
+
| 5 | API 代理目标 | `http://localhost:8080` |
|
|
77
|
+
| 6 | GitLab 分组(登记提示用) | 空 |
|
|
29
78
|
|
|
30
|
-
|
|
79
|
+
### 命名规则(contract/registry.md 一-1/一-2,与 golang 生成器同款)
|
|
80
|
+
|
|
81
|
+
- 格式 `^[a-z][a-z0-9-]{1,31}$`:小写字母/数字/短横线,字母开头,2~32 字符——大写、下划线、中文一律当场拒绝;
|
|
82
|
+
- 禁裸通用词:`api app service server backend web admin main common system demo user gateway` 不得单独成名(加前缀消歧,如 `ysaas-admin`)。
|
|
83
|
+
|
|
84
|
+
### 非交互 flags(脚本 / CI)
|
|
85
|
+
|
|
86
|
+
`npm create @yarch/admin@latest <名> -- --ui antd --yes`(npm 传 flag 须 `--` 分隔;pnpm 直接跟)。
|
|
87
|
+
维护者本地直跑:`node stacks/web/packages/create/bin/create-admin.mjs <名> --ui antd --yes --deps file`。
|
|
88
|
+
|
|
89
|
+
| flag | 取值 | 说明 |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| `--name` | 工程名 | 也可用第一个位置参数 |
|
|
92
|
+
| `--ui` | `semi` \| `antd` \| `arco` | 非法值报错 |
|
|
93
|
+
| `--micro` | `base` \| `sub` | 微前端模板档;缺省=单应用 admin(不受微前端规约约束) |
|
|
94
|
+
| `--registry` | 路径 | 微前端应用名核对用的 registry.md(缺省用包内快照) |
|
|
95
|
+
| `--desc` | 文本 | 不得含双引号/反斜杠 |
|
|
96
|
+
| `--port` | 1024~65535 | |
|
|
97
|
+
| `--proxy` | `http(s)://…` | API 代理目标 |
|
|
98
|
+
| `--group` | 文本 | GitLab 分组 |
|
|
99
|
+
| `--deps` | `version`(默认)\| `file` | `file` = 指向 yarch 本仓源码(发版前联调) |
|
|
100
|
+
| `--src` / `--out` | 目录 | 模板根 / 输出目录(默认 `./<工程名>`,须空) |
|
|
101
|
+
| `--yes` | | 非交互,缺省全走默认 |
|
|
31
102
|
|
|
32
|
-
|
|
103
|
+
### 原理(一段话)
|
|
33
104
|
|
|
34
|
-
|
|
35
|
-
|---|---|
|
|
36
|
-
| `admin-semi`(默认) | Semi Design(抖音系) |
|
|
37
|
-
| `admin-antd` | antd(蚂蚁系) |
|
|
38
|
-
| `admin-arco` | Arco Design(字节系) |
|
|
105
|
+
maven-archetype / cookiecutter 模式:三档模板是声明式资产(`{{var}}` 占位 + `archetype.json` 变量声明),生成器做问答 → 变量集 → 目录/文件/内容全量替换 + 残留占位符扫描;模板自身不要求可安装,工程正确性由 CI「生成后冒烟」(生成 → install → tsc → build)保证。
|
|
39
106
|
|
|
40
|
-
|
|
107
|
+
### 发布(维护者)
|
|
41
108
|
|
|
42
|
-
推 tag `stacks/web/vX.Y.Z`
|
|
109
|
+
推 tag `stacks/web/vX.Y.Z` → [web-publish.yml](../../../.github/workflows/web-publish.yml):断言 + 机检 → contract → react → create 顺序发布(幂等)。
|
|
110
|
+
</details>
|
package/bin/create-admin.mjs
CHANGED
|
@@ -18,6 +18,7 @@ import { readFileSync, writeFileSync, readdirSync, mkdirSync } from "node:fs";
|
|
|
18
18
|
import { fileURLToPath } from "node:url";
|
|
19
19
|
import { dirname, join, resolve } from "node:path";
|
|
20
20
|
import readline from "node:readline/promises";
|
|
21
|
+
import { parseRegistryMd } from "./registry.mjs";
|
|
21
22
|
|
|
22
23
|
const PKG_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
23
24
|
const UI_TIERS = {
|
|
@@ -25,6 +26,13 @@ const UI_TIERS = {
|
|
|
25
26
|
antd: "antd(蚂蚁系)",
|
|
26
27
|
arco: "Arco Design(字节系)",
|
|
27
28
|
};
|
|
29
|
+
// 微前端模板档(W10):载器 micro-app(contract/README 登记表默认档),UI 档本批固定 semi,其余档触发式。
|
|
30
|
+
const MICRO_KINDS = {
|
|
31
|
+
base: "微前端基座(micro-frontend.md 一-1:全局唯一,承载布局/菜单/登录态/路由分发/错误兜底)",
|
|
32
|
+
sub: "微前端子应用(micro-frontend.md 一-3:独立·集成双运行形态,只做域内页面)",
|
|
33
|
+
};
|
|
34
|
+
// @yarch 底座版本依赖(--deps version 形态);与本仓发版版本同步 bump。
|
|
35
|
+
const YARCH_VERSION = "^0.2.0";
|
|
28
36
|
|
|
29
37
|
const servicePattern = /^[a-z][a-z0-9-]{1,31}$/;
|
|
30
38
|
// 禁裸通用词(registry.md 一-1/一-2 口径摘录,与 golang yarch-init 同款;完整表以 contract/registry.md 为准)。
|
|
@@ -40,11 +48,13 @@ const PLACEHOLDER = /\{\{\s*([a-zA-Z][a-zA-Z0-9]*)\s*\}\}/g;
|
|
|
40
48
|
|
|
41
49
|
function usage() {
|
|
42
50
|
return [
|
|
43
|
-
"用法:create-admin <工程名|输出目录> [--name <名>] [--ui semi|antd|arco] [--
|
|
44
|
-
" [--
|
|
45
|
-
" [--src <模板根>] [--out <目录>] [--yes]",
|
|
51
|
+
"用法:create-admin <工程名|输出目录> [--name <名>] [--ui semi|antd|arco] [--micro base|sub]",
|
|
52
|
+
" [--registry <registry.md 路径>] [--desc <描述>] [--port <端口>] [--proxy <目标>]",
|
|
53
|
+
" [--group <GitLab分组>] [--deps file|version] [--src <模板根>] [--out <目录>] [--yes]",
|
|
54
|
+
" --micro 微前端模板档(W10):base=基座 / sub=子应用;缺省=单应用 admin(不受微前端规约约束)",
|
|
55
|
+
" --registry 微前端名称核对用的 contract/registry.md 路径(默认用包内快照 bin/registry-snapshot.json)",
|
|
46
56
|
" --yes 非交互:缺省项全走默认值(CI 用)",
|
|
47
|
-
" --deps @yarch 底座依赖形态:version(默认,^0.
|
|
57
|
+
" --deps @yarch 底座依赖形态:version(默认,^0.2.0,需 @yarch 已发 npm)| file(发版前本地过渡)",
|
|
48
58
|
].join("\n");
|
|
49
59
|
}
|
|
50
60
|
|
|
@@ -77,6 +87,43 @@ function validateName(name) {
|
|
|
77
87
|
return null;
|
|
78
88
|
}
|
|
79
89
|
|
|
90
|
+
// —— 微前端应用名校验(micro-frontend.md 二-1/二-4,十三表「创建期」机检)——
|
|
91
|
+
|
|
92
|
+
// 快照来源:--registry 指向的 registry.md(CI/内网用最新表)优先,否则用随包分发的快照。
|
|
93
|
+
function loadRegistry(registryArg) {
|
|
94
|
+
if (registryArg) {
|
|
95
|
+
return parseRegistryMd(readFileSync(resolve(registryArg), "utf8"));
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const snapshot = JSON.parse(readFileSync(join(PKG_ROOT, "bin", "registry-snapshot.json"), "utf8"));
|
|
99
|
+
return {
|
|
100
|
+
serviceNames: new Set(snapshot.serviceNames),
|
|
101
|
+
appNames: new Set(snapshot.appNames),
|
|
102
|
+
};
|
|
103
|
+
} catch {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function validateMicroName(name, registry) {
|
|
109
|
+
const baseErr = validateName(name);
|
|
110
|
+
if (baseErr) return baseErr;
|
|
111
|
+
if (!registry) {
|
|
112
|
+
return "无法核对 registry.md(缺 bin/registry-snapshot.json 且未传 --registry <path>)——微前端应用名必须核对登记表(二-1)";
|
|
113
|
+
}
|
|
114
|
+
if (!name.includes("-")) {
|
|
115
|
+
return "微前端应用名须由「服务名-用途/域」两段及以上构成(micro-frontend.md 二-1,正例 ysaas-billing)";
|
|
116
|
+
}
|
|
117
|
+
const service = name.split("-")[0];
|
|
118
|
+
if (!registry.serviceNames.has(service)) {
|
|
119
|
+
return `首段 ${service} 不在 registry.md 二节已登记服务名表(二-1);若快照过期,用 --registry 指向最新 contract/registry.md`;
|
|
120
|
+
}
|
|
121
|
+
if (registry.appNames.has(name)) {
|
|
122
|
+
return `应用名 ${name} 已在 registry.md 四节登记(二-4:跨项目不得重名)`;
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
|
|
80
127
|
async function askText(rl, question, { fallback = "", validate = null, optional = false } = {}) {
|
|
81
128
|
for (;;) {
|
|
82
129
|
const hint = fallback ? `(默认 ${fallback})` : optional ? "(可空)" : "";
|
|
@@ -144,12 +191,23 @@ async function main() {
|
|
|
144
191
|
const args = parseArgs(process.argv.slice(2));
|
|
145
192
|
const nameArg = args.name || (args._.length > 0 && !args._[0].startsWith("/") ? args._[0] : null);
|
|
146
193
|
|
|
194
|
+
let micro = args.micro;
|
|
195
|
+
if (micro !== undefined && !(micro in MICRO_KINDS)) {
|
|
196
|
+
fatal(`--micro 须为 ${Object.keys(MICRO_KINDS).join("|")},当前:${micro}`);
|
|
197
|
+
}
|
|
147
198
|
const ui = args.ui ?? "semi";
|
|
148
199
|
if (!(ui in UI_TIERS)) fatal(`--ui 须为 ${Object.keys(UI_TIERS).join("|")},当前:${ui}`);
|
|
200
|
+
if (micro && ui !== "semi") {
|
|
201
|
+
fatal("微前端模板档本批仅 semi(W1 默认档);其余 UI 档触发式扩展(PLAN.md W10)");
|
|
202
|
+
}
|
|
149
203
|
|
|
150
204
|
const interactive = !args.yes && process.stdin.isTTY;
|
|
151
205
|
if (!nameArg && !interactive) fatal(`工程名必填(或用 --yes 走交互外模式):\n${usage()}`);
|
|
152
206
|
|
|
207
|
+
// 微前端形态才需要登记表核对(二-1 首段=已登记服务名;单应用仍走一-1/一-2 正则+禁裸词)。
|
|
208
|
+
const needsRegistry = micro !== undefined || interactive; // 交互形态问答后可能选 micro
|
|
209
|
+
const registry = needsRegistry ? loadRegistry(args.registry) : null;
|
|
210
|
+
|
|
153
211
|
const rl = interactive ? readline.createInterface({ input: process.stdin, output: process.stdout }) : null;
|
|
154
212
|
try {
|
|
155
213
|
let name = nameArg;
|
|
@@ -160,17 +218,34 @@ async function main() {
|
|
|
160
218
|
|
|
161
219
|
if (interactive) {
|
|
162
220
|
console.log("yarch web 工程生成器(@yarch/create-admin)\n");
|
|
163
|
-
if (
|
|
164
|
-
|
|
221
|
+
if (micro === undefined) {
|
|
222
|
+
const kindIdx = await askSelect(
|
|
223
|
+
rl,
|
|
224
|
+
"工程形态(micro-frontend.md 一:单应用不受微前端规约约束;基座全局唯一、子应用双运行形态)",
|
|
225
|
+
[
|
|
226
|
+
"单应用 admin(默认,npm create @yarch/admin 常规形态)",
|
|
227
|
+
"微前端基座 base(--micro base)",
|
|
228
|
+
"微前端子应用 sub(--micro sub)",
|
|
229
|
+
],
|
|
230
|
+
0,
|
|
231
|
+
);
|
|
232
|
+
micro = kindIdx === 0 ? undefined : kindIdx === 1 ? "base" : "sub";
|
|
233
|
+
}
|
|
234
|
+
const validator = micro ? (v) => validateMicroName(v, registry) : validateName;
|
|
235
|
+
const nameLabel = micro
|
|
236
|
+
? "应用名(= 路由前缀 = storage/事件前缀,二-2 一名三用;首段=已登记服务名)"
|
|
237
|
+
: "工程名(= npm 包名 = registry 服务名)";
|
|
238
|
+
if (!name) name = await askText(rl, nameLabel, { validate: validator });
|
|
239
|
+
else if (validator(name)) fatal(validator(name));
|
|
165
240
|
if (!description) {
|
|
166
241
|
description = await askText(rl, "工程描述", {
|
|
167
|
-
fallback: `${name}:基于 yarch web
|
|
242
|
+
fallback: `${name}:基于 yarch web 脚手架生成的${micro ? (micro === "base" ? "微前端基座" : "微前端子应用") : "中后台"}工程`,
|
|
168
243
|
validate: (v) => (v.includes('"') || v.includes("\\") ? "不得包含双引号与反斜杠(要写进 package.json)" : null),
|
|
169
244
|
});
|
|
170
245
|
}
|
|
171
246
|
if (!port) {
|
|
172
247
|
port = await askText(rl, "dev 端口", {
|
|
173
|
-
fallback: "5173",
|
|
248
|
+
fallback: micro === "sub" ? "5174" : "5173",
|
|
174
249
|
validate: (v) => (/^\d{4,5}$/.test(v) && Number(v) >= 1024 && Number(v) <= 65535 ? null : "1024~65535 的数字端口号"),
|
|
175
250
|
});
|
|
176
251
|
}
|
|
@@ -184,10 +259,10 @@ async function main() {
|
|
|
184
259
|
}
|
|
185
260
|
|
|
186
261
|
if (!name) fatal(`工程名缺失。\n${usage()}`);
|
|
187
|
-
const nameErr = validateName(name);
|
|
262
|
+
const nameErr = micro ? validateMicroName(name, registry) : validateName(name);
|
|
188
263
|
if (nameErr) fatal(`工程名 ${JSON.stringify(name)} ${nameErr}`);
|
|
189
|
-
description ??= `${name}:基于 yarch web
|
|
190
|
-
port ??= "5173";
|
|
264
|
+
description ??= `${name}:基于 yarch web 脚手架生成的${micro ? (micro === "base" ? "微前端基座" : "微前端子应用") : "中后台"}工程`;
|
|
265
|
+
port ??= micro === "sub" ? "5174" : "5173";
|
|
191
266
|
proxyTarget ??= "http://localhost:8080";
|
|
192
267
|
group ??= "";
|
|
193
268
|
if (!/^\d{4,5}$/.test(port) || Number(port) < 1024 || Number(port) > 65535) {
|
|
@@ -197,14 +272,22 @@ async function main() {
|
|
|
197
272
|
fatal(`代理目标 ${proxyTarget} 无效:须为 http(s):// 开头`);
|
|
198
273
|
}
|
|
199
274
|
|
|
200
|
-
// @yarch 底座依赖形态(W8):version =
|
|
275
|
+
// @yarch 底座依赖形态(W8):version = 版本依赖(标准形态,@yarch/contract、@yarch/react 已发 npm);
|
|
201
276
|
// file: 绝对路径 = golang replace 行对偶(发版前本地过渡,yarch 源码变更后重跑 pnpm install 刷新)。
|
|
202
277
|
const depsMode = args.deps === "file" ? "file" : "version";
|
|
203
|
-
const yarchContractDep =
|
|
204
|
-
|
|
205
|
-
const yarchReactDep = depsMode === "version" ? "^0.1.0" : `file:${resolve(PKG_ROOT, "../react")}`;
|
|
278
|
+
const yarchContractDep = depsMode === "version" ? YARCH_VERSION : `file:${resolve(PKG_ROOT, "../contract")}`;
|
|
279
|
+
const yarchReactDep = depsMode === "version" ? YARCH_VERSION : `file:${resolve(PKG_ROOT, "../react")}`;
|
|
206
280
|
|
|
207
|
-
const vars = {
|
|
281
|
+
const vars = {
|
|
282
|
+
packageName: name,
|
|
283
|
+
appName: name,
|
|
284
|
+
service: name.split("-")[0],
|
|
285
|
+
description,
|
|
286
|
+
port,
|
|
287
|
+
proxyTarget,
|
|
288
|
+
yarchContractDep,
|
|
289
|
+
yarchReactDep,
|
|
290
|
+
};
|
|
208
291
|
|
|
209
292
|
const outDir = resolve(args.out || (args._.length > 0 ? args._[args._.length - 1] : name));
|
|
210
293
|
let existing;
|
|
@@ -215,7 +298,9 @@ async function main() {
|
|
|
215
298
|
}
|
|
216
299
|
if (existing && existing.length > 0) fatal(`输出目录 ${outDir} 非空`);
|
|
217
300
|
|
|
218
|
-
const templateDir = resolve(
|
|
301
|
+
const templateDir = resolve(
|
|
302
|
+
args.src || join(PKG_ROOT, "templates", micro ? `${micro}-semi` : `admin-${ui}`),
|
|
303
|
+
);
|
|
219
304
|
try {
|
|
220
305
|
readFileSync(join(templateDir, "archetype.json"));
|
|
221
306
|
} catch {
|
|
@@ -230,12 +315,19 @@ async function main() {
|
|
|
230
315
|
|
|
231
316
|
const tierDesc = JSON.parse(readFileSync(join(templateDir, "archetype.json"), "utf8")).description;
|
|
232
317
|
const groupHint = group ? `(属主建议:${group}/${name})` : "";
|
|
233
|
-
|
|
318
|
+
const tierLabel = micro ? `${micro}-semi 档` : `admin-${ui} 档`;
|
|
319
|
+
const registryHint = micro
|
|
320
|
+
? `2. 应用名已置为 ${JSON.stringify(name)}——去 yarch 仓 contract/registry.md 四节前端应用名登记表登记${groupHint}
|
|
321
|
+
3. ${micro === "base"
|
|
322
|
+
? "基座:micro-apps.config.ts 是子应用入口登记表(十二-2,git 纳管);子应用接入只改此表"
|
|
323
|
+
: "子应用:在基座仓 micro-apps.config.ts 登记入口(十二-2);pnpm dev 独立运行 / pnpm dev:micro 被基座加载(十一)"}`
|
|
324
|
+
: `2. 服务名已置为 ${JSON.stringify(name)}——去 yarch 仓 contract/registry.md 登记表登记${groupHint}`;
|
|
325
|
+
console.log(`✅ 已生成 ${outDir}(${n} 个文件,${tierLabel})—— ${tierDesc}
|
|
234
326
|
|
|
235
327
|
下一步:
|
|
236
328
|
1. cd ${outDir} && pnpm install && pnpm dev # http://localhost:${port}
|
|
237
|
-
|
|
238
|
-
3. @yarch 底座为 ${depsMode === "version" ?
|
|
329
|
+
${registryHint}
|
|
330
|
+
${micro ? "4" : "3"}. @yarch 底座为 ${depsMode === "version" ? `${YARCH_VERSION} 版本依赖(升级 = pnpm update @yarch/contract @yarch/react)` : "file: 本地依赖(发版前过渡;正式发版后改用默认 version 形态重新生成或手动替换)"}
|
|
239
331
|
`);
|
|
240
332
|
} finally {
|
|
241
333
|
if (rl) rl.close();
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// 从 contract/registry.md 生成包内快照 bin/registry-snapshot.json(发版前跑;npm 消费方无仓可读,
|
|
3
|
+
// 快照是 --registry 未传时的核对来源)。CI/内网可随时用 --registry 指最新 registry.md 覆盖快照。
|
|
4
|
+
//
|
|
5
|
+
// 用法:node bin/gen-registry-snapshot.mjs [yarch 仓根目录](默认向上定位 ../../../../)
|
|
6
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { dirname, join, resolve } from "node:path";
|
|
9
|
+
import { parseRegistryMd } from "./registry.mjs";
|
|
10
|
+
|
|
11
|
+
const PKG_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
12
|
+
const repoRoot = resolve(process.argv[2] ?? join(PKG_ROOT, "../../../.."));
|
|
13
|
+
const mdPath = join(repoRoot, "contract", "registry.md");
|
|
14
|
+
|
|
15
|
+
let md;
|
|
16
|
+
try {
|
|
17
|
+
md = readFileSync(mdPath, "utf8");
|
|
18
|
+
} catch {
|
|
19
|
+
console.error(`gen-registry-snapshot: 读不到 ${mdPath}(传 yarch 仓根目录作为参数)`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const { serviceNames, appNames } = parseRegistryMd(md);
|
|
24
|
+
const snapshot = {
|
|
25
|
+
source: "contract/registry.md",
|
|
26
|
+
generatedAt: new Date().toISOString(),
|
|
27
|
+
serviceNames: [...serviceNames].sort(),
|
|
28
|
+
appNames: [...appNames].sort(),
|
|
29
|
+
};
|
|
30
|
+
const out = join(PKG_ROOT, "bin", "registry-snapshot.json");
|
|
31
|
+
writeFileSync(out, `${JSON.stringify(snapshot, null, 2)}\n`);
|
|
32
|
+
console.log(`✅ ${out}:服务名 ${snapshot.serviceNames.length} 个,应用名 ${snapshot.appNames.length} 个`);
|
package/bin/registry.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// registry.md 解析(共享模块:create-admin 校验 与 gen-registry-snapshot 快照生成 同源,防漂移)。
|
|
2
|
+
// 解析 contract/registry.md:二节服务名登记表 + 四节前端应用名登记表(首列反引号包裹的行)。
|
|
3
|
+
export function parseRegistryMd(md) {
|
|
4
|
+
const serviceNames = new Set();
|
|
5
|
+
const appNames = new Set();
|
|
6
|
+
let section = "";
|
|
7
|
+
for (const line of md.split("\n")) {
|
|
8
|
+
const heading = line.match(/^##\s+(一|二|三|四|五|六|七|八|九|十)、/);
|
|
9
|
+
if (heading) {
|
|
10
|
+
section = heading[1];
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
const cell = line.match(/^\|\s*`([a-z][a-z0-9-]{1,31})`\s*\|/);
|
|
14
|
+
if (!cell) continue;
|
|
15
|
+
if (section === "二") serviceNames.add(cell[1]);
|
|
16
|
+
else if (section === "四") appNames.add(cell[1]);
|
|
17
|
+
}
|
|
18
|
+
return { serviceNames, appNames };
|
|
19
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yarch/create-admin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "yarch web 工程生成器:交互问答 + archetype 全量渲染(maven-archetype/cookiecutter 模式,golang cmd/yarch-init 的 web 对偶)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"README.md"
|
|
13
13
|
],
|
|
14
14
|
"publishConfig": { "access": "public" },
|
|
15
|
-
"repository": { "type": "git", "url": "git+https://github.com/
|
|
15
|
+
"repository": { "type": "git", "url": "git+https://github.com/ydonghao/yarch.git", "directory": "stacks/web/packages/create" },
|
|
16
16
|
"license": "Apache-2.0",
|
|
17
17
|
"engines": {
|
|
18
18
|
"node": ">=20"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# AGENTS.md — {{packageName}} 工程守则
|
|
2
|
+
|
|
3
|
+
> 本工程由 yarch 脚手架生成,基于跨栈统一契约(yarch 仓 `contract/`,全部 v1.0 定稿)。
|
|
4
|
+
> 任何 AI 编码代理改码前先读本文件;条文与直觉冲突时以本文件为准,红线改动直接拒绝——机检与 CR 均按此执行。
|
|
5
|
+
|
|
6
|
+
## 契约红线(违反 = 机检失败 / CR 必拒)
|
|
7
|
+
|
|
8
|
+
| 红线 | 规则 | 出处 |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| 统一信封 | 响应一律 `{code, message, data, traceId}` 四字段,`code === 0` 即成功;判错只看 `code`,HTTP 状态码不承载业务语义 | contract/api/rest-response.md |
|
|
11
|
+
| 错误码 | 只用 `@yarch/contract` 的 `errorCodes` 常量(1xxx 通用 / 2xxx 认证);新业务码在业务仓登记 3xxx+ 段位;**禁裸数字错误码** | contract/api/error-codes.md |
|
|
12
|
+
| HTTP 封装 | 业务请求只经 `createClient` 产出的客户端(信封解包 / traceId 透传 / 401 跳登录已内置);**禁裸 fetch/axios 直连业务接口** | 参考 `src/features/*/api.ts` 现状 |
|
|
13
|
+
| 分层方向 | `pages/` 只组合 `features/`(禁直调 `features/*/api.ts`,取数经 hooks);`ui/`·`components/` 禁反向依赖 `features/`·`pages/` | yarch depcruise 同款规则 |
|
|
14
|
+
| traceId | 排查链路键即 `traceId`(W3C traceparent);响应头/信封里的 traceId 禁丢弃,报障必附 | contract/api/logging-trace.md |
|
|
15
|
+
| 命名 | 文件/目录 kebab-case;工程名即服务名(小写短横线,禁裸通用词),改名 = registry 变更评审 | contract/registry.md 一 |
|
|
16
|
+
| 底座升级 | `@yarch/contract`·`@yarch/react` 一律 `pnpm update` 跟进版本;**禁 patch / 改 node_modules / 拷贝源码内联** | — |
|
|
17
|
+
|
|
18
|
+
## 验证(改完必跑,全绿才算完成)
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm build # tsc --noEmit + vite build——生成工程的机检底线
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
平台侧还有契约断言测试与依赖方向机检(depcruise);本工程若引入 CI,建议把两者加进来后再放开依赖方向的约束。
|
|
25
|
+
|
|
26
|
+
## 登记与升级
|
|
27
|
+
|
|
28
|
+
- 服务名 / 错误码段位 / 前端应用名登记:yarch 仓 `contract/registry.md`(PR 即登记);
|
|
29
|
+
- 底座新版本:`pnpm update @yarch/contract @yarch/react`,只改 version 一行。
|
|
30
|
+
|
|
31
|
+
## 完成定义(DoD)
|
|
32
|
+
|
|
33
|
+
tsc 零错 · build 通过 · 新增接口全走统一信封与错误码常量 · 新增取数落在 features 层。
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# AGENTS.md — {{packageName}} 工程守则
|
|
2
|
+
|
|
3
|
+
> 本工程由 yarch 脚手架生成,基于跨栈统一契约(yarch 仓 `contract/`,全部 v1.0 定稿)。
|
|
4
|
+
> 任何 AI 编码代理改码前先读本文件;条文与直觉冲突时以本文件为准,红线改动直接拒绝——机检与 CR 均按此执行。
|
|
5
|
+
|
|
6
|
+
## 契约红线(违反 = 机检失败 / CR 必拒)
|
|
7
|
+
|
|
8
|
+
| 红线 | 规则 | 出处 |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| 统一信封 | 响应一律 `{code, message, data, traceId}` 四字段,`code === 0` 即成功;判错只看 `code`,HTTP 状态码不承载业务语义 | contract/api/rest-response.md |
|
|
11
|
+
| 错误码 | 只用 `@yarch/contract` 的 `errorCodes` 常量(1xxx 通用 / 2xxx 认证);新业务码在业务仓登记 3xxx+ 段位;**禁裸数字错误码** | contract/api/error-codes.md |
|
|
12
|
+
| HTTP 封装 | 业务请求只经 `createClient` 产出的客户端(信封解包 / traceId 透传 / 401 跳登录已内置);**禁裸 fetch/axios 直连业务接口** | 参考 `src/features/*/api.ts` 现状 |
|
|
13
|
+
| 分层方向 | `pages/` 只组合 `features/`(禁直调 `features/*/api.ts`,取数经 hooks);`ui/`·`components/` 禁反向依赖 `features/`·`pages/` | yarch depcruise 同款规则 |
|
|
14
|
+
| traceId | 排查链路键即 `traceId`(W3C traceparent);响应头/信封里的 traceId 禁丢弃,报障必附 | contract/api/logging-trace.md |
|
|
15
|
+
| 命名 | 文件/目录 kebab-case;工程名即服务名(小写短横线,禁裸通用词),改名 = registry 变更评审 | contract/registry.md 一 |
|
|
16
|
+
| 底座升级 | `@yarch/contract`·`@yarch/react` 一律 `pnpm update` 跟进版本;**禁 patch / 改 node_modules / 拷贝源码内联** | — |
|
|
17
|
+
|
|
18
|
+
## 验证(改完必跑,全绿才算完成)
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm build # tsc --noEmit + vite build——生成工程的机检底线
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
平台侧还有契约断言测试与依赖方向机检(depcruise);本工程若引入 CI,建议把两者加进来后再放开依赖方向的约束。
|
|
25
|
+
|
|
26
|
+
## 登记与升级
|
|
27
|
+
|
|
28
|
+
- 服务名 / 错误码段位 / 前端应用名登记:yarch 仓 `contract/registry.md`(PR 即登记);
|
|
29
|
+
- 底座新版本:`pnpm update @yarch/contract @yarch/react`,只改 version 一行。
|
|
30
|
+
|
|
31
|
+
## 完成定义(DoD)
|
|
32
|
+
|
|
33
|
+
tsc 零错 · build 通过 · 新增接口全走统一信封与错误码常量 · 新增取数落在 features 层。
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# AGENTS.md — {{packageName}} 工程守则
|
|
2
|
+
|
|
3
|
+
> 本工程由 yarch 脚手架生成,基于跨栈统一契约(yarch 仓 `contract/`,全部 v1.0 定稿)。
|
|
4
|
+
> 任何 AI 编码代理改码前先读本文件;条文与直觉冲突时以本文件为准,红线改动直接拒绝——机检与 CR 均按此执行。
|
|
5
|
+
|
|
6
|
+
## 契约红线(违反 = 机检失败 / CR 必拒)
|
|
7
|
+
|
|
8
|
+
| 红线 | 规则 | 出处 |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| 统一信封 | 响应一律 `{code, message, data, traceId}` 四字段,`code === 0` 即成功;判错只看 `code`,HTTP 状态码不承载业务语义 | contract/api/rest-response.md |
|
|
11
|
+
| 错误码 | 只用 `@yarch/contract` 的 `errorCodes` 常量(1xxx 通用 / 2xxx 认证);新业务码在业务仓登记 3xxx+ 段位;**禁裸数字错误码** | contract/api/error-codes.md |
|
|
12
|
+
| HTTP 封装 | 业务请求只经 `createClient` 产出的客户端(信封解包 / traceId 透传 / 401 跳登录已内置);**禁裸 fetch/axios 直连业务接口** | 参考 `src/features/*/api.ts` 现状 |
|
|
13
|
+
| 分层方向 | `pages/` 只组合 `features/`(禁直调 `features/*/api.ts`,取数经 hooks);`ui/`·`components/` 禁反向依赖 `features/`·`pages/` | yarch depcruise 同款规则 |
|
|
14
|
+
| traceId | 排查链路键即 `traceId`(W3C traceparent);响应头/信封里的 traceId 禁丢弃,报障必附 | contract/api/logging-trace.md |
|
|
15
|
+
| 命名 | 文件/目录 kebab-case;工程名即服务名(小写短横线,禁裸通用词),改名 = registry 变更评审 | contract/registry.md 一 |
|
|
16
|
+
| 底座升级 | `@yarch/contract`·`@yarch/react` 一律 `pnpm update` 跟进版本;**禁 patch / 改 node_modules / 拷贝源码内联** | — |
|
|
17
|
+
|
|
18
|
+
## 验证(改完必跑,全绿才算完成)
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm build # tsc --noEmit + vite build——生成工程的机检底线
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
平台侧还有契约断言测试与依赖方向机检(depcruise);本工程若引入 CI,建议把两者加进来后再放开依赖方向的约束。
|
|
25
|
+
|
|
26
|
+
## 登记与升级
|
|
27
|
+
|
|
28
|
+
- 服务名 / 错误码段位 / 前端应用名登记:yarch 仓 `contract/registry.md`(PR 即登记);
|
|
29
|
+
- 底座新版本:`pnpm update @yarch/contract @yarch/react`,只改 version 一行。
|
|
30
|
+
|
|
31
|
+
## 完成定义(DoD)
|
|
32
|
+
|
|
33
|
+
tsc 零错 · build 通过 · 新增接口全走统一信封与错误码常量 · 新增取数落在 features 层。
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# AGENTS.md — {{packageName}}(微前端基座)工程守则
|
|
2
|
+
|
|
3
|
+
> 本工程由 yarch 脚手架生成(`--micro base`),基于跨栈统一契约(yarch 仓 `contract/`)与微前端规约 `contract/web/micro-frontend.md`。
|
|
4
|
+
> 任何 AI 编码代理改码前先读本文件;条文与直觉冲突时以本文件为准,红线改动直接拒绝——机检与 CR 均按此执行。
|
|
5
|
+
|
|
6
|
+
## 基座五权(只归基座,条文 micro-frontend.md 一-1)
|
|
7
|
+
|
|
8
|
+
登录态唯一持有(十-1)· 导航端口唯一注册(十-2)· 菜单与路由分发(三-4)· 主题下发(六-1)· 错误兜底(四-5)。子应用索要任何一项 = 架构违规。
|
|
9
|
+
|
|
10
|
+
## 契约红线(违反 = 机检失败 / CR 必拒)
|
|
11
|
+
|
|
12
|
+
| 红线 | 规则 | 出处 |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| manifest 装配 | 子应用接入/下线**只改 `src/app/micro-apps.config.ts` 登记表**(entry/version/routePrefix/menu);禁在任何组件里硬编码子应用路由或菜单 | 十二-2 / 三-4 |
|
|
15
|
+
| 登记先行 | 新子应用应用名须先在 yarch 仓 `contract/registry.md` 四节登记(两段式、首段=已登记服务名、全局不重名),再入本工程登记表 | registry.md 四 |
|
|
16
|
+
| 共享运行时 | `src/micro/shared.ts` 注册 `__YARCH_REACT__ / __YARCH_CONTRACT__ / __YARCH_SUPPLY__` 后才能启动载器;新增共享成员须同步子应用供给层口径 | 八-1 / 八-2 |
|
|
17
|
+
| 事件订阅宿主 | 子应用事件(`{应用名}:{动词-名词}`)的订阅挂**常驻布局壳**(`layouts/basic-layout.tsx`),不挂会随路由卸载的页面;订阅与退订成对 | 九-1 / 七-4 |
|
|
18
|
+
| 统一信封 / 错误码 / traceId | 同单应用档:判错只看 `code`,错误码只用常量,报障必附 traceId | contract/api/* |
|
|
19
|
+
| 底座升级 | `@yarch/contract`·`@yarch/react`·`@micro-zoe/micro-app` 一律 `pnpm update`;禁 patch / 内联拷贝 | — |
|
|
20
|
+
|
|
21
|
+
## 验证(改完必跑)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm build # tsc --noEmit + vite build
|
|
25
|
+
pnpm build:micro 同款子应用联调:入口 URL 经 VITE_SUB_*_URL 注入,禁改死代码
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 完成定义(DoD)
|
|
29
|
+
|
|
30
|
+
tsc 零错 · build 通过 · 新子应用接入只动了登记表 · 基座在子应用全部下线后仍可独立运行(三-1)。
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# {{appName}} · 微前端基座
|
|
2
|
+
|
|
3
|
+
> {{description}}。规约依据:[contract/web/micro-frontend.md](https://github.com/ydonghao/yarch/blob/main/contract/web/micro-frontend.md) v1.0;
|
|
4
|
+
> 载器 micro-app(contract/README.md 关键架构决策登记表默认档,观察哨:停更切 qiankun)。
|
|
5
|
+
|
|
6
|
+
## 五权归基座(三-2/十-1/十-2)
|
|
7
|
+
|
|
8
|
+
登录态与 token、菜单/路由分发、主题与 UI 档定义、全局错误兜底、布局外壳——全部在本工程;
|
|
9
|
+
子应用经 `__YARCH_SUPPLY__`(props 下行,五-5)与共享 contract 单例(八-1)取用,禁子应用自建。
|
|
10
|
+
|
|
11
|
+
## 开发
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm install && pnpm dev # http://localhost:{{port}}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 子应用接入三步(十二-2:入口变更只改 manifest)
|
|
18
|
+
|
|
19
|
+
1. 生成子应用:`npm create @yarch/admin ysaas-billing -- --micro sub --registry <contract/registry.md>`
|
|
20
|
+
2. 在 `src/app/micro-apps.config.ts` 登记入口/路由前缀/菜单元数据(跨环境入口用 `.env.local` 覆盖,十二-7)
|
|
21
|
+
3. 子应用侧起 `pnpm dev:micro`(集成模式 dev server,本基座即可加载)
|
|
22
|
+
|
|
23
|
+
## 双模式冒烟(十一-3,CI 口径)
|
|
24
|
+
|
|
25
|
+
- 子应用独立:`pnpm build`(自足产物)
|
|
26
|
+
- 子应用集成:`pnpm build:micro`(框架/contract 经 window 全局 shim,产物体积消失——八-1/八-2 机检对象)
|
|
27
|
+
|
|
28
|
+
## 部署(十二-3/十二-4)
|
|
29
|
+
|
|
30
|
+
构建产物内容寻址(hash 文件名);nginx 一应用一 root + `try_files` 兜底——样例见 `conf/nginx.conf.example`。
|
|
31
|
+
|
|
32
|
+
## 登记提醒
|
|
33
|
+
|
|
34
|
+
应用名 `{{packageName}}`(首段服务名 `{{service}}`)须在 yarch 仓 `contract/registry.md` 四节前端应用名登记表登记(二-1/二-4);
|
|
35
|
+
storage key / 事件名 / 路由前缀均以应用名为前缀(二-2 一名三用)。
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "yarch 微前端基座模板 · Semi 档:micro-app 载器(默认档)+ manifest 声明式装配 + 登录态/导航/主题/错误兜底五权归基座",
|
|
3
|
+
"variables": [
|
|
4
|
+
{ "name": "packageName", "desc": "应用名(= npm 包名 = 路由前缀 = storage/事件前缀,micro-frontend.md 二-1/二-2)", "required": true, "default": "" },
|
|
5
|
+
{ "name": "appName", "desc": "展示名(index.html 标题)", "required": false, "default": "= packageName" },
|
|
6
|
+
{ "name": "service", "desc": "首段服务名(registry.md 已登记,二-1)", "required": false, "default": "" },
|
|
7
|
+
{ "name": "description", "desc": "工程描述(package.json)", "required": false, "default": "" },
|
|
8
|
+
{ "name": "port", "desc": "vite dev 端口", "required": false, "default": "5173" },
|
|
9
|
+
{ "name": "proxyTarget", "desc": "/api/v1 反向代理目标", "required": false, "default": "http://localhost:8080" },
|
|
10
|
+
{ "name": "yarchContractDep", "desc": "@yarch/contract 依赖(发版前 file: 本地路径,发版后 ^x.y.z)", "required": false, "default": "" },
|
|
11
|
+
{ "name": "yarchReactDep", "desc": "@yarch/react 依赖(同上)", "required": false, "default": "" }
|
|
12
|
+
]
|
|
13
|
+
}
|