跳转到内容

包与依赖关系 ​

XiHan.UI 是一个 pnpm workspace。packages/*/* 是对外发布的库包(按角色分 adapters / design / features / engine 四组),tooling/* 是内部工具(不发布)。

全部库包 ​

包依赖peer 依赖层
@xihan-ui/coremotion—1
@xihan-ui/tokens——1
@xihan-ui/icons——1
@xihan-ui/motion——1
@xihan-ui/pointer——1
@xihan-ui/viz——1
@xihan-ui/positioncore—2
@xihan-ui/code-highlightcore—2
@xihan-ui/chat-streamcore—2
@xihan-ui/markdown——2
@xihan-ui/soundcore—2
@xihan-ui/animationscore motion—2
@xihan-ui/headlesscore motion pointer viz—3
@xihan-ui/stylestokens(只取其 CSS 产物)—3
@xihan-ui/backgroundscore motion—3
@xihan-ui/vuecore motion pointer viz headless positionvue、backgrounds(可选)、sound(可选)、code-highlight(可选)4
@xihan-ui/web-componentscore motion pointer viz headless positionbackgrounds(可选)、code-highlight(可选)4

发布走 changesets,所有库包同属一个 fixed 版本组,一起升到同一个版本号。

依赖图 ​

箭头方向 = 依赖方向,只画实际声明的依赖。同层之间只有 core → motion 一条横向依赖。

层 4   ┌─────────────┐       ┌──────────────────┐
       │     vue     │       │  web-components  │  peer: backgrounds · code-highlight(可选);vue 另有 peer: sound(可选)、vue
       └──────┬──────┘       └────────┬─────────┘
              │  core · motion · pointer · viz · headless · position
              └───────────┬───────────┘
                          ▼
层 3   ┌──────────────┐  ┌───────────────────┐   ┌────────────────┐
       │   headless   │  │    backgrounds    │   │ styles(纯CSS)│
       └──────┬───────┘  └─────────┬─────────┘   └───────┬────────┘
   core·motion·pointer·viz         core·motion            tokens 的 CSS 产物
              │                    │
              ▼                    ▼
层 2   ┌──────────┐ ┌────────────────┐ ┌─────────────┐ ┌───────┐ ┌────────────┐ ┌──────────┐
       │ position │ │ code-highlight │ │ chat-stream │ │ sound │ │ animations │ │ markdown │
       └────┬─────┘ └───────┬────────┘ └──────┬──────┘ └───┬───┘ └─────┬──────┘ └──────────┘
            └───────────────┴─────────────────┴───────────┴───────────┘            无依赖
                          ▼
层 1   ┌──────────┐  ┌──────────┐   ┌──────────┐  ┌───────┐  ┌─────────┐  ┌─────┐
       │   core   │─►│  motion  │   │  tokens  │  │ icons │  │ pointer │  │ viz │
       └──────────┘  └──────────┘   └──────────┘  └───────┘  └─────────┘  └─────┘
                     零运行时依赖      无依赖        无依赖      无依赖     无依赖

三个包完全独立,可以单独使用:

  • @xihan-ui/tokens:只需要设计令牌与主题运行时,不需要组件;
  • @xihan-ui/markdown:只需要流式 Markdown 渲染内核;
  • @xihan-ui/styles:纯 CSS,它对 tokens 的依赖只是为了 @import 令牌产物,不引入任何 JS。

依赖规则 ​

分层拓扑写在 tooling/eslint-config/src/layers.json 中,由 dependency-cruiser 在 pnpm boundaries 时强制。层级越低越基础,只能依赖 canDependOn 列出的包。

除分层外还有四条规则:

规则内容
no-circular禁止循环依赖
no-unresolvable无法解析的 import:最常见的成因是引用了邻层却未在 package.json 中声明依赖
styles-no-js-depsstyles 是纯 CSS,不得依赖任何 JS 包
no-external-in-packages库包的运行时代码不得引入第三方

第三方运行时依赖 ​

没有。登记在案的例外只有适配器的宿主框架:@xihan-ui/vue 的 vue,@xihan-ui/react 的 react 与 react-dom。

以下能力均为自研,不引入第三方:

能力包常见的第三方选择
日期运算、时区换算与按地区的周core(@xihan-ui/core/date)date-fns / Day.js / @internationalized/date
浮层定位positionFloating UI
代码着色code-highlightShiki / Prism
Web Components 响应式基类web-componentsLit
Markdown 渲染markdownmarkdown-it / marked
状态机coreXState

新增第三方运行时依赖必须逐条登记进白名单并写明理由与移除条件,由 check-runtime-deps 门禁保证。

开发期第三方依赖另行处理

@lit/reactive-element 与 commonmark-spec 出现在 workspace catalog 中,但只供测试比对:前者用于差分校验自研响应式基类,后者用于读取 CommonMark 官方用例。两者都不进入任何包的运行时依赖。

版本约定 ​

  • 内部运行时依赖一律 workspace:^(发布时展开为当前锁步版本的 ^ 区间),内部开发期依赖用 workspace:*;
  • 第三方版本只从 workspace catalog 取,包内写 catalog:,不得内联版本号(check-exact-pins 门禁);
  • 升级只改 pnpm-workspace.yaml 的 catalog 一处。

产物契约 ​

项值
模块格式ESM only,不提供 CJS
Node>= 18
类型每个入口一份 .d.ts
副作用全部 sideEffects: false,styles 与 tokens/tokens.css 除外

pnpm gate:publish 逐包运行 publint 与 attw,按 ESM-only 的支持面校验 exports 条件与类型解析(node16-from-ESM 与 bundler 两列)。

子路径导出 ​

主入口之外另有子路径的包:

包子路径
@xihan-ui/core./metadata ./skin-check ./vite ./vanilla ./presence
@xihan-ui/tokens./runtime ./tokens.css ./tokens.json
@xihan-ui/icons./codegen
@xihan-ui/vue./backgrounds ./behavior ./sound
@xihan-ui/web-components./define ./backgrounds ./custom-elements.json
@xihan-ui/styles每份皮肤一条 CSS,共 148 条(136 份组件皮肤 + 12 份共享层),另有 ./index.css(主入口,生成的扁平有层文件,家族只内联一次)与 ./index.unlayered.css 两个整包入口

其余十一个包(headless / motion / pointer / viz / position / code-highlight / animations / backgrounds / chat-stream / markdown / sound)只有主入口。

组件没有单独的子路径导出:按需引入依靠 tree-shaking,不依靠手写路径。

相关 ​

Released under The MIT License