搜索 K
主题
@vaultkit/vitepress-plugin-npm-card 提供 ::: npm-card 容器:写包介绍、教程文章时一行嵌入 npm 包信息卡——版本、描述、周下载、解包体积、运行时依赖数、license、TS 类型徽标、keywords 一卡集齐。构建期从 npm registry 抓取元数据渲染为静态卡片,零客户端 JS,全程免认证。
语法与实现同 repo-card 完全同轨:单段 Vite 插件(enforce: 'pre')在 md 编译前改写原文,主参数走 info-string 位、单行即闭合。本文覆盖主参数两种形态、全部 4 个属性、三档尺寸逐档实活演示、全部 4 个插件 options,并讲透它规避几十 MB 完整包文档的取数策略。
介绍一个 npm 包时,读者最关心的几个数字——最新版本、周下载量、体积、依赖数——散落在 npmjs.com 各处。手工抄进文章,发布当天就开始过时;贴 shields.io 徽章,则是页面运行时的一堆第三方请求。
npm-card 在构建期取数、构建期渲染:数据随每次部署自动刷新,页面加载零额外请求;新发布的包周下载端点还没数据时优雅降级(只是不渲染该字段),不炸构建。
pnpm add -D @vaultkit/vitepress-plugin-npm-card// .vitepress/config.ts —— 注册在 vite.plugins(非 markdown.config)
import { npmCard } from '@vaultkit/vitepress-plugin-npm-card'
import { defineConfig } from 'vitepress'
export default defineConfig({
vite: { plugins: [npmCard()] },
})// .vitepress/theme/index.ts
import '@vaultkit/vitepress-plugin-npm-card/styles/index.css'使用 @vaultkit/vitepress-theme-vault 主题则开箱即带,容器直接可用。
主参数走 info-string 位,单行即闭合、::: 收尾可省:
::: npm-card vue
::: npm-card @vue/reactivity {size="sm"}
::: npm-card https://www.npmjs.com/package/vitepress {size="lg"}实活效果(本页构建期真实抓取渲染):
直接写包名,scoped 包原样支持(@scope/name);构建期先过 npm 合法包名正则,非法包名直接抛错:
::: npm-card vue
::: npm-card @vue/reactivity写包主页地址,可带 /v/x.y.z 版本尾巴(自动忽略,恒取 latest):
::: npm-card https://www.npmjs.com/package/vitepress全部 4 个属性:
| 属性 | 类型 | 缺省 | 说明 |
|---|---|---|---|
pkg | string | — | 包名(等价于 info-string 主参数的简写形态) |
url | string | — | npmjs.com/package/<name> 地址(等价于主参数 URL 形态) |
size | string | md | sm / md / lg |
class | string | — | 卡片额外类名 |
pkg / url 属性形态与主参数等价(主参数优先级更高):
::: npm-card {pkg="vue" size="sm"}
::: npm-card {url="https://www.npmjs.com/package/vue" class="hero-card"}未知属性、非法包名、size 超出三档,全部构建期抛错(fail-fast),不渲染残卡。
npm 徽标 + 包名 + 版本 + 周下载,一行高,正文顺带提及:
::: npm-card vue {size="sm"}在 sm 基础上加描述、TS 徽标与统计行(周下载、解包体积、运行时依赖数、license),列包清单用:
::: npm-card vue {size="md"}再加大标题、npm i 安装命令行、keywords 徽标行(至多 5 个)与悬停光泽扫过,教程开头、作品页展示用:
::: npm-card @vue/reactivity {size="lg"}npm i @vue/reactivityvue11.9M/w335 kB1 depsMITnpmCard(options?) 的 NpmCardOptions 共 4 项:
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
registryBase | string | 'https://registry.npmjs.org' | 元数据 registry 基址 |
downloads | boolean | true | 周下载量抓取开关 |
ttl | number | 3_600_000 | 缓存有效期(ms,缺省 1 小时) |
cacheDir | string | node_modules/.cache/vitepress-plugin-npm-card | 缓存目录 |
元数据抓取的 registry 基址,国内 CI 可切 npmmirror 等镜像加速构建:
npmCard({ registryBase: 'https://registry.npmmirror.com' })周下载量抓取开关。注意数据恒来自官方 api.npmjs.org,与 registryBase 无关(镜像不提供 downloads API);内网构建可整体关掉:
npmCard({ downloads: false }) // 卡片不再渲染周下载字段与 repo-card 同款缓存语义:TTL 内直接命中磁盘缓存,过期重抓、失败回退陈缓存。CI 建议持久化缓存目录:
npmCard({ ttl: 24 * 3_600_000, cacheDir: '.cache/npm-card' })npm registry 的 /{pkg} 端点返回全版本历史文档——大包极其恐怖:vite 的完整文档约 37 MB。给每张卡片拉几十 MB 再丢掉 99.9%,是构建性能的灾难。
npm-card 刻意只打两个小端点:
registry.npmjs.org/{pkg}/latest——单版本文档,几 KB,含版本、描述、license、dependencies、types、keywords、dist.unpackedSize 全部所需字段api.npmjs.org/downloads/point/last-week/{pkg}——周下载量,一个数字两个端点都免认证,也就没有任何 token 配置项——这是它与 repo-card options 表的最大差异。
新发布的包 downloads 端点可能 404,也可能返回 error 体。npm-card 把两种情况统一降级为 null:卡片不渲染下载字段,构建照常通过,只留一行 warn。元数据错误炸构建(包名写错理应发现),统计数据缺失不炸构建(新包无数据不是作者的错)——两类失败区别对待。
Vite 原文改写(enforce: 'pre' + 行首正则 + type-6 HTML block 透传)、ATTR_PATTERN 属性解析、fetchCached 磁盘缓存全部来自 @vaultkit/repo-platform-kit。npm-card 是这个底座「平台无关部分」的最佳示范:它不需要 GitHub/CNB 的平台知识,只消费缓存与属性解析。
改写前会先按 CommonMark 围栏规则切段、只处理围栏外的文本——代码块里顶格演示 ::: npm-card 语法是安全的,这一行为与 repo-card / remote-file 通用。
体积字段有时不显示? registry 老版本发布物可能缺 dist.unpackedSize,缺则整个字段不渲染。
TS 徽标的判定标准? latest 版本 manifest 存在 types 或 typings 字段即亮 TS 徽标;靠 @types/* 补类型的包不亮。
能显示指定版本吗? 不能,恒取 latest——包卡的语义是「这个包现在什么样」,锁版本展示请直接写代码块。