@12-apps/app-shell

中文文档
5.14.1发布于 2026/10/27MITTypeScriptES Module构建来源已验证近 30 天下载 3.4万

一个产品份额的外壳三相(12-18). 无框架核心(.):打入的JSON API客户端及其ApiError,WCAG品牌-palette校正,pt-BR格式化, stale-chunk恢复和同意线. 浏览器半个(./反应:创建WebApp)

中文使用文档
文档目录7 节
  1. 为什么是包裹
  2. 两分之一
  3. 两个客户,分钱是CALLER
  4. useServerDataViews —— URL是查询
  5. 在你读代码前有三件事值得了解
  6. 同意的故事,在一个段落中
  7. 测试

@ 12- apps/ app- shell

一个产品份额的几个SPA壳作为可安装包: 已打入 API 客户端及其 ApiError,MUI主题 建筑在一个租户的品牌种子 会话、 路由错误边界、 路由级别代码分割以幸存 部署、条件/事先同意门——以及该门后端的小地表 需要帮助.

pnpm add @12-apps/app-shell

收养合同、所需接头和锋利: 采用.md。 。 。 .

WebAppShellConfig.theme (和 createAppTheme 直接)也要求 density —— 说 'compact' | 'normal' | 'comfortable' 或原始因子,镜像 @12-apps/ui属于自己的 UiThemeOptions.density设置它移动类型尺度, 带密度的MUI 组件覆盖和设置 theme.density。它也会改变宿主本身如何 theme.components 与工厂合并:没有密度,主机条目 用于一个组件 REPLACES 整个条目; 与一个, SLOT 合并两个条目 相反(defaultProps 浅浮出水面, variants )——见: AppThemeOptions.density自己的医生和 采用.md 在此之前 组合密度和您自己的组件覆盖.

density 单枪匹马无所事事——通过 densityTheme 我也一样. 此软件包参考 至密度执行,只按类型,所以一个从未设置密度的主机 从来没有在第一次涂料上运送模块。 想要密度导入的主机 执行本身和通过:

import { densityThemeOptions } from '@12-apps/ui/tokens';

createAppTheme('light', { density: 'compact', densityTheme: densityThemeOptions });

density 没有 densityTheme 构建无密度主题和 console.warns一次,在开发中,命名缺失选项.

为什么是包裹

三个SPA不能分享任何东西,所以他们分享一个私人的一揽子方案——和一个私人的 软件包是其他人无法安装的。 这个是5218LOC 确切的东西 浏览器中的每个多租户产品需求,其子系统一直在运行 一次到自己的包(@12-apps/realtime, (中文(简体) ), @12-apps/notifications, (中文(简体) ), @12-apps/observability-frontend, (中文(简体) ), @12-apps/auth) (中文(简体) ). 什麽 留下的就是外壳本身 里面的就是它们.

两分之一

const shell        = createWebAppShell({ /* config */ });   // browser
const { routes }   = createApiAppShell({ /* config */ });    // backend

shell.Provider 环绕您的路由是整个浏览器接线——路由错误 边界是 内部 这样 onCrash 到达时你没有带任何东西. 如果您想要一个崩溃的页面来保留该页面, 请将第二个边界置于您自己的铬下方 侧边栏;最近的一条接住, 所以没有双倍.

子路径里面有什么东西
.无框架 : apiFetch 编号 : ApiError, (中文(简体) ), restResult, (中文(简体) ), joinApiPath 编号 : stripTrailingSlashes,WCAG品牌-palette修正,pt-BR钱和持续时间格式化, stale-chunk恢复,同意线.
./reactcreateWebAppShell - 供应商塔(包括边界),主题, lazyRoute同意门, useDeviceDetection, (中文(简体) ), useServerDataViews而相撞的导航持续状态useCollapsedSections, (中文(简体) ), useSidebarRail) (中文(简体) ).
./servercreateApiAppShell - 同意地位/接受说明,框架中立.
./hono四十行相应者. hono 是一个可选的对等点.
./viteappShellOptimizeDeps() ——依赖预分解预设. 所编而成,而所须也.

两个客户,分钱是CALLER

apiFetch 掷出 ApiError 一个非2xx. restResult 返回时 { ok: false, error, fieldErrors?, status? }都说 { data } 编号 : { error, issues } 包含每个 createApi* 软件包解答输入, 所以屏幕 可以在没有第二个适配器的情况下混合它们.

到达 apiFetch 对于阅读和任何 失败是别人的 来处理 — 一个查询、 预选、 背景更新。 到达 restResult 人类在等待着写作: 呈文有两种普通的结果,一种是 即“服务器拒绝并命名了字段”,所以写成 掷出每个处理器的成本 a try编号 :catch 他们的捕捉是主要路径.

status 是故意的ABSENT 在网络故障。 只有这样 将“服务器说不”和“没有回答”区分开来 显示,另一个是重试——它让一个平行的表面告诉一个403 ("不是你的",在按钮旁说) 从409("有人更快", 刷新).

useServerDataViews —— URL是查询

A 类 DataViewsGrid 在服务器模式中过滤器中, 并且不自行排序: 它 EMITS a DataViewQuery 和主捕捉。 这个钩子是路由器驱动的答案—— 它映射查询到搜索参数并替换它们,以及页面的查询 钩子,按键在那些抛物, 重新fetches。 将状态保存在 URL 中大多数 是什么把管理员名单 一个人可以工作 与他们战斗: a被过滤的可链接、可重装和可后扣.

const server = useServerDataViews({
  totalCount, page, pageSize,
  toParams: (query) => ({ q: query.search || undefined, type: query.filters.type }),
});

两种行为是累赘的,由案件支撑,而不是留给 注释 :

  • 只有自由的文本发音. 过滤芯片或页码离开搜索 不变并同步应用; 等待250ms的点击会感觉断裂 .
  • 它与 LIVE URL 合并,而不是路由器的功能快照。 A 类 从间隔写前的定时器中执行解开的搜索 由 URL 的另一个所有者(一行点击写入) ?view=)和路由器 快照可以延后它,所以行选择会消失在一秒之后 接线员成功了.

底名来自 ROUTER (useHref('/')而不是从捆绑者那里 已配置基础 。 这是两个来源 一个事实,只同意 当他们 配置相同,读取捆绑器就可以使模块 外面可以卸货.

在你读代码前有三件事值得了解

ApiError 用于另一个已发布的软件包. @12-apps/entitlements上市频道决定拒绝是否是计划 通过阅读拒绝 status 财务报告和审定财务报表 body 脱掉这个 三地被钉住 以一个测试的原因.

这里没有报告它不能回头的成功. 同意终点传播a 写作失败为500,而不是回答204,因为写作失败为204 告诉用户他们接受,而每个守卫都拒绝. onCrash, (中文(简体) ), isCurrent, (中文(简体) ), consent 财务报告和审定财务报表 brand.name 需要而不是默认,因为 他们的每个可能的默认 都默默地失败了 检查——和边界 onCrash 报告来自挂载而不是 记录,出于同样的原因.

租户TYPED的颜色不是你能画的颜色. 一个牌子六重奏被选中 标语上看起来不错,不能像白卡上14px的文字那样清晰:一个真正的种子 租户 #7ED957 其价格为1.76:1而下限为4.5:1。 调色板 所以房客认得他们的肤色 无法选择无法读取的 .

同意的故事,在一个段落中

POST /consent/terms 总是可以FIX的用户 其接受已经停滞. 没有什么东西能告诉他们,所以从来没有人叫它: 每一个先前同意的用户都默默地进入一个待定的用户——仍然在其中签字, 他们听到的第一件事是赤裸裸的 401 {"error":"Unauthorized"} 在支付步骤上, 重试永远无法 成功 . GET /consent/status 是失落的一半, 大门是它是什么, 因此,两分之一是一揽子:在一条道路上达成一致的两端是: 整个功能.

测试

pnpm test          # the package's own suites

消费者证明住在 harness/ 在 repo 根: 驱动真实的一页 createWebAppShell 对一个真实的 createApiAppShell 挂载,均安装于 包装的柏油丸.

版本与发布记录

@12-apps/app-shell 共发布 30 个版本,首次发布于 2026/08/13;过去 12 个月发布了 30 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
5.14.1latest2026/10/2710 天前
5.14.02026/10/2512 天前
5.13.12026/09/291 个月前
5.13.02026/09/291 个月前
5.12.02026/09/281 个月前
5.8.2app-shell-5.8.x2026/09/251 个月前

关于 @12-apps/app-shell 的常见问题

@12-apps/app-shell 是什么?

一个产品份额的外壳三相(12-18). 无框架核心(.):打入的JSON API客户端及其ApiError,WCAG品牌-palette校正,pt-BR格式化, stale-chunk恢复和同意线. 浏览器半个(./反应:创建WebApp)

如何安装 @12-apps/app-shell?

在项目目录运行 npm install @12-apps/app-shell,或使用 pnpm add / yarn add / bun add。

@12-apps/app-shell 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@12-apps/app-shell 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@12-apps/app-shell 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@12-apps/app-shell 可以商用吗?

@12-apps/app-shell 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@12-apps/app-shell 的下载量有多少?

根据 npm 官方下载统计,@12-apps/app-shell 在 2026/10/04 – 2026/11/02 这 30 天内被下载 33,590 次,日均约 1,120 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@12-apps/app-shell 还在维护吗?

最新版本 5.14.1 发布于 2026/10/27(10 天前);至今共发布 30 个版本,其中过去 12 个月发布了 30 个;首次发布于 2026/08/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。