@manohub/app-kit 0.2.4 → 0.2.6
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/CONTRACT.md +8 -3
- package/README.md +132 -2
- package/dist/components/app-drawer.d.ts +6 -2
- package/dist/components/app-drawer.js +3 -3
- package/dist/services/app-container.d.ts +14 -0
- package/dist/services/app-container.js +16 -1
- package/lint/__tests__/guardrails.spec.mjs +34 -0
- package/lint/run-all.mjs +7 -0
- package/package.json +2 -2
package/CONTRACT.md
CHANGED
|
@@ -783,9 +783,14 @@ pnpm --filter @manohub/app-kit test:unit # vitest(契约单测)+ 护栏
|
|
|
783
783
|
而令牌(`--ui-*`)与主题桥接(`--f-theme-*`)都锚在 `.app-container` 上、微前端下应用侧 CSS 还被
|
|
784
784
|
scopecss 限定在容器内 —— 落到 body 会让弹窗**内容里所有组件与应用样式一起失效**。
|
|
785
785
|
`AppDialog` / `modalService` 内部已改投 `.app-container`,消费方无需也不应干预渲染宿主。
|
|
786
|
-
11.
|
|
787
|
-
|
|
788
|
-
|
|
786
|
+
11. **抽屉的宿主只接受「选择器字符串」**:`AppDrawer`(§4.18)同样把内容投到 `.app-container`(否则样式全丢),
|
|
787
|
+
但**不能像 `AppDialog` 那样传 Element**:上游 `FDrawer` 算 `f-drawer-inline` 时写的是
|
|
788
|
+
`document.querySelector(host)`,传 Element 会拿 `"[object HTMLDivElement]"` 当选择器解析并抛
|
|
789
|
+
`SyntaxError: not a valid selector`(整页渲染中断,已在 mcp 实测)。本件走容器唯一 id 的
|
|
790
|
+
`#id` 字符串(`resolveAppContainerSelector()`)。
|
|
791
|
+
随之而来的定位问题:上游在「宿主不是 `body`」时会给抽屉根节点加 `f-drawer-inline`
|
|
792
|
+
(把 `position: fixed` 改成 `absolute`)—— 微前端里绝对定位的包含块不可控
|
|
793
|
+
(`.app-container` 自身未定位、宿主层级随门户而变),抽屉与遮罩会错位。
|
|
789
794
|
包内桥接层因此把 `.f-drawer.f-drawer-inline` 的定位压回 `fixed`:**覆盖范围与改造前 `host: "body"` 完全一致**。
|
|
790
795
|
另:上游 `showFooter` 默认 `true` 且高度取 `footerHeight`(默认 60px),不给内容也留一条空白 ——
|
|
791
796
|
`AppDrawer` 在无页脚时直接关掉该区块,应用侧不必再写「隐藏空 footer」的覆盖样式。
|
package/README.md
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
- **接入方必读**:[CONTRACT.md](./CONTRACT.md) —— 页面结构契约、组件用法与词表、样式纪律、反例库、护栏用法、已知偏差。
|
|
7
7
|
**写页面代码前先读它**;它随包分发,冲突时以它为准。
|
|
8
|
+
- **接入 SOP**(安装 → 样式 → 入口 → 护栏 → 验收 → 故障对照 → 新应用从零搭建):[`skills/app-kit/references/adoption.md`](./skills/app-kit/references/adoption.md),随包分发。
|
|
8
9
|
- **改本包时才看**:`AGENTS.md`(包内实现踩坑与硬性要求,不随包分发)
|
|
9
10
|
- **入口**:`@manohub/app-kit/entry` → `createSubApp`
|
|
10
11
|
- **组件/服务**:`@manohub/app-kit` → `AppShell` / `AppPanel` / `AppTree` / `AppTable` / `AppButton` / `notify` …
|
|
11
|
-
- **样式**:`@manohub/app-kit/reset.css` + `@manohub/app-kit/styles.css`(应用侧 `style.css`
|
|
12
|
+
- **样式**:`@manohub/app-kit/reset.css` + `@manohub/app-kit/styles.css`(应用侧 `style.css` 固定三行,见下)
|
|
12
13
|
- **命令入口**:`appkit`(`package.json` 的 `bin`,在应用包根执行)
|
|
13
14
|
- `pnpm exec appkit lint [--changed|--strict|--json]` —— 三条护栏;单条排查用 `appkit lint:style` / `lint:component` / `lint:structure`
|
|
14
15
|
- `pnpm exec appkit install [--also-claude|--dry-run]` —— 落 AI 技能到本工程
|
|
@@ -16,6 +17,135 @@
|
|
|
16
17
|
- 等价写法(老脚本/钩子可用):`node node_modules/@manohub/app-kit/lint/run-all.mjs`、`node node_modules/@manohub/app-kit/skills/install.mjs`
|
|
17
18
|
- 各护栏脚本仍单独可跑(用法见 CONTRACT.md §8)
|
|
18
19
|
|
|
20
|
+
## 新项目接入(快速开始)
|
|
21
|
+
|
|
22
|
+
> 下面是「从零接一个子应用」的最小动作序列,完整版与故障对照见随包分发的
|
|
23
|
+
> [`skills/app-kit/references/adoption.md`](./skills/app-kit/references/adoption.md);
|
|
24
|
+
> 每一条契约条款以 [CONTRACT.md](./CONTRACT.md) 为准。
|
|
25
|
+
|
|
26
|
+
### 1. 安装
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pnpm add @manohub/app-kit
|
|
30
|
+
|
|
31
|
+
# 自备 peer(必须是工程内唯一实例)
|
|
32
|
+
pnpm add vue vue-router pinia @tanstack/vue-query \
|
|
33
|
+
i18next i18next-vue i18next-browser-languagedetector
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- **不要**再单独安装 `@farris/ui-vue`(被骨架层收敛)或 `@manohub/icon`(由骨架层依赖带入)。
|
|
37
|
+
- 应用侧**禁止** `import '@farris/ui-vue'`(护栏会拦),组件一律从 `@manohub/app-kit` 取。
|
|
38
|
+
- 本包发布在 **npm 官方仓**(公开),默认 registry 直接可装。工程若把默认 registry 指到了内网镜像,
|
|
39
|
+
需显式声明作用域(凭据不入库):
|
|
40
|
+
|
|
41
|
+
```ini
|
|
42
|
+
# .npmrc
|
|
43
|
+
@manohub:registry=https://registry.npmjs.org/
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- 工程配置两项:`tsconfig` 用 `moduleResolution: "bundler"`(包的子路径导出靠 `exports`),
|
|
47
|
+
`types` 含 `vite/client`;需要 JSX 页面时加 `@vitejs/plugin-vue-jsx`。
|
|
48
|
+
- 出现「同名类型互不兼容 / provide 取不到」这类双实例症状时,按 adoption.md §6 收敛单例
|
|
49
|
+
(`resolve.dedupe` + tsconfig `paths`)。
|
|
50
|
+
|
|
51
|
+
### 2. 样式:固定三行,顺序即契约
|
|
52
|
+
|
|
53
|
+
```css
|
|
54
|
+
/* src/style.css */
|
|
55
|
+
@import "@manohub/app-kit/reset.css";
|
|
56
|
+
@import "@manohub/app-kit/styles.css";
|
|
57
|
+
@import "./app.css";
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`styles.css` 内部已按 farris CSS → 令牌 → 桥接 → 组件样式汇总,**不要**自行打乱顺序或改写内部导入。
|
|
61
|
+
|
|
62
|
+
### 3. 入口:统一走 `createSubApp`
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
// src/main.ts
|
|
66
|
+
import { createSubApp } from '@manohub/app-kit/entry'
|
|
67
|
+
import App from './App.vue'
|
|
68
|
+
import { routes } from './router'
|
|
69
|
+
import './style.css'
|
|
70
|
+
|
|
71
|
+
export const { mount, unmount } = createSubApp({
|
|
72
|
+
rootComponent: App,
|
|
73
|
+
routes,
|
|
74
|
+
// 用 vue-i18n 的应用以插件注入;本包的 i18n 选项是 i18next 语义,两者不要混用
|
|
75
|
+
// extraPlugins: [i18n],
|
|
76
|
+
// 以 `index.html?xxx=1` 直开的入口(iframe / 选择模式)必须登记,否则首屏守卫会清空 query
|
|
77
|
+
// rootPathAliases: ['/index.html'],
|
|
78
|
+
})
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`createSubApp` 已统一负责 `.app-container` 包裹、pinia、farris 插件、VueQuery、路由、挂载、
|
|
82
|
+
宿主语言监听、首屏守卫、`window.mount/unmount` 与 `microApp.mount/unmount` 协议、非微前端环境自动挂载 ——
|
|
83
|
+
**应用侧不要再手写这些**。全部选项见 adoption.md §3 或 CONTRACT.md §1。
|
|
84
|
+
|
|
85
|
+
### 4. 第一个页面用模板 A
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import { AppShell, AppSearchBox, AppTable, AppPagination } from '@manohub/app-kit'
|
|
89
|
+
|
|
90
|
+
<AppShell>
|
|
91
|
+
<AppShell.Header title="技能分类" toolbar={<AppSearchBox … />} />
|
|
92
|
+
<AppShell.Body mode="table">
|
|
93
|
+
<AppTable framed rows={rows} columns={cols} rowKey="id" />
|
|
94
|
+
</AppShell.Body>
|
|
95
|
+
<AppShell.Footer>
|
|
96
|
+
<AppPagination page={page} pageSize={size} total={total} … />
|
|
97
|
+
</AppShell.Footer>
|
|
98
|
+
</AppShell>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
三种页面模板(列表 / 双栏 / 详情)、筛选与操作位归属、两级滚动契约见 CONTRACT.md §4;
|
|
102
|
+
写页面前务必过一遍 CONTRACT.md 的「四条铁律」与反例库。
|
|
103
|
+
|
|
104
|
+
### 5. 护栏接入(建议,机械判定规范合规)
|
|
105
|
+
|
|
106
|
+
```jsonc
|
|
107
|
+
// appkit-guardrails.config.json(应用包根)
|
|
108
|
+
{
|
|
109
|
+
"$schema": "./node_modules/@manohub/app-kit/lint/guardrails.config.schema.json",
|
|
110
|
+
"apps": [{ "dir": ".", "name": "<app-name>", "prefixes": ["<your-prefix>"], "pending": false }],
|
|
111
|
+
"srcGlobs": ["src/**/*.ts", "src/**/*.tsx"],
|
|
112
|
+
"styleGlobs": ["src/**/*.css"],
|
|
113
|
+
"contractDoc": "node_modules/@manohub/app-kit/CONTRACT.md"
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
```jsonc
|
|
118
|
+
// package.json
|
|
119
|
+
{
|
|
120
|
+
"scripts": {
|
|
121
|
+
"lint": "appkit lint",
|
|
122
|
+
"lint:changed": "appkit lint --changed",
|
|
123
|
+
"lint:strict": "appkit lint --strict"
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
新工程没有存量,直接 `pending: false`;存量应用先产基线再逐步归零(口径见 CONTRACT.md §8)。
|
|
129
|
+
|
|
130
|
+
### 6. 技能包落盘(AI 代理用)
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
pnpm exec appkit install # → .codebuddy/skills/(幂等,包升级后重跑即刷新)
|
|
134
|
+
pnpm exec appkit install --also-claude # 同时 → .claude/skills/
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 7. 验收
|
|
138
|
+
|
|
139
|
+
| 项 | 命令 | 通过标准 |
|
|
140
|
+
|---|---|---|
|
|
141
|
+
| 类型 | `pnpm exec vue-tsc --noEmit` | 0 错(含 `@manohub/app-kit/entry` 等子路径可解析) |
|
|
142
|
+
| 构建 | `pnpm build` | 成功产出 |
|
|
143
|
+
| 护栏 | `pnpm exec appkit lint` | 无违规(或与基线一致;收口用 `--strict`) |
|
|
144
|
+
| 运行 | 启动后打开页面 | 骨架与组件样式正常、弹层落点正常 |
|
|
145
|
+
|
|
146
|
+
还有一批**本包管不到、必须向宿主平台确认**的项(子应用产物路径与挂载方式、是否有 `index.html?xxx=1`
|
|
147
|
+
直开入口、dev server 端口与代理、宿主下发的语言键与初始路由约定)—— 清单见 adoption.md §9.7。
|
|
148
|
+
|
|
19
149
|
## 分发形态
|
|
20
150
|
|
|
21
151
|
由**源码分发**改为**产物分发**:`exports` 指向 `dist`(含类型声明与 `styles.css` / `reset.css`)。
|
|
@@ -26,7 +156,7 @@
|
|
|
26
156
|
- `skills/` 是随包分发的 AI 技能包(见下);
|
|
27
157
|
- 包内不存在 `dist/` 时先执行构建再联调。
|
|
28
158
|
|
|
29
|
-
## 技能包(AI
|
|
159
|
+
## 技能包(AI 代理用,随包分发)
|
|
30
160
|
|
|
31
161
|
随包分发三个技能:`app-kit`(入口编排)/ `app-kit-migrate`(存量应用改造)/ `app-kit-dev`(日常页面开发)。
|
|
32
162
|
在消费方工程根执行即可落到自己的技能目录(幂等,包升级后重跑即刷新):
|
|
@@ -9,8 +9,12 @@ import { type PropType, type SlotsType, type VNodeChild } from 'vue';
|
|
|
9
9
|
* 吃掉的上游坑:
|
|
10
10
|
* 1. **被当 DOM 容器的宽度**:上游 `width` 声明成 `String`、默认 `"300"`,值会原样落进行内 style
|
|
11
11
|
* ⇒ `width:300` 不是合法 CSS,抽屉宽度会退化成「内容宽度」。本件默认 `width: 480`(数值 ⇒ `480px`)。
|
|
12
|
-
* 2. **渲染宿主固定为 `.app-container
|
|
13
|
-
*
|
|
12
|
+
* 2. **渲染宿主固定为 `.app-container`,且必须传「选择器字符串」**:上游 `host` 默认 `"body"`,
|
|
13
|
+
* 抽屉落容器外会同时丢令牌(`--ui-*`)与应用侧样式(微前端下被 scopecss 限定在容器内)——
|
|
14
|
+
* 与 AppDialog 同一件事。但**传法不同**:`FModal` 的 `host` 是 `Object`(可传 Element),
|
|
15
|
+
* `FDrawer` 算 `f-drawer-inline` 时写的是 `document.querySelector(host)` —— 传 Element 会拿
|
|
16
|
+
* `"[object HTMLDivElement]"` 当选择器解析并抛 `SyntaxError`(非法选择器,整页渲染中断)。
|
|
17
|
+
* 故这里走 `resolveAppContainerSelector()`(给容器补唯一 id 再返回 `#id`)。
|
|
14
18
|
* 随之而来的第二个坑:上游在 host ≠ body 时给根节点加 `f-drawer-inline`(`position: absolute`),
|
|
15
19
|
* 而绝对定位的包含块在微前端里不可控,包内桥接层已把它改回 `fixed`
|
|
16
20
|
* (覆盖范围与改造前 `host: "body"` 一致)。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FDrawer } from "@farris/ui-vue";
|
|
2
2
|
import { defineComponent, computed, h } from "vue";
|
|
3
|
-
import {
|
|
3
|
+
import { resolveAppContainerSelector } from "../services/app-container.js";
|
|
4
4
|
const FarrisDrawer = FDrawer;
|
|
5
5
|
let drawerSeq = 0;
|
|
6
6
|
const AppDrawer = /* @__PURE__ */ defineComponent({
|
|
@@ -80,8 +80,8 @@ const AppDrawer = /* @__PURE__ */ defineComponent({
|
|
|
80
80
|
* 无内容时关掉上游页脚区块 —— 否则恒定渲染一条 `footerHeight`(默认 60px)的空白。
|
|
81
81
|
*/
|
|
82
82
|
showFooter: hasFooter,
|
|
83
|
-
/** 渲染宿主:见头注释第 2 条(farris 默认 `"body"`
|
|
84
|
-
host:
|
|
83
|
+
/** 渲染宿主:见头注释第 2 条(farris 默认 `"body"` 会让抽屉样式全丢;且上游只吃字符串选择器) */
|
|
84
|
+
host: resolveAppContainerSelector(),
|
|
85
85
|
customClass: ["ak-drawer", attrs.class].filter(Boolean).join(" "),
|
|
86
86
|
customStyle: attrs.style,
|
|
87
87
|
"onUpdate:modelValue": handleUpdate
|
|
@@ -13,3 +13,17 @@
|
|
|
13
13
|
* → `document.body`(兜底,行为与改写前一致,不会更差)。
|
|
14
14
|
*/
|
|
15
15
|
export declare function resolveAppContainer(): Element;
|
|
16
|
+
/**
|
|
17
|
+
* 同 `resolveAppContainer`,但返回**选择器字符串** —— 给「上游只吃字符串宿主」的件用。
|
|
18
|
+
*
|
|
19
|
+
* 为什么不能直接给 Element:farris `FDrawer` 算 `f-drawer-inline` 时写的是
|
|
20
|
+
* `typeof host === 'string' ? host !== 'body' : document.querySelector(host)` ——
|
|
21
|
+
* 传 Element 会落到后半段,`document.querySelector(元素)` 拿到的是 `"[object HTMLDivElement]"`
|
|
22
|
+
* 这个**非法选择器**,当场抛 `SyntaxError: ... is not a valid selector`(实测,整页渲染因此中断)。
|
|
23
|
+
* (对照:`FModal` 的 `host` 声明为 `Object`,传 Element 正常 —— 两个件不是一套规则。)
|
|
24
|
+
*
|
|
25
|
+
* 给字符串又要避免「门户里多应用并存时串到第一个 `.app-container`」,故给容器补一个
|
|
26
|
+
* **进程内唯一 id** 再用 `#id` 定位;容器已有 id 时直接用它的。
|
|
27
|
+
* 兜底到 `document.body` 时返回 `"body"`(上游对该值有专门分支,不查 DOM)。
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveAppContainerSelector(): string;
|
|
@@ -2,6 +2,21 @@ import { getCurrentAppContainer } from "./app-context.js";
|
|
|
2
2
|
function resolveAppContainer() {
|
|
3
3
|
return getCurrentAppContainer() ?? document.querySelector(".app-container") ?? document.body;
|
|
4
4
|
}
|
|
5
|
+
const containerIds = /* @__PURE__ */ new WeakMap();
|
|
6
|
+
let containerSeq = 0;
|
|
7
|
+
function resolveAppContainerSelector() {
|
|
8
|
+
const container = resolveAppContainer();
|
|
9
|
+
if (container === document.body) return "body";
|
|
10
|
+
if (container.id) return `#${container.id}`;
|
|
11
|
+
let id = containerIds.get(container);
|
|
12
|
+
if (!id) {
|
|
13
|
+
id = `ak-app-container-${containerSeq += 1}`;
|
|
14
|
+
containerIds.set(container, id);
|
|
15
|
+
container.id = id;
|
|
16
|
+
}
|
|
17
|
+
return `#${id}`;
|
|
18
|
+
}
|
|
5
19
|
export {
|
|
6
|
-
resolveAppContainer
|
|
20
|
+
resolveAppContainer,
|
|
21
|
+
resolveAppContainerSelector
|
|
7
22
|
};
|
|
@@ -240,6 +240,40 @@ test('规则级豁免:--strict 时豁免一律失效(收口验收口径)',
|
|
|
240
240
|
}
|
|
241
241
|
})
|
|
242
242
|
|
|
243
|
+
test('统一入口:--strict 必须透传给三条子护栏(否则收口验收空转)', () => {
|
|
244
|
+
const root = makeConsumer('violations-src')
|
|
245
|
+
try {
|
|
246
|
+
// 三条规则整类豁免 + 不挂起:平时全绿,收口预演必须拦断 —— 差别只在 `--strict` 有没有传下去
|
|
247
|
+
writeConfig(root, [
|
|
248
|
+
{
|
|
249
|
+
dir: 'app',
|
|
250
|
+
name: 'fixture-app',
|
|
251
|
+
prefixes: ['other-'],
|
|
252
|
+
pending: false,
|
|
253
|
+
waivedRules: [
|
|
254
|
+
{ rule: 'api/*', reason: '分阶段迁移:组件替换在下一批次', since: '2026-09-18' },
|
|
255
|
+
{ rule: 'style/*', reason: '分阶段迁移:样式收口在下一批次', since: '2026-09-18' },
|
|
256
|
+
{ rule: 'structure/*', reason: '本 fixture 用于验证参数透传', since: '2026-09-18' },
|
|
257
|
+
],
|
|
258
|
+
},
|
|
259
|
+
])
|
|
260
|
+
|
|
261
|
+
const plain = runAuditWith('run-all.mjs', root)
|
|
262
|
+
assert.equal(plain.code, 0, '平时:三整类豁免 → 全绿')
|
|
263
|
+
assert.ok(plain.out.includes('全绿'), `平时汇总行应为全绿,实际:${plain.out}`)
|
|
264
|
+
|
|
265
|
+
const strict = runAuditWith('run-all.mjs', root, ['--strict'])
|
|
266
|
+
assert.equal(strict.code, 1, '--strict:豁免失效 → 必须拦断(收口验收的唯一口径)')
|
|
267
|
+
assert.ok(!strict.out.includes('全绿'), `--strict 不应再报全绿,实际:${strict.out}`)
|
|
268
|
+
// 三条子护栏都要真的按 strict 跑(只透传给一条同样会退化成半空转)
|
|
269
|
+
for (const rule of ['api/farris-import', 'style/visual', 'structure/no-shell']) {
|
|
270
|
+
assert.ok(strict.out.includes(rule), `--strict 报告里应出现 ${rule},实际:${strict.out}`)
|
|
271
|
+
}
|
|
272
|
+
} finally {
|
|
273
|
+
rmSync(root, { recursive: true, force: true })
|
|
274
|
+
}
|
|
275
|
+
})
|
|
276
|
+
|
|
243
277
|
test('规则级豁免:0 条命中时提示可撤销(豁免只该在「还没迁到那层」期间存在)', () => {
|
|
244
278
|
const root = makeConsumer('clean-src')
|
|
245
279
|
try {
|
package/lint/run-all.mjs
CHANGED
|
@@ -26,6 +26,13 @@ const AUDITS = ['style-audit.mjs', 'component-audit.mjs', 'structure-audit.mjs']
|
|
|
26
26
|
const args = parseArgs()
|
|
27
27
|
const passthrough = process.argv.slice(2).filter((a) => a.startsWith('--app=') || a.startsWith('--cwd='))
|
|
28
28
|
if (args.changed) passthrough.push('--changed')
|
|
29
|
+
/**
|
|
30
|
+
* `--strict` 必须透传:它决定的是**子护栏**的拦截口径(存量挂起与规则豁免失效),
|
|
31
|
+
* 而不只是本脚本的输出。漏传过一次 —— 表现是 `appkit lint --strict` 恒绿(豁免照旧生效),
|
|
32
|
+
* 收口验收因此变成空转,看输出完全看不出问题。
|
|
33
|
+
* 回归由 `lint/__tests__/guardrails.spec.mjs` 的「统一入口:--strict 必须透传」锁住。
|
|
34
|
+
*/
|
|
35
|
+
if (args.strict) passthrough.push('--strict')
|
|
29
36
|
if (args.json) passthrough.push('--json')
|
|
30
37
|
|
|
31
38
|
const runOne = (script) =>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manohub/app-kit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "子应用统一骨架层:入口编排(createSubApp)、布局契约(AppShell)、页面组件、原子件、服务、样式底座。farris 被收敛在本包内部,对外只暴露标准 API。",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@farris/ui-vue": "^1.8.4",
|
|
66
|
-
"@manohub/icon": "^0.2.
|
|
66
|
+
"@manohub/icon": "^0.2.6"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@tanstack/vue-query": "catalog:",
|