@devopsplaybook.io/common-web

中文文档
0.12.1发布于 2026/11/06ISCES Module近 30 天下载 3827

DevOpsPlaybook 网络应用程序共享 Nuxt 层

中文使用文档
文档目录13 节
  1. 快开始
  2. 构成部分
  3. B. 可构成物和服务
  4. 认证状态和 HTTP 集成
  5. 服务器 URL 配置
  6. 服务退后
  7. SSR和仅限客户使用
  8. 脚本和app-shell 样式
  9. 苹果壳钩
  10. 覆盖一个组件
  11. 兼容性和释放政策
  12. 包装、类型和副作用
  13. 发展

@devopsplaybook.io/common-web (英语)

一个小的,不建 Nuxt 4层 包含共享设计符牌,UI组件, devOpsPlaybook 网页应用程序的可编译和浏览器服务.

快开始

npm install @devopsplaybook.io/common-web

从您的 Nuxt 配置中扩展层 :

export default defineNuxtConfig({
  extends: ["@devopsplaybook.io/common-web"],
});

层组件和可堆积由Nuxt自动导入. 货船 原始 Vue 和 TypeScript 源; 您的应用程序的 Nuxt 构建汇编它们 。 纳克特4是 所需经费。 这个 playground/ 目录显示一个消耗性应用.

构成部分

构成部分目的
<Loading size="small" />可用的装载指标; size 实值 small 或者说 large。动画在 prefers-reduced-motion: reduce。 。 。 .
<AlertMessages />可访问的现场区域,显示发布的信息 EventBus,每个带每个消息 开除 按钮.
<AppNavigation :links="links" :link-component="NuxtLink" label="Primary" />带有名称的导航外壳 brand 插槽,可配置链接(label, (中文(简体) ), to选项 icon 财务报告和审定财务报表 active)和可选择的可访问性 label。 。 。 .
<OfflineBanner message="You are offline." />宣布下线状态,并通过默认槽接受替换内容.

AlertMessages 监听 EventTypes.ALERT_MESSAGE 事件。 它的有效载荷是: { text, type?, durationMs? } 与 type 限于 info, (中文(简体) ), success, (中文(简体) ), warning 或者说 error。默认显示时间为5秒; durationMs: 0 保存信件直到用户激活 开除 按钮。 负持续时间被夹到 0他们将永居其中; 非无限值NaN, (中文(简体) ), Infinity)使用五秒默认值. 错误渲染 充满自信 role="alert" 以礼相待的方式 role="status" 区域。 这两个地区是兄弟姐妹,总是挂起,所以 每条消息都公布一次。 解除管制是本地人 <button type="button"> 带有无障碍名称 Dismiss 和明显的焦点 铃声。 同名词 type + 键 text 双对被复制,队列不变 大部分5条留言, 放弃最古老的第一。 提醒样式使用前缀 .alert-message* 分类,所以消费者样式表不受 层的全局样式. handleError(error, { debug = false } = {}) 日志 a 静态摘要(消息、状态、方法、没有查询字符串的路径) 带有证书被编辑)并发出相应的出错提示. debug: true 日志原始错误对象,其中可能包含证书,并且是 仅供发展之用.

AppNavigation 简单化 <a href> 默认链接, 保留 非纳克特深层进口和原材料使用有效。 Nuxt 应用程序应当 通过它们的链接组件来保持SPA状态的导航:

<script setup lang="ts">
import { resolveComponent } from "vue";

const NuxtLink = resolveComponent("NuxtLink");
</script>

<template>
  <AppNavigation :links="links" :link-component="NuxtLink" />
</template>

这个 label 道具设置可访问导航的名称和默认值 Main navigation。在页面上给每个导航一个不同的标签,这样屏幕 读者用户可以分辨:

<AppNavigation :links="primaryLinks" label="Primary" />
<AppNavigation :links="secondaryLinks" label="Secondary" />

链接按目标和位置键,所以重复 to 目标仍在实现; 在开发中,组件在检测到重复时记录警告.

OfflineBanner 保留它 role="status" 随时挂起的活区 屏幕阅读器宣布过渡; 而在线区域为视觉 藏起来 横幅会隐藏在服务器 HTML 中并反映真实 水合后连接 默认副本为中性 You are offline.; 替换为 message 道具或默认槽.

B. 可构成物和服务

  • useTheme() 持续 light编号 :dark 首选项 localStorage 并适用 data-theme 转到文档根。 状态是一个全单元的单子: useTheme() 调用相同 preference 财务报告和审定财务报表 isDark 裁判,请稍等 电话里没看到一份烂拷贝 窗口 storage 听者保持分页同步 . isDark 反映有效主题:默认 system 偏好 如下 prefers-color-scheme,包括实时操作系统变化,以及 toggleTheme() 与有效值脱节。 使用 setTheme("system") 返回到操作系统的偏好。 何时 localStorage 缺少 (SSR)或被屏蔽(sandboxed iframe,隐私模式),主题仍然适用 只有坚韧性被跳过. 该图层还注入了小的预绘 <head> 应用的脚本 data-theme 从 localStorage 财务报告和审定财务报表 prefers-color-scheme 开始之前 涂料,所以存储的黑暗偏好不再闪出光主题 装入。 具有严格CSP的应用程序必须允许此内置脚本(nonce 或 unsafe-inline没有它 prefers-color-scheme CSS 路径仍然 应用,主题在水合后解决. 设定 COMMON_WEB_THEME_SCRIPT_NONCE 构建时的环境变量 在被注入的标签上添加一个非ce( 读取时间为 nuxt.config.ts 实值 (评价) 共享层不支持每个请求的非ce: 构建 与导出项相连接的头条目 themeInitScriptEntry(nonce) 助手从 @devopsplaybook.io/common-web/composables/theme 并覆盖 app.head.script 在消耗性应用.
  • useAppHeight() 更新 --app-height 从 visualViewport 可用时 并清理卸载上的听众大小。 调整更新大小与 requestAnimationFrame,因此重复调整事件大小和多个组件 实例每个框架最多写出一次自定义属性。 待决框架 只在最后一次卸载时才取消, 所以卸载一个组件永远不会取消另一个组件的更新.
  • useOfflineStatus() 返回反应 isOnline 参考: 开始是 true 因此,服务器 HTML 和第一个客户端渲染协议,然后读取 navigator.onLine 在挂起并跟随 online编号 :offline 事件,所以 已装入下线的页面显示在水合后右侧的下线横幅 水分不匹配.
  • 例如,通过包深进口提供各种服务 @devopsplaybook.io/common-web/services/AuthService。 。 。 . AuthService, (中文(简体) ), PreferencesService 财务报告和审定财务报表 RefreshIntervalService 守护每个 localStorage 通过内部 BrowserStorage 帮助者,所以在SSR或与 被屏蔽的存储读取返回他们的已记录倒计时, 而写作是无操作的 .
  • createAuthenticationStore() 返回 Pinia 存储定义; Pinia 必须在消费应用程序中提供.

犬类认证存储密钥是 auth_token在此兼容期间 释放, AUTH_TOKEN 财务报告和审定财务报表 AUTH_TOKEN_KEY 读取并迁移到 警犬钥匙 托肯斯留在这 localStorage,匹配现有应用程序. 当一个经认证的标志 进入其寿命的最后20%, AuthService 通过更新 POST /api/users/session/refresh 输入 背景情况. getToken() 财务报告和审定财务报表 getAuthHeader() 返回仍然有效的当前 信号符立即发出,下一个呼叫会看到更新的信号符,所以缓慢地刷新 终点从来不会拖住打电话者.

getToken() 绝不因存储或更新的符号而拒绝:

  • 腐败或不可解密的令牌被视为已签名 : 每个认证密钥是 已删除, AUTH_UPDATED 已排放,并且 null 已返回。 过期代币为 删除并返回 null。礼物 exp 或者说 iat 索赔必须是有限的 数字;带有字符串或有其他错误的债权的符号是腐败的.
  • A 类 401 或者说 403 从刷新端点表示会话被取消: 届会被清除, AUTH_UPDATED 已排放,并且 null 已返回.
  • 超时和无效的续作回复执行单一请求. 网络 错误和 5xx 回复在500米后重试一次.
  • 当续签仍然失败时, 返回仍然有效的当前符号 进一步更新该标志的尝试暂停30秒。 更新 在背景中运行,所以最糟糕的情况是 大约6.5秒的背景 工作(2个3s的尝试加上500ms的后退),从不挡住呼叫器. 如果在尝试中该符号过期,会话将被清除并稍后结束 调用返回 null。 。 。 .
  • 3秒后续约请求超时, 同时通话共享一个单次 请求。 在飞行中保存的标志胜过更新 数值.
  • 重新发行的代币被验证(可解码、非空地、未来) exp,以及 exp > iat 何时 iat 在那之前.
  • AUTH_RENEWAL_FAILED 以 { reason }时 reason 这是其中之一 timeout, (中文(简体) ), 5xx, (中文(简体) ), network 或者说 invalid-response。它没有符号、 URL 或 PII;消费者可以使用自己的遥测仪. 此软件包添加无 OpenTeleometry 度量衡或依赖性.

removeToken() 清除每个存储的认证密钥. removeToken(token) 是一个 比较和移动操作: 它只在存储的符号时清除会话 仍然相等 token,因此,僵化的反应不能丢弃更新的会话.

认证状态和 HTTP 集成

AuthService.saveToken() 财务报告和审定财务报表 removeToken() 发射 EventTypes.AUTH_UPDATED 编辑 EventBus 当存储的符号实际 更改; 延长和到期通过这些方法。 皮尼亚店订货 到事件和刷新 isAuthenticated,所以更新,登录在另一个 选项卡或过期的符号不再离开 UI stale。 给添加剂打电话 refreshAuthentication() 操作手动刷新; ensureAuthenticated() 仍然装入初始状态。 商店还监听浏览器 storage ,使符号在标签中同步更改.

Bearer-token 附加是选入的: 分层船只有注册帮助器 而不注册插件,所以已有应用程序保持当前 行为。 默认时在耗用应用程序中添加客户端插件 Axios 实例应认证请求,并清除会议 401数字 :

// plugins/auth.client.ts
import { registerAxiosAuthInterceptors } from "@devopsplaybook.io/common-web/services/AxiosAuthInterceptor";

export default defineNuxtPlugin(() => {
  registerAxiosAuthInterceptors();
});

registerAxiosAuthInterceptors(instance = axios, { allowedOrigins = [], loginPaths = ["/users/session"] } = {}) 附加 Authorization: Bearer <token> 只有在请求不明确时 Authorization 页眉和 允许有效目标:

  • 相对 URL 、 页面来源、 绝对源 Config.SERVER_URL 和清单所列任何来源 allowedOrigins 即接受迹象;
  • 向任何其他来源提出的跨原产地请求没有收到任何征兆,不触发 符号更新, 当绝对 URL 无法解析时, 失败关闭 ;
  • allowedOrigins 条目已恢复正常化为来源和无效条目 掷出 TypeError· ;
  • 登记为每Axios实例的同位素并返回 false 何时 已经注册; 选项仅适用于第一次注册.

A 类 401 仅在失败的请求使用当前时清除存储的符号 存储的代号(所附代号记录在请求上或从 发送 Authorization 头曰. 烂透了 401 被忽略,a 401 从a 请求没有寄出任何指示牌,则无法澄清任何问题。 登录路径可配置通过 loginPaths: 有效路径名上的后缀匹配, 默认 ["/users/session"],在配置时替换,而忽略了空条目. loginPaths: [] 豁免任何路径.

服务器 URL 配置

Config.get() 返回时 { SERVER_URL: "/api" } 默认。 输入不同的 基础 URL, 例如来自 Nuxt 客户端插件, 并重置用于测试 :

import Config from "@devopsplaybook.io/common-web/services/Config";

Config.set({ SERVER_URL: "https://api.example.com" });
await Config.get(); // { SERVER_URL: "https://api.example.com" }
Config.reset(); // back to "/api"

Config.set() 修剪白相间并去除后遗症,所以 "https://api.example.com///" 财务报告和审定财务报表 "/api/" 变成 "https://api.example.com" 财务报告和审定财务报表 "/api"在开发中,它警告URL使用时 http: 而不是一个 循环主机( r)localhost, (中文(简体) ), 127.0.0.1, (中文(简体) ), [::1]) (中文(简体) ). 一个非同源 SERVER_URL 必须使用HTTPS,并允许通过CORS生成应用程序源; 跨原产地请求只有在来源是 配置 SERVER_URL 原产地或列于 allowedOrigins。 。 。 .

服务退后

UserService.isInitialized({ timeoutMs = 5000, signal, cacheTtlMs = 0 } = {}) 决定 false 网络或 HTTP 错误而不是拒绝, 因此设置代码 可以安全地打开门 每项请求都以下列条件为准: timeoutMs (默认为5 s) 并接受可选 AbortSignal与 cacheTtlMs > 0 一个成功的 true 在此期间对结果进行再利用(按URL键); false 永远 缓存和 cacheTtlMs: 0 禁用缓存。 失败将警告记录为 reason (单位:千美元)timeout, (中文(简体) ), aborted, (中文(简体) ), http-<status> 或者说 network)和没有 URL, 符号 或反应机构. RefreshIntervalService.get() 倒计时 "10000" 当存储值是 失踪或畸形; set() 正常化有效的非负整数字符串 (例如 "05000" 变成 "5000")并投掷 TypeError 否则. "0" 有效,并禁止投票。 两者 PreferencesService 财务报告和审定财务报表 RefreshIntervalService 容忍丢失或被封存: 读取返回 null 编号 : "10000" 写作被跳过,故他们在安全无虞 无效 set() 值仍然丢出 TypeError。 。 。 .

SSR和仅限客户使用

该图层具有SSR兼容性:组件在服务器上渲染 堆肥者守护他们的浏览器只访问.

  • useTheme() 保持模块级别状态,但触摸 document, (中文(简体) ), window 财务报告和审定财务报表 localStorage 仅在 onMounted (在安全部门改革期间从未运行)和通过 守护者 BrowserStorage 帮助; 服务器总是使默认值 system 优先选择.
  • useOfflineStatus() 备忘 isOnline 改为 true因此,服务器和 第一客户端达成一致意见; 真实值读取于 onMounted,所以一个 离线页面显示水合后而非服务器上的横幅 HTML (英语).
  • useAppHeight() 触摸 window 仅在内部 onMounted。 。 。 .
  • AuthService, (中文(简体) ), PreferencesService 财务报告和审定财务报表 RefreshIntervalService 守护每个 localStorage 访问:在安全部门改革期间,读取返回记录的倒计时 写作是没有的.

托肯存储, 会话更新, AUTH_UPDATED 跨塔布传播 同步和选入 Axios 集成是只浏览器: 注册 Axios 来自 a 的助手 .client.ts 如上所示的插件,并期望 认证状态只有在水合后才有意义 .

tests/ssr.spec.ts 使运出组件与 createSSRApp 财务报告和审定财务报表 renderToString 在一个节点环境中,所以这个服务器发送合同是 执行人 npm test 和通过CI工作流程.

脚本和app-shell 样式

层负载 assets/css/tokens.css 财务报告和审定财务报表 assets/css/app-shell.css。 。 。 . 键包括 --color-* (包括每个状态前景符号) --color-on-success, (中文(简体) ), --color-on-error 财务报告和审定财务报表 --color-on-warning 用过的 --color-success, (中文(简体) ), --color-error 财务报告和审定财务报表 --color-warning, (中文(简体) ), --space-*, (中文(简体) ), --text-*, (中文(简体) ), --radius-*, (中文(简体) ), --shadow-*, (中文(简体) ), --header-height,以及 --app-height。可以选择暗模式 data-theme="dark" 或来 从 prefers-color-scheme 当没有设定明确的光线偏好时。 状态 颜色与WCAG AA相对 --color-on-* 两者的前景标志 主题. --color-primary 财务报告和审定财务报表 --color-primary-hover 两者的定义 主题和在运出时遇到 AA(4.5:1) --color-surface 财务报告和审定财务报表 --color-surface-raised 学来. tests/contrast.spec.ts 门文本, 变音的文字,主,主盘旋 和状态颜色对在光和 两个黑暗的街区。 这个 dpb-fade-in 财务报告和审定财务报表 dpb-blink 帮助类已禁用 下级 prefers-reduced-motion: reduce。 。 。 .

在图层后装入特定应用的 CSS , 只重新定义您需要的值 :

:root {
  --color-primary: #145da0;
  --header-height: 4.5rem;
}

苹果壳钩

用于页面框架和 浮动提醒容器 :

<div class="page-layout">
  <AppNavigation :links="links" />
  <main>
    <NuxtPage />
    <AlertMessages class="page-alert-messages" />
  </main>
</div>

#page-layout 财务报告和审定财务报表 #page-alert-messages 继续作为遗产别名提供支持 对于现有的消费者来说,所以当前加价继续起作用. 优先上课 新的标记,以避免在多个布局上架时发生重复的ID相撞.

覆盖一个组件

Nuxt给予应用本地组件相对于层组件的优先级. 添加组件 在你的应用软件下同名 components/ 例如,目录 components/Loading.vue,它取代了层的 <Loading /> 无 伪造或修改此软件包。 App 特定导航项目通过 通过 links 道具而不是嵌入层.

深层的进口也可用于工具和测试,但不在 Nuxt 应用程序 :

import Loading from "@devopsplaybook.io/common-web/components/Loading.vue";

兼容性和释放政策

此发行支持 Nuxt ^4.0.0 ưμ㼯A ^3.5.0; Nuxt 提供 Vue,所以 Nuxt 4 应用程序已经满足了此对等点 。 皮尼亚 ^2.0.0 || ^3.0.0 || ^4.0.0 是可选对等点:只有 stores/AuthenticationStore 需要,所以不使用 存储无需安装。 Pinia 4 仅限无害环境管理,需要消耗 应用程序 @vue/devtools-api 相对依赖。 数值 3 应用程序(包括心电图)不支持.

对于 Nuxt 大型升级, 更新对等依赖, 建造操场 测试所有从包装中输出的组件/组件 柏油丸,并验证刮伤消费者在放出前可以延长地层. 保留释放语义:用于修正的补丁,用于向后兼容的次要 特性,以及用于打破 API 或框架更改的主要特性。 合并工作流程 当软件包版本尚未发布时, 发布新的 npm 公共版本 已发布; 凸起 package.json 手动在发布PR上.

PR Check 财务报告和审定财务报表 Main Build 运行共享 npm 的寄存器本地版本 工作流程,使审计门只能覆盖生产依赖; 报告关于发展工具链的咨询,但不会失败。 见 捐款额 为政策和 被接受的只有发展的建议。 本地工作只是权宜之计,直到 共享 common-utils npm工作流程采用同门.

包装、类型和副作用

包件载运生 Vue 和 TypeScript 源头没有构建步骤,所以有 故意拒绝 types 或者说 exports.types 条目: 类型信息来自 页:1 .ts编号 :.vue 和深度进口的决心 exports nuxt 模块分辨率下的映射. sideEffects 白名单 CSS 和 .vue 文件这样组件样式和符号样式表都永远不会 树被震动,而无副作用 .ts 模块可以是. npm run build 当包装的柏油丸中缺少任何公共文件时失败, 而包装 归档是什么 npm test 运行对面.

发展

npm ci
npm run lint
npm run typecheck
npm test
npm run build
npm run dev

npm run typecheck 运行 nuxi typecheck (单位:千美元)vue-tsc --noEmit在地层上, 在游戏场和测试中失败. npm test 收拾东西 库并运行组件、服务和SSR测试. npm run build 验证其内容并建造游乐场. 见 捐款额 详细情况.

版本与发布记录

@devopsplaybook.io/common-web 共发布 29 个版本,首次发布于 2026/09/27;过去 12 个月发布了 29 个版本。

版本发布日期距今
0.12.1latest2026/11/066 天前
0.12.1-beta.21.f8635c4beta2026/11/066 天前
0.12.02026/11/0210 天前
0.12.0-beta.20.8d8d60f2026/11/0210 天前
0.11.02026/11/0210 天前
0.11.0-beta.19.837c0632026/11/0210 天前

关于 @devopsplaybook.io/common-web 的常见问题

@devopsplaybook.io/common-web 是什么?

DevOpsPlaybook 网络应用程序共享 Nuxt 层

如何安装 @devopsplaybook.io/common-web?

在项目目录运行 npm install @devopsplaybook.io/common-web,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:vue(^3.5.0)、nuxt(^4.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@devopsplaybook.io/common-web 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/devopsplaybook.io__common-web 是否存在。

@devopsplaybook.io/common-web 支持 ESM 还是 CommonJS?

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

@devopsplaybook.io/common-web 需要什么版本的 Node.js?

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

@devopsplaybook.io/common-web 可以商用吗?

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

@devopsplaybook.io/common-web 的下载量有多少?

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

@devopsplaybook.io/common-web 还在维护吗?

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