version-catalog
Håndhev sentralisert versjonsadministrasjon i monorepoer ved å kreve catalog:- eller workspace:-notasjon for alle avhengigheter.
Regeldetaljer
Section titled “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
Section titled “Eksempler på feil kode”{ "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
Section titled “Eksempler på riktig kode”{ "dependencies": { "zod": "catalog:", "hono": "catalog:", "@myorg/shared": "workspace:*" }}{ "catalog": { "zod": "^3.23.0", "hono": "^4.0.0" } }Alle versjoner administreres sentralt. Oppgradering av zod krever bare endring av rotkatalogen.
Regelimplementasjon
Section titled “Regelimplementasjon”/// <reference path="../rules.d.ts" />
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<string, unknown>; for (const depType of [ "dependencies", "devDependencies", "peerDependencies", ]) { const deps = pkg[depType] as Record<string, string> | 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<string, string>; 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<string, unknown>; for (const depType of [ "dependencies", "devDependencies", "peerDependencies", ]) { const deps = pkg[depType] as Record<string, string> | 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
Section titled “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
Section titled “Når du ikke bør bruke den”I enkeltpakke-repositorier eller monorepoer som bruker en annen versjonsstyringstrategi som Renovates gruppeoppdateringer.