npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@manohub/app-kit

v0.4.3

Published

子应用统一骨架层:入口编排(createSubApp)、布局契约(AppShell)、页面组件、原子件、服务、样式底座。farris 被收敛在本包内部,对外只暴露标准 API。

Readme

@manohub/app-kit

子应用统一骨架层(预编译产物分发,消费方按版本号安装):入口编排、布局契约(AppShell/AppPanel)、页面组件、原子件、服务、样式底座。 底层组件库(farris)被收敛在本包内部 —— 消费方不得安装或直连它。

  • 接入方必读:CONTRACT.md —— 页面结构契约、组件用法与词表、样式纪律、反例库、护栏用法、已知偏差。 写页面代码前先读它;它随包分发,冲突时以它为准。
  • 接入 SOP(安装 → 样式 → 入口 → 护栏 → 验收 → 故障对照 → 新应用从零搭建):skills/app-kit/references/adoption.md,随包分发。
  • 改本包时才看:AGENTS.md(包内实现踩坑与硬性要求,不随包分发)
  • 入口:@manohub/app-kit/entry → createSubApp
  • 组件/服务:@manohub/app-kit → AppShell / AppPanel / AppTree / AppNav / AppTable / AppButton / notify …
  • 样式:@manohub/app-kit/reset.css + @manohub/app-kit/styles.css(应用侧 style.css 固定三行,见下)
  • 命令入口:appkit(package.json 的 bin,在应用包根执行)
    • pnpm exec appkit lint [--changed|--strict|--json] —— 三条护栏;单条排查用 appkit lint:style / lint:component / lint:structure
    • pnpm exec appkit install [--also-claude|--dry-run] —— 落 AI 技能到本工程
    • npm 消费方把 pnpm exec 换成 npx;scripts 里可直接写 appkit lint(.bin 在 PATH 里)
    • 等价写法(老脚本/钩子可用):node node_modules/@manohub/app-kit/lint/run-all.mjs、node node_modules/@manohub/app-kit/skills/install.mjs
    • 各护栏脚本仍单独可跑(用法见 CONTRACT.md §8)

新项目接入(快速开始)

下面是「从零接一个子应用」的最小动作序列,完整版与故障对照见随包分发的 skills/app-kit/references/adoption.md; 每一条契约条款以 CONTRACT.md 为准。

1. 安装

pnpm add @manohub/app-kit

# 自备 peer(必须是工程内唯一实例)
pnpm add vue vue-router pinia @tanstack/vue-query vue-i18n
  • 不要再单独安装 @farris/ui-vue(被骨架层收敛)或 @manohub/icon(由骨架层依赖带入)。

  • vue-i18n 即使不用也必须装:createSubApp 所在模块会静态引入它,漏装时 vite build 直接失败 (Rollup failed to resolve import "vue-i18n")—— 应用侧不传 i18n 选项、不写 useI18n() 也一样要装。

  • 应用侧禁止 import '@farris/ui-vue'(护栏会拦),组件一律从 @manohub/app-kit 取。

  • 本包发布在 npm 官方仓(公开),默认 registry 直接可装。工程若把默认 registry 指到了内网镜像, 需显式声明作用域(凭据不入库):

    # .npmrc
    @manohub:registry=https://registry.npmjs.org/
  • 工程配置两项:tsconfig 用 moduleResolution: "bundler"(包的子路径导出靠 exports), types 含 vite/client;需要 JSX 页面时加 @vitejs/plugin-vue-jsx。

  • 出现「同名类型互不兼容 / provide 取不到」这类双实例症状时,按 adoption.md §6 收敛单例 (resolve.dedupe + tsconfig paths)。

2. 样式:固定三行,顺序即契约

/* src/style.css */
@import "@manohub/app-kit/reset.css";
@import "@manohub/app-kit/styles.css";
@import "./app.css";

styles.css 内部已按 farris CSS → 令牌 → 桥接 → 组件样式汇总,不要自行打乱顺序或改写内部导入。

3. 入口:统一走 createSubApp

// src/main.ts
import { createSubApp } from '@manohub/app-kit/entry'
import App from './App.vue'
import { routes } from './router'
import './style.css'

export const { mount, unmount } = createSubApp({
  rootComponent: App,
  routes,
  // i18n(vue-i18n):实例由骨架层唯一创建并注册,这里只给词条;详见 CONTRACT.md §10
  // i18n: { messages: { en, zh } },
  // 以 `index.html?xxx=1` 直开的入口(iframe / 选择模式)必须登记,否则首屏守卫会清空 query
  // rootPathAliases: ['/index.html'],
  // 宿主不支持深路径 fallback 时改 hash;需要自定义 base 时传 RouterHistory 实例
  // history: 'hash',
})

createSubApp 已统一负责 .app-container 包裹、pinia、farris 插件、i18n 装配与宿主语言同步、VueQuery、路由、挂载、 首屏守卫、window.mount/unmount 与 microApp.mount/unmount 协议、非微前端环境自动挂载 —— 应用侧不要再手写这些。全部选项见 adoption.md §3 或 CONTRACT.md §1,i18n 专项见 CONTRACT.md §10。

4. 第一个页面用模板 A

import { AppShell, AppSearchBox, AppTable, AppPagination } from '@manohub/app-kit'

<AppShell>
  <AppShell.Header title="技能分类" toolbar={<AppSearchBox … />} />
  <AppShell.Body mode="plain">
    <AppTable framed rows={rows} columns={cols} rowKey="id" />
  </AppShell.Body>
  <AppShell.Footer>
    <AppPagination page={page} pageSize={size} total={total} … />
  </AppShell.Footer>
</AppShell>

三种页面模板(列表 / 双栏 / 详情)、筛选与操作位归属、两级滚动契约见 CONTRACT.md §4; 写页面前务必过一遍 CONTRACT.md 的「四条铁律」与反例库。

5. 护栏接入(建议,机械判定规范合规)

// appkit-guardrails.config.json(应用包根)
{
  "$schema": "./node_modules/@manohub/app-kit/lint/guardrails.config.schema.json",
  "apps": [{ "dir": ".", "name": "<app-name>", "prefixes": ["<your-prefix>"], "pending": false }],
  "srcGlobs": ["src/**/*.ts", "src/**/*.tsx"],
  "styleGlobs": ["src/**/*.css"],
  "contractDoc": "node_modules/@manohub/app-kit/CONTRACT.md"
}
// package.json
{
  "scripts": {
    "lint": "appkit lint",
    "lint:changed": "appkit lint --changed",
    "lint:strict": "appkit lint --strict"
  }
}

新工程没有存量,直接 pending: false;存量应用先产基线再逐步归零(口径见 CONTRACT.md §8)。

6. 技能包落盘(AI 代理用)

pnpm exec appkit install                 # → .codebuddy/skills/(幂等,包升级后重跑即刷新)
pnpm exec appkit install --also-claude   # 同时 → .claude/skills/

7. 验收

| 项 | 命令 | 通过标准 | |---|---|---| | 类型 | pnpm exec vue-tsc --noEmit | 0 错(含 @manohub/app-kit/entry 等子路径可解析) | | 构建 | pnpm build | 成功产出 | | 护栏 | pnpm exec appkit lint | 无违规(或与基线一致;收口用 --strict) | | 运行 | 启动后打开页面 | 骨架与组件样式正常、弹层落点正常 |

还有一批本包管不到、必须向宿主平台确认的项(子应用产物路径与挂载方式、是否有 index.html?xxx=1 直开入口、dev server 端口与代理、宿主下发的语言键与初始路由约定)—— 清单见 adoption.md §9.7。

分发形态

由源码分发改为产物分发:exports 指向 dist(含类型声明与 styles.css / reset.css)。

  • 公开入口名与源码分发期逐字一致,消费方的引用语句与样式导入三行不需要改;
  • 消费方不再需要为本包准备 TSX 编译配置或单例包的类型钉死;
  • lint/、CONTRACT.md 仍原样随包分发(消费方的护栏与契约按包内路径引用它们);
  • skills/ 是随包分发的 AI 技能包(见下);
  • 包内不存在 dist/ 时先执行构建再联调。

技能包(AI 代理用,随包分发)

随包分发三个技能:app-kit(入口编排)/ app-kit-migrate(存量应用改造)/ app-kit-dev(日常页面开发)。 在消费方工程根执行即可落到自己的技能目录(幂等,包升级后重跑即刷新):

pnpm exec appkit install                 # → .codebuddy/skills/
pnpm exec appkit install --also-claude   # 同时 → .claude/skills/
pnpm exec appkit install --dry-run       # 只预览

装了之后,代理在做接入、迁移或页面开发时会命中本包规范与流程;技能职责边界与维护约定见 skills/README.md。

来源

本包由 gsp-cloud-ds/dip/ibp/aihub/aihub-frontend 的 app-kit 分支(导入 commit 315b60f)迁入, 只调整分发形态,未改包内实现。设计与实现依据(原仓 docs/plans/*)未随包迁入,留档在来源仓。