diff --git a/.yarn/versions/575ebbc8.yml b/.yarn/versions/575ebbc8.yml new file mode 100644 index 000000000000..c54fa28f6d6d --- /dev/null +++ b/.yarn/versions/575ebbc8.yml @@ -0,0 +1,24 @@ +releases: + "@yarnpkg/cli": prerelease + "@yarnpkg/plugin-node-modules": prerelease + "@yarnpkg/pnpify": prerelease + +declined: + - "@yarnpkg/plugin-constraints" + - "@yarnpkg/plugin-dlx" + - "@yarnpkg/plugin-essentials" + - "@yarnpkg/plugin-init" + - "@yarnpkg/plugin-interactive-tools" + - "@yarnpkg/plugin-npm-cli" + - "@yarnpkg/plugin-pack" + - "@yarnpkg/plugin-patch" + - "@yarnpkg/plugin-pnp" + - "@yarnpkg/plugin-stage" + - "@yarnpkg/plugin-typescript" + - "@yarnpkg/plugin-version" + - "@yarnpkg/plugin-workspace-tools" + - vscode-zipfs + - "@yarnpkg/builder" + - "@yarnpkg/core" + - "@yarnpkg/doctor" + - "@yarnpkg/pnp" diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/features/pnpLoose.test.js b/packages/acceptance-tests/pkg-tests-specs/sources/features/pnpLoose.test.js index 19b03e004f11..e566abca487e 100644 --- a/packages/acceptance-tests/pkg-tests-specs/sources/features/pnpLoose.test.js +++ b/packages/acceptance-tests/pkg-tests-specs/sources/features/pnpLoose.test.js @@ -46,6 +46,29 @@ describe(`Features`, () => { ), ); + test( + `it should allow resolutions to top-level hoisting candidates (even if they have peer dependencies)`, + makeTemporaryEnv( + { + dependencies: { + [`no-deps`]: `1.0.0`, + [`forward-peer-deps`]: `1.0.0`, + }, + }, + { + pnpMode: `loose`, + }, + async ({path, run, source}) => { + await run(`install`); + + await expect(source(`require('peer-deps')`)).resolves.toMatchObject({ + name: `peer-deps`, + version: `1.0.0`, + }); + }, + ), + ); + test( `it should log an exception if a dependency tries to require something it doesn't own but that can be accessed through hoisting`, makeTemporaryEnv( diff --git a/packages/plugin-node-modules/sources/PnpLooseLinker.ts b/packages/plugin-node-modules/sources/PnpLooseLinker.ts index 576e610a8db0..24887d84adea 100644 --- a/packages/plugin-node-modules/sources/PnpLooseLinker.ts +++ b/packages/plugin-node-modules/sources/PnpLooseLinker.ts @@ -1,9 +1,9 @@ -import {LinkOptions, MinimalLinkOptions, Package} from '@yarnpkg/core'; -import {VirtualFS, ZipOpenFS, ppath, PortablePath, npath, Filename} from '@yarnpkg/fslib'; -import {getLibzipPromise} from '@yarnpkg/libzip'; -import {PnpInstaller, PnpLinker} from '@yarnpkg/plugin-pnp'; -import {NodeModulesPackageNode, buildNodeModulesTree} from '@yarnpkg/pnpify'; -import {PnpSettings, makeRuntimeApi, PackageInformation, PhysicalPackageLocator, DependencyTarget} from '@yarnpkg/pnp'; +import {LinkOptions, structUtils} from '@yarnpkg/core'; +import {VirtualFS, ZipOpenFS, ppath, npath, Filename} from '@yarnpkg/fslib'; +import {getLibzipPromise} from '@yarnpkg/libzip'; +import {PnpInstaller, PnpLinker} from '@yarnpkg/plugin-pnp'; +import {NodeModulesPackageNode, buildNodeModulesTree} from '@yarnpkg/pnpify'; +import {PnpSettings, makeRuntimeApi, DependencyTarget} from '@yarnpkg/pnp'; export class PnpLooseLinker extends PnpLinker { protected mode = `loose`; @@ -35,14 +35,13 @@ class PnpLooseInstaller extends PnpInstaller { pnpSettings.fallbackPool = fallbackPool; const registerFallback = (name: string, entry: NodeModulesPackageNode) => { - const locator = pnp.findPackageLocator(`${npath.fromPortablePath(entry.target)}/`); - if (locator === null) - throw new Error(`Assertion failed: Expected the target to map to a locator`); + const locator = structUtils.parseLocator(entry.locator); + const identStr = structUtils.stringifyIdent(locator); - if (locator.name === name) { + if (identStr === name) { fallbackPool.set(name, locator.reference); } else { - fallbackPool.set(name, [locator.name, locator.reference]); + fallbackPool.set(name, [identStr, locator.reference]); } }; diff --git a/packages/yarnpkg-pnpify/sources/buildNodeModulesTree.ts b/packages/yarnpkg-pnpify/sources/buildNodeModulesTree.ts index cb4c8113673a..0fce03459938 100644 --- a/packages/yarnpkg-pnpify/sources/buildNodeModulesTree.ts +++ b/packages/yarnpkg-pnpify/sources/buildNodeModulesTree.ts @@ -17,6 +17,7 @@ export type NodeModulesBaseNode = { // The entry for a package within a node_modules export type NodeModulesPackageNode = { locator: LocatorKey, + // The source path. Note that the virtual paths have been resolved/lost! target: PortablePath, // Hard links are copies of the target; soft links are symlinks to it linkType: LinkType,