diff --git a/AGENTS.md b/AGENTS.md index f36a095b672f..2ef332569fa5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -101,9 +101,12 @@ Update Vitest failing snapshots with the `-u` option. Do not blindly update snap - `pnpm lint:catalogs` - Check the content of the pnpm catalogs - `pnpm lint:knip` - Knip to find unused files, exports and dependencies (config in `knip.config.ts`) - `pnpm lint:knip:production` - Knip to find the exports and dependencies of published packages that only tests use +- `pnpm lint:knip:public-api` - Knip to warn about the public API exports that the monorepo doesn't use, not part of `pnpm lint` - `pnpm lint:deps` - Check that `pnpm-lock.yaml` is deduplicated (`pnpm dedupe --check`) - Add `:fix` suffix to auto-fix issues (e.g., `pnpm lint:js:fix`) +The exports of package entry points (`package.json` `main` and `exports`) are public API, even when undocumented (see the comments in `packages/docusaurus-theme-common/src/index.ts`) or unused by the monorepo: third-party sites, plugins and themes use them. Never remove them as dead code: report them, and only remove one when the maintainer explicitly decides to, as a breaking change. `/internal` entry points (like `@docusaurus/theme-common/internal`) have no stability guarantee, but removing their exports is still a breaking change PR. + To fix CSpell unknown words, don't run `pnpm lint:spelling:fix`: it checks the whole repository and is slow. Instead: 1. Check the files you changed: `pnpm exec cspell --no-progress --show-context `. Ignore files in dot-directories (`.agents/`, `.github/`...): `pnpm lint:spelling` doesn't check them diff --git a/knip.config.ts b/knip.config.ts index 05a6cab60f02..3af15e860e8a 100644 --- a/knip.config.ts +++ b/knip.config.ts @@ -21,6 +21,29 @@ function themePackageConfig({ }; } +// `pnpm lint:knip:public-api` passes --include-entry-exports to report the +// unused exports of package entry points. They are public API that sites, +// plugins and themes can use: only warn about them, see AGENTS.md +const publicApiConfig: KnipConfiguration = { + rules: {exports: 'warn', types: 'warn'}, + // Public API used in ways Knip can't follow + ignoreIssues: { + // Theme components, resolved through @theme/* aliases or swizzled + 'packages/*/src/theme/**': ['exports', 'types'], + // Plugin and theme modules: Docusaurus loads their values by name from the + // site config + 'packages/docusaurus-{plugin,preset}-*/src/index.ts': ['exports'], + 'packages/docusaurus-theme-!(common|translations)/src/index.ts': [ + 'exports', + ], + // Core has no package entry point: Docusaurus loads its files by path or + // through the @docusaurus/* and @theme/* aliases + 'packages/docusaurus/**': ['exports', 'types'], + // Knip doesn't link the imports of @docusaurus/types to this package + 'packages/docusaurus-types/**': ['exports', 'types'], + }, +}; + // Knip calls this function with its parsed CLI arguments // // Entry patterns ending with "!" are production entries: @@ -29,7 +52,10 @@ function themePackageConfig({ // The package.json main/exports/bin fields are production entries, but the // entries written here need the suffix. A leading "!" is an unrelated negation. // See https://knip.dev/features/production-mode -const config: KnipConfig = ({production}) => ({ +const config: KnipConfig = ({ + production, + 'include-entry-exports': includeEntryExports, +}) => ({ // Production mode reports the exports only used by tests, except the ones // also used in their own file: they are often exported to be tested ignoreExportsUsedInFile: production, @@ -199,6 +225,7 @@ const config: KnipConfig = ({production}) => ({ ], }, }, + ...(includeEntryExports ? publicApiConfig : {}), }); export default config; diff --git a/package.json b/package.json index dc9968d8e299..bdf28b5bf8c6 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "lint:deps:fix": "pnpm dedupe", "lint:knip": "knip", "lint:knip:production": "knip --production --exports --dependencies --no-tag-hints --workspace './packages/*'", + "lint:knip:public-api": "knip --include-entry-exports --include exports,types --workspace './packages/*'", "lint:knip:fix": "knip --fix", "lerna": "lerna", "test": "vitest run",