Skip to content

Commit ca54d0c

Browse files
committed
fix(pnp): resolve virtual paths in process.dlopen (#4630)
1 parent 7abe377 commit ca54d0c

File tree

5 files changed

+92
-11
lines changed

5 files changed

+92
-11
lines changed

.pnp.cjs

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.yarn/versions/c4427793.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
releases:
2+
"@yarnpkg/cli": patch
3+
"@yarnpkg/plugin-pnp": patch
4+
"@yarnpkg/pnp": patch
5+
6+
declined:
7+
- "@yarnpkg/esbuild-plugin-pnp"
8+
- "@yarnpkg/plugin-compat"
9+
- "@yarnpkg/plugin-constraints"
10+
- "@yarnpkg/plugin-dlx"
11+
- "@yarnpkg/plugin-essentials"
12+
- "@yarnpkg/plugin-init"
13+
- "@yarnpkg/plugin-interactive-tools"
14+
- "@yarnpkg/plugin-nm"
15+
- "@yarnpkg/plugin-npm-cli"
16+
- "@yarnpkg/plugin-pack"
17+
- "@yarnpkg/plugin-patch"
18+
- "@yarnpkg/plugin-pnpm"
19+
- "@yarnpkg/plugin-stage"
20+
- "@yarnpkg/plugin-typescript"
21+
- "@yarnpkg/plugin-version"
22+
- "@yarnpkg/plugin-workspace-tools"
23+
- "@yarnpkg/builder"
24+
- "@yarnpkg/core"
25+
- "@yarnpkg/doctor"
26+
- "@yarnpkg/nm"
27+
- "@yarnpkg/pnpify"
28+
- "@yarnpkg/sdks"

packages/acceptance-tests/pkg-tests-specs/sources/pnp.test.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const {npath, ppath, xfs} = require(`@yarnpkg/fslib`);
1+
const {npath, ppath, xfs, Filename} = require(`@yarnpkg/fslib`);
22
const cp = require(`child_process`);
33
const {satisfies} = require(`semver`);
44

@@ -2097,4 +2097,33 @@ describe(`Plug'n'Play`, () => {
20972097
},
20982098
),
20992099
);
2100+
2101+
test(
2102+
`it should resolve virtual paths passed to process.dlopen`,
2103+
makeTemporaryEnv(
2104+
{
2105+
dependencies: {
2106+
pkg: `portal:./pkg`,
2107+
},
2108+
},
2109+
async ({path, run, source}) => {
2110+
await xfs.mkdirPromise(ppath.join(path, `pkg`));
2111+
await xfs.writeFilePromise(ppath.join(path, `pkg/test.node`), `invalid`);
2112+
await xfs.writeJsonPromise(ppath.join(path, `pkg`, Filename.manifest), {
2113+
name: `pkg`,
2114+
peerDependencies: {
2115+
'no-deps': `*`,
2116+
},
2117+
});
2118+
2119+
await expect(run(`install`)).resolves.toMatchObject({code: 0});
2120+
2121+
await expect(source(`require('pkg/test.node')`)).rejects.toMatchObject({
2122+
externalException: {
2123+
message: expect.not.stringMatching(/__virtual__|invalid mode/),
2124+
},
2125+
});
2126+
},
2127+
),
2128+
);
21002129
});

packages/yarnpkg-pnp/sources/hook.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/yarnpkg-pnp/sources/loader/applyPatch.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import {FakeFS, PosixFS, npath, patchFs, PortablePath, NativePath} from '@yarnpkg/fslib';
2-
import fs from 'fs';
3-
import {Module} from 'module';
4-
import {URL, fileURLToPath} from 'url';
1+
import {FakeFS, PosixFS, npath, patchFs, PortablePath, NativePath, VirtualFS} from '@yarnpkg/fslib';
2+
import fs from 'fs';
3+
import {Module} from 'module';
4+
import {URL, fileURLToPath} from 'url';
55

6-
import {PnpApi} from '../types';
6+
import {PnpApi} from '../types';
77

8-
import {ErrorCode, makeError, getIssuerModule} from './internalTools';
9-
import {Manager} from './makeManager';
10-
import * as nodeUtils from './nodeUtils';
8+
import {ErrorCode, makeError, getIssuerModule} from './internalTools';
9+
import {Manager} from './makeManager';
10+
import * as nodeUtils from './nodeUtils';
1111

1212
export type ApplyPatchOptions = {
1313
fakeFs: FakeFS<PortablePath>;
@@ -19,6 +19,14 @@ type PatchedModule = Module & {
1919
isLoading?: boolean;
2020
};
2121

22+
declare global {
23+
module NodeJS {
24+
interface Process {
25+
dlopen: (module: Object, filename: string, flags?: number) => void;
26+
}
27+
}
28+
}
29+
2230
export function applyPatch(pnpapi: PnpApi, opts: ApplyPatchOptions) {
2331
/**
2432
* The cache that will be used for all accesses occurring outside of a PnP context.
@@ -411,6 +419,17 @@ export function applyPatch(pnpapi: PnpApi, opts: ApplyPatchOptions) {
411419
originalExtensionJSFunction.call(this, module, filename);
412420
};
413421

422+
const originalDlopen = process.dlopen;
423+
process.dlopen = function (...args) {
424+
const [module, filename, ...rest] = args;
425+
return originalDlopen.call(
426+
this,
427+
module,
428+
npath.fromPortablePath(VirtualFS.resolveVirtual(npath.toPortablePath(filename))),
429+
...rest,
430+
);
431+
};
432+
414433
// When using the ESM loader Node.js prints either of the following warnings
415434
//
416435
// - ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time

0 commit comments

Comments
 (0)