源码分发 (vize lib)
vize lib 以 shadcn/ui 的方式,把 @vizejs/ui 的组件和 @vizejs/composable 的组合式函数 作为源码 复制到你的项目中。
复制后的文件归你所有:可以随意修改,Vize 会记录每个文件来自哪个包版本,让升级保持安全。
vpx vize lib pull rating
这会把 rating 系列以及它导入的所有内容 (controllable-state、id 等) 写入 src/components/vize/,
并在 vize-lib.lock.json 中记录这次拉取。
源码从哪里来
每个已发布的 @vizejs/ui 和 @vizejs/composable tarball 都包含一个带版本的注册表:
node_modules/@vizejs/ui/
registry/
registry.json # 条目、文件、sha256 摘要、依赖
files/families/... # 原始 .vue / .ts / .css 源码(不含测试)
vize lib 按以下顺序解析注册表:
--registry <path>:registry.json、其所在目录或已解包的包目录。重复该参数即可同时传入 ui 和 composable 注册表,此时自动发现会被关闭。- 项目中已安装的包 (
node_modules/@vizejs/ui/registry/registry.json,与 Node 解析一样向上查找父目录)。 - 当请求固定了与已安装版本不同的版本,或包尚未安装 (此时为
@latest) 时,执行npm pack @vizejs/<pkg>@<version>到临时目录并用tar -xzf解包。使用--offline可禁止这一步。
不涉及任何注册表服务器或额外的 HTTP 客户端:注册表就是 npm 已经提供的 tarball,因此每个版本都不可变且可复现。
命令
| 命令 | 作用 |
|---|---|
vize lib init [--dry-run] |
检测项目结构并写入 lib 配置部分。 |
vize lib list [--kind ui|composable] |
列出可拉取的条目。 |
vize lib search <words> |
按名称、标题、描述和别名搜索。 |
vize lib info <name> |
显示文件、注册表依赖、npm peer 和包版本。 |
vize lib pull <item>... [--dir <dir>] |
复制条目及其注册表依赖;--dry-run、--overwrite、--with-examples。 |
vize lib add <item>... |
与 shadcn 兼容的 pull 别名 (-p/--path、-o/--overwrite、-y/--yes)。 |
vize lib status |
将已拉取的文件与锁文件和已安装的注册表进行比较。 |
vize lib diff <name> [--to <version>] |
显示从本地副本到注册表版本的 unified diff。 |
vize lib update [<name>...] [--to <v>] |
应用上游变更而不覆盖本地修改;--dry-run、--force。 |
vize lib remove <name>... |
删除条目以及不再被需要的依赖;--dry-run、--force。 |
vize lib outdated |
将锁定的版本与已安装和最新的注册表进行比较。 |
所有命令都支持 --json 输出机器可读结果,以及 --root <dir> 以针对其他项目运行。
指定条目
条目可以通过规范名称 (rating)、别名 (star rating、useToggle)、在两个包中同名时加种类前缀
(ui:locale、composable:locale),以及精确的包版本 ([email protected]、composable:[email protected]) 来指定。
目标目录
拉取的文件在每个种类各自的一个目录下保持注册表布局 (families/form/rating/rating.vue、
foundations/id/deterministic-id.ts 等),因此条目之间的相对导入无需改写即可工作。目录按以下顺序确定:
--dir <dir>(必须位于项目内)vize.config.*中的lib部分- 注册表默认值:
src/components/vize(ui) 和src/composables/vize(composable)
// vize.config.ts
import { defineConfig } from "vize";
export default defineConfig({
lib: {
uiDir: "src/ui/vendor",
composableDir: "src/composables/vendor",
// dir: "src/vendor", // 两种类型共用的回退目录
// lockfile: "vize-lib.lock.json",
},
});
某个种类一旦拉取到某个目录,之后该种类的拉取都会复用它;会拆分依赖图的冲突 --dir 会被拒绝。
拉取的源码只导入相对路径和 vue 等 npm 包。pull 会报告 package.json 尚未声明的 npm 依赖,但不会替你安装。
快速开始:init
vize lib init --dry-run # 显示检测到的结构和配置变更
vize lib init # 写入
init 会检测源码目录 (src/,Nuxt 4 项目为 app/) 和 TypeScript,然后写入 lib.uiDir / lib.composableDir。
没有配置时创建 vize.config.json;已有 vize.config.json 时只追加 lib 部分而不改动其余内容;对于
vize.config.ts / .pkl 则打印代码片段而不编辑代码。已有的 lib 部分会被保留,除非使用 --force。
若 tsconfig.json 缺少 allowImportingTsExtensions,init 会给出提示:拉取的源码以 ./x.ts 形式导入同级文件。
检查更新:outdated
vize lib outdated 列出注册表与锁文件不一致的已拉取条目:
| 列 | 含义 |
|---|---|
current |
vize-lib.lock.json 中记录的版本。 |
wanted |
update 将使用的注册表版本 (已安装的包,否则为最新)。 |
latest |
npm 上发布的最新版本 (npm view;--offline 时跳过)。 |
state |
update-available、newer-release、removed-upstream、unknown (或 up-to-date)。 |
update-available 表示条目的 contentHash 不同;不影响条目文件的版本升级仍为 up-to-date。--json 包含所有条目。
第三方注册表
任何包或站点都可以发布相同格式的注册表,并通过命名空间使用:
{
"lib": {
"registries": {
"@acme": "npm:@acme/vue-kit",
"@design": { "source": "https://design.example.com/r/registry.json", "dir": "src/design" },
"@local": { "source": "./registry", "dir": "src/local" }
}
}
}
vize lib pull @acme/data-table @design/[email protected]
vize lib list --kind @acme
npm:<package>[@range]使用已安装包的registry/registry.json,否则执行npm pack。https://…/registry.json通过curl获取,每个文件按需从同级的files/<path>下载 (仅 https)。- 其他值是相对于配置文件的路径:
registry.json、其所在目录或包目录。
第三方注册表使用与官方注册表相同的 JSON Schema 校验 (未知字段、格式错误的摘要、未知的角色或依赖、不完整的依赖闭包都会被拒绝),
下载的每个字节在写入前都会用 SHA-256 校验。命名空间的条目放在其 dir (否则为注册表的 defaultTargetDirectory),
以 @namespace 为键锁定,并且永远不会覆盖其他已拉取条目拥有的文件。
使用示例与 Musea 画廊
大多数 UI 系列在源码旁附带无样式的使用示例 (families/<area>/<family>/examples/<family>-*.vue)。
它们随注册表发布,但只有在请求时才会拉取:
vize lib pull switch --with-examples
示例会放在拉取的源码旁 (…/switch/examples/switch-basic.vue),通过相对路径导入该系列,并像其他文件一样记录在
vize-lib.lock.json 中,因此 status、diff 和 update 都会覆盖它们;一旦请求过,update 会继续拉取。
同样的示例会生成一个 Musea 画廊:每个系列一个故事,每个示例一个变体。在仓库中于
examples/vite-musea 运行 pnpm gallery:ui,即可重新生成故事 (npm/ui/scripts/generate-gallery.ts) 并启动画廊。
版本管理与安全更新
vize-lib.lock.json (请提交它) 为每个条目记录来源包及其精确版本、注册表 contentHash、是直接请求还是作为依赖引入,
以及拉取时每个文件的 SHA-256。这些摘要是 你的文件、拉取时的文件 与 新的注册表文件 三方比较的合并基准。
| 你的文件 vs 拉取时 | 注册表 vs 拉取时 | update / pull 的行为 |
|---|---|---|
| 未改动 | 未改动 | 不做任何事 (unchanged) |
| 未改动 | 已改动 | 替换 (update) |
| 已修改 | 未改动 | 保留你的修改 (keep-local) |
| 已修改 | 已改动 | 除非 --force / --overwrite,否则拒绝 (conflict) |
| 未改动 | 上游已删除 | 删除 (delete) |
| 已修改 | 上游已删除 | 除非 --force,否则拒绝 (conflict-delete) |
| 缺失 | 任意 | 恢复 (create) |
| 存在但未锁定 | 任意 | 除非 --overwrite,否则拒绝 (conflict) |
只要还有未解决的冲突就不会写入任何内容,因此被拒绝的更新不会改动文件和锁文件。用
vize lib diff <name> --to <version> 查看上游变更,手动合并后再运行 update --force。
典型的升级流程:
pnpm add @vizejs/ui@latest # 或:vize lib update --to 0.428.0
vize lib status # 哪些条目有更新或本地修改
vize lib update --dry-run # 预览文件操作
vize lib update # 应用;如有冲突会列出
remove 会删除条目以及仅为它拉取的所有依赖。只要其他已拉取的条目仍导入目标就会拒绝,并且除非使用 --force,
否则会保留本地修改过的文件。
注册表格式
注册表文档由
vize-lib-registry.schema.json
描述,锁文件由
vize-lib-lock.schema.json
描述。两者都随 vize npm 包发布在 schemas/ 下。
registryDependencies是构建时根据相对导入图计算出的完整传递闭包;共享的基础模块是独立条目, 因此拉取两个都需要id的组件时只会复制一次id。- 每个文件都带有
sha256;vize lib会用它校验复制的每个字节。 contentHash只在条目的文件变化时改变,因此status只会对不同版本间源码确实不同的条目报告 "update available"。