Skip to content

💡 Support project-defined conditions beyond the built-in resolver fallbacks #1877

Description

@popelenkow

Suggest an idea for Knip

Source-first monorepos may expose TypeScript sources to repository tooling through a project-defined condition while keeping compiled output for package consumers:

{
  "exports": {
    ".": {
      "monorepo": "./src/index.ts",
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js",
      "default": "./dist/index.js"
    }
  }
}

Knip's main resolver activates require, import, and node; its fallback activates require, import, and browser. Neither resolver activates monorepo, so both select a dist target instead of the available source.

I reproduced this with [email protected]. A temporary backport of the proposed configuration and a working validation are available in PR #667.

The same project-defined condition can already be configured for other tools:

// Vite
conditions: ['monorepo', ...defaultClientConditions];

// eslint-import-resolver-typescript
conditionNames: ['monorepo', ...defaultConditionNames];

Related issue

This is related to issue #1873, which was recently resolved in Knip 6.26.0 by adding a browser-condition fallback. That fix handles the reported map where node points to unbuilt output and default points to source: the fallback omits node, so the source target can be selected.

However, changing from the node condition to the browser fallback cannot activate an arbitrary project-defined condition. The fix for #1873 therefore does not cover the configuration above.

Prior art

Proposed configuration

Expose the conditionNames option of oxc-resolver as a top-level Knip
configuration option:

{
  "conditions": ["monorepo", "require", "import", "node", "default"]
}

The configured array should replace Knip's built-in condition names for all module resolvers. When the option is omitted, existing resolver-specific node and browser behavior should remain unchanged. Package map default targets remain fallbacks according to conditional exports/imports semantics.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions