@devframes/plugin-a11y

中文文档
1.3.3发布于 2026/11/10MITTypeScriptES Module构建来源已验证近 30 天下载 9343

Built-in devframe that audits the user app with axe and highlights accessibility issues in the page.

原始使用文档
文档目录4 节
  1. How it works
  2. Configuration
  3. Run the demo
  4. File map

@devframes/plugin-a11y

[!WARNING] Experimental This devframe is experimental and may change without a major version bump until it stabilizes.

An accessibility inspector built on devframe. It runs axe-core against a user app and surfaces the violations in a Solid panel:

  • Route-aware tracking: buckets violations by location.pathname and tracks them as you navigate the user app (History-API patched, framework-neutral), persisted in sessionStorage so history survives reloads within a tab session.
  • Dashboard + grouped violations: a Dashboard tab (totals, severity breakdown, per-route inventory, scan controls) and a Violations tab listing every tracked route, grouped, with the active route marked.
  • Select + highlight: hover previews the offending element; ticking a violation's checkbox selects it, giving the card a distinct state and drawing globally-numbered badges over all its elements in the page. <html>/<body> targets get a corner notice instead of a viewport-filling ring.
  • Generate fix prompts: a nav button gathers the selected violations (rule metadata, WCAG tags, docs, and each element's selector/markup/failure summary, grouped by route) into one paste-ready AI prompt in a dialog.
  • Constant scanning: a DOM MutationObserver plus debounced mouse/keyboard/touch rescans, toggleable from the Dashboard.
  • WCAG 2.0–2.2 + best-practice: the broadened axe tag set, with best-practice rules tagged and filterable.
  • Console logging: newly-appeared violations are logged (deduped) to the browser console.

The scan + highlight loop works the same whether the devframe runs as a live dev server or as a baked static build.

How it works

Three pieces, two of them browser-side:

PieceRuns inRole
Page script (src/inject)the user app's pageruns axe-core, tracks routes, owns the aggregate state, draws the preview + pinned rings
Panel (src/spa)the devtools iframeSolid SPA: Dashboard + grouped violations, fires preview/pin/rescan
Node (src/index.ts, src/node, src/rpc)the node sideget-config RPC (impact taxonomy + runtime config): live in dev, baked in a static build

The page script and panel talk over devframe's in-page channel (devframe/in-page-channel, contract in src/shared/protocol.ts), not the devframe RPC backend. That is what keeps the live loop working in both modes: neither half needs a server to reach the other, only a same-origin handshake in the same tab. The page script owns the authoritative route → report map as the channel's shared state, which is replayed to late-joining panels and streamed as patches on every change, so the panel stays a pure render of it. devframe RPC carries the data model on top; get-config is a static function, so it resolves over WebSocket in dev and from the baked dump in a static build; the panel forwards its runtime-config slice to the page script over the channel, keeping the page script itself free of any RPC dependency.

devframe deliberately provides no access to the user app's DOM, so the page script is the author-provided bridge into the user app's page. In a hub, the page script is the a11y dock's client script, and the definition declares it by path, so the hub serves it same-origin and devframes: ['@devframes/plugin-a11y'] works with no host wiring. The hub's client runtime (createDevframeClientRuntime from @devframes/hub/client) then imports it into the host page and calls its default export with the client-script context. A host can also serve the module itself (e.g. via /@fs/… under Vite) by attaching a11yClientScriptBundlePath as a per-mount clientScript. Booted that way, the page script also mirrors the active route's scan into the hub's messages feed: a summary entry driven through the loading → idle lifecycle plus one entry per violated rule, carrying the impact-mapped level, WCAG tags as labels, and the first offending element's selector and bounding box (rendered by @devframes/plugin-messages when the hub mounts it). Each entry also carries a navigation action: clicking it in the messages panel activates the a11y dock (hub:docks:activate) deep-linked to the rule + route (or the Dashboard, for the summary). Both minimal hub examples do exactly this. Outside a hub, one <script type="module"> for the same bundle does the job; the demo below shows it (no hub context, so the feed mirror simply stays off).

Configuration

Pass options to createA11yDevframe() (surfaced through get-config, so they reach both the panel and the page script):

createA11yDevframe({
  autoScan: true, //         rescan on debounced interaction (default true)
  logIssues: true, //        log new violations to the console (default true)
  defaultHighlight: false, // auto-pin a route's violations on first scan (default false)
  axe: {
    tags: [
      'wcag2a',
      'wcag2aa',
      'wcag21aa',
      'wcag22aa',
      'best-practice'
    ],
    runOptions: {}, //       extra axe `run` options merged over the defaults
  },
})

Run the demo

The demo serves an intentionally-broken host page and the panel from one origin so they share the channel.

pnpm -C plugins/a11y build       # build the panel + the page-script bundle
pnpm -C plugins/a11y demo        # dev: live WebSocket RPC → http://localhost:4477/

pnpm -C plugins/a11y cli:build   # bake the static deploy (dist/static)
pnpm -C plugins/a11y demo:build  # static: baked RPC dump, no server

Open the URL, then hover any row in the panel, and the matching element in the page gets a focus ring (and scrolls into view if it's off-screen). Both demo modes behave identically; the panel's websocket / static tag is the only tell.

Standalone, without a user app:

pnpx @devframes/plugin-a11y      # the published package, panel only, at /__devframes_plugin_a11y/
pnpm -C plugins/a11y dev         # from source: same, at /__devframes_plugin_a11y/

File map

PathExportPurpose
src/index.ts.createA11yDevframe() (also the default export), declaring the page script as its dock's client script; a11yClientScriptBundlePath is that module, for hosts that serve it themselves
src/node/index.ts/nodesetupA11y(ctx, options?) registers the RPC functions with the runtime config
src/cli.ts/clicreateA11yCli() backs the devframes_plugin_a11y bin
src/client/index.ts/clientconnectA11y(), a typed browser RPC client wrapper
src/rpc/internalget-config static RPC + the type-safe client registry
src/shared/protocol.tsinternalthe page script ↔ panel in-page channel contract (A11yChannelProtocol)
src/inject/internalthe page script (axe scan, highlight overlay, hub messages mirror) → dist/inject/inject.js
src/spa/internalthe Solid panel SPA → assets-pkg/dist (ships in @devframes/plugin-a11y--assets)
demo/internalsame-origin host page + server (dev + static modes)
tests/internaldev-server RPC + static-build dump

版本与发布记录

@devframes/plugin-a11y 共发布 68 个版本,首次发布于 2026/07/06;过去 12 个月发布了 68 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.3.3latest2026/11/101 天前
1.3.22026/11/029 天前
1.3.12026/11/0110 天前
1.3.02026/10/3112 天前
1.2.62026/10/1924 天前
1.2.52026/10/1428 天前

关于 @devframes/plugin-a11y 的常见问题

@devframes/plugin-a11y 是什么?

Built-in devframe that audits the user app with axe and highlights accessibility issues in the page.

如何安装 @devframes/plugin-a11y?

在项目目录运行 npm install @devframes/plugin-a11y,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:devframe(1.3.3)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 devframes_plugin_a11y,可以用 npx devframes_plugin_a11y 直接运行。

@devframes/plugin-a11y 支持 TypeScript 吗?

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

@devframes/plugin-a11y 支持 ESM 还是 CommonJS?

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

@devframes/plugin-a11y 可以商用吗?

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

@devframes/plugin-a11y 的下载量有多少?

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

@devframes/plugin-a11y 还在维护吗?

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