fix(resolve-extends): support Yarn Plug'n'Play by Guflly · Pull Request #4933 · conventional-changelog/commitlint · GitHub
Skip to content

fix(resolve-extends): support Yarn Plug'n'Play - #4933

Merged
escapedcat merged 5 commits into
conventional-changelog:masterfrom
Guflly:fix/yarn-pnp-resolution
Aug 6, 2026
Merged

escapedcat merged 5 commits into
conventional-changelog:masterfrom
Guflly:fix/yarn-pnp-resolution

Conversation

@Guflly

@Guflly Guflly commented Aug 5, 2026 •

Copy link
Copy Markdown
Contributor

Description

Adds Yarn Plug'n'Play resolution to the pure ESM preset fallback while preserving the existing node_modules lookup.

Motivation and Context

Yarn PnP projects do not have a node_modules tree, so import-only ESM presets cannot be found by the existing fallback. The resolver now asks the PnP API for the package location first.

Closes #2637.

Usage examples

Existing Yarn PnP configurations work without changes.

How Has This Been Tested?

  • pnpm exec vitest run @commitlint/resolve-extends/src/index.test.ts (30 tests)
  • pnpm build
  • pnpm lint
  • pnpm check-no-focused-tests
  • Yarn 4.17 PnP smoke test with conventional-changelog-conventionalcommits@10.2.0
  • pnpm test (1199 passed; 10 unrelated Windows environment failures from symlink permissions and the workspace Git root)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have verified that any documentation examples I added/changed actually work.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • For a feature/bug fix, my commits follow the test-driven flow: a failing-test commit, then the implementation.

@qodo-code-review

Copy link
Copy Markdown

@greptile-apps

greptile-apps Bot commented Aug 5, 2026 •

Copy link
Copy Markdown

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
@commitlint/resolve-extends/src/index.ts Adds guarded Yarn PnP package lookup and preserves the prior node_modules fallback behavior.
@commitlint/resolve-extends/src/index.test.ts Adds focused coverage for PnP pure-ESM resolution and confirms that pnpapi is not loaded outside PnP.

Reviews (3): Last reviewed commit: "test(resolve-extends): isolate non-PnP f..." | Re-trigger Greptile

@qodo-code-review

qodo-code-review Bot commented Aug 5, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Silent pnpapi load failure ✓ Resolved 🐞 Bug ☼ Reliability
Description
In the pure-ESM fallback, resolveEsmOnly unconditionally loads "pnpapi" via localRequire and
suppresses all exceptions, which can mask genuine PnP resolution/runtime errors and makes failures
hard to diagnose. It also means a resolvable third-party "pnpapi" package (non-PnP) would be
executed on this fallback path rather than only when actually running under PnP.
Code

@commitlint/resolve-extends/src/index.ts[R106-109]

+	try {
+		const pnpApi = localRequire("pnpapi") as {
+			resolveToUnqualified(
+				request: string,
Evidence
The new PnP resolution branch loads pnpapi and discards all errors, and it is executed from
resolveFrom’s fallback path when standard resolution fails. resolveFrom is invoked for resolving
presets/configs from user config, so this silent failure affects real-world debugging.

@commitlint/resolve-extends/src/index.ts[93-139]
@commitlint/resolve-extends/src/index.ts[142-184]
@commitlint/resolve-extends/src/index.ts[261-266]
@commitlint/resolve-extends/src/index.ts[309-332]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`resolveEsmOnly` attempts `localRequire("pnpapi")` and wraps the whole PnP branch in `catch {}`. This hides unexpected PnP API failures and can also load an unintended `pnpapi` dependency in non-PnP projects.

### Issue Context
This code path runs when normal `require.resolve` and `resolve-from` fail (e.g., pure-ESM packages with import-only `exports`). `resolveFrom` is called as part of resolving user configuration (extends/parser presets), so diagnostics matter.

### Fix Focus Areas
- @commitlint/resolve-extends/src/index.ts[93-139]

### Suggested fix
- Only attempt the PnP resolution branch when actually running under PnP (e.g., by checking a Node-provided PnP indicator such as `process.versions.pnp` or an equivalent Node API).
- Narrow the catch handling:
 - Ignore “module not found” for `pnpapi` as an expected non-PnP case.
 - For other errors (loading `pnpapi`, calling `resolveToUnqualified`, reading manifests), emit a debug log when `process.env.DEBUG === "true"` before falling back to `node_modules` walking.
- Keep the behavior of falling back to `node_modules` lookup when PnP isn’t available.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread @commitlint/resolve-extends/src/index.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates @commitlint/resolve-extends to resolve pure-ESM preset packages in Yarn Plug’n’Play (PnP) projects by consulting the PnP API first, while keeping the existing node_modules walk fallback for non-PnP installs.

Changes:

  • Add a Yarn PnP resolution path for pure-ESM preset fallback resolution via pnpapi.resolveToUnqualified.
  • Refactor ESM-only package resolution into a shared helper (resolveEsmPackage) used by both PnP and node_modules fallback paths.
  • Add unit tests covering the PnP code path and ensuring behavior differs when PnP is not active.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
@commitlint/resolve-extends/src/index.ts Adds PnP-aware resolution before the existing node_modules walk for pure-ESM presets.
@commitlint/resolve-extends/src/index.test.ts Adds scaffolding and tests for simulating PnP resolution and validating behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread @commitlint/resolve-extends/src/index.test.ts
@escapedcat

Copy link
Copy Markdown
Member

Have a look at the feedback, not sure how important that really is

@Guflly

Guflly commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

It was valid. Fixed in 5008895; the non-PnP test now deletes and restores the PnP marker. The focused tests, lint, formatting, and build pass.

@escapedcat
escapedcat merged commit 67ee127 into conventional-changelog:master Aug 6, 2026
12 checks passed
@escapedcat

Copy link
Copy Markdown
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

CommitLint with Yarn v2 (Plug'n'play)

3 participants