---
title: version-catalog
description: Håndhev sentralisert versjonsadministrasjon i monorepoer ved å kreve catalog- eller workspace-notasjon for alle avhengigheter.
---
Håndhev sentralisert versjonsadministrasjon i monorepoer ved å kreve `catalog:`- eller `workspace:`-notasjon for alle avhengigheter.
## Regeldetaljer
I monorepoer med mange pakker fører duplisering av versjonsstrenger på tvers av `package.json`-filer til versjonsforskyvning og oppgraderingssmerter. Denne regelen sikrer at hver avhengighetsreferanse bruker `catalog:` (hentet fra en sentral katalog i rot-`package.json`) eller `workspace:` (for interne pakker), aldri en rå semver-streng.
Regelen har to sjekker: `catalog-usage` verifiserer at alle avhengigheter bruker riktig notasjon, og `catalog-completeness` verifiserer at hver `catalog:`-referanse peker til en faktisk oppføring i rotkatalogen.
## Eksempler på **feil** kode
```json title="packages/api/package.json"
{ "dependencies": { "zod": "^3.23.0", "hono": "^4.0.0" } }
```
Rå semver-strenger omgår den sentrale katalogen og vil divergere på tvers av pakker.
## Eksempler på **riktig** kode
```json title="packages/api/package.json"
{
"dependencies": {
"zod": "catalog:",
"hono": "catalog:",
"@myorg/shared": "workspace:*"
}
}
```
```json title="package.json (root)"
{ "catalog": { "zod": "^3.23.0", "hono": "^4.0.0" } }
```
Alle versjoner administreres sentralt. Oppgradering av `zod` krever bare endring av rotkatalogen.
## Regelimplementasjon
```typescript
///
export default {
rules: {
"catalog-usage": {
description:
'All workspace dependencies must use "catalog:" or "workspace:" notation',
async check(ctx) {
const packageJsonFiles = [
...(await ctx.glob("packages/*/package.json")),
...(await ctx.glob("packages/*/*/package.json")),
];
for (const file of packageJsonFiles) {
const pkg = (await ctx.readJSON(file)) as Record;
for (const depType of [
"dependencies",
"devDependencies",
"peerDependencies",
]) {
const deps = pkg[depType] as Record | undefined;
if (!deps) continue;
for (const [name, version] of Object.entries(deps)) {
if (
typeof version === "string" &&
!version.startsWith("catalog:") &&
!version.startsWith("workspace:")
) {
ctx.report.violation({
message: `${file}: ${depType}.${name} uses "${version}" instead of "catalog:" or "workspace:"`,
file,
fix: `Change to "catalog:" and ensure the package is listed in root package.json catalog`,
});
}
}
}
}
},
},
"catalog-completeness": {
description:
"All catalog: references must resolve to entries in root package.json catalog",
async check(ctx) {
const rootPkg = (await ctx.readJSON("package.json")) as Record<
string,
unknown
>;
const catalog = (rootPkg.catalog ?? {}) as Record;
const catalogKeys = new Set(Object.keys(catalog));
const packageJsonFiles = [
...(await ctx.glob("packages/*/package.json")),
...(await ctx.glob("packages/*/*/package.json")),
];
for (const file of packageJsonFiles) {
const pkg = (await ctx.readJSON(file)) as Record;
for (const depType of [
"dependencies",
"devDependencies",
"peerDependencies",
]) {
const deps = pkg[depType] as Record | undefined;
if (!deps) continue;
for (const [name, version] of Object.entries(deps)) {
if (
typeof version !== "string" ||
!version.startsWith("catalog:")
)
continue;
const catalogRef =
version === "catalog:"
? name
: version.slice("catalog:".length);
if (!catalogKeys.has(catalogRef)) {
ctx.report.violation({
message: `${file}: ${depType}.${name} references catalog:${catalogRef} but it is not in root catalog`,
file,
fix: `Add "${catalogRef}" to the catalog section in the root package.json`,
});
}
}
}
}
},
},
},
} satisfies RuleSet;
```
## Når du bør bruke den
I monorepoer der flere pakker deler avhengigheter og du ønsker en enkelt sannhetskilde for versjoner (f.eks. Bun workspaces med katalogstøtte, eller lignende oppsett).
## Når du ikke bør bruke den
I enkeltpakke-repositorier eller monorepoer som bruker en annen versjonsstyringstrategi som Renovates gruppeoppdateringer.