Skip to content

Commit aa18aea

Browse files
authored
Merge pull request #245 from webpack/bugfix/pnp
resolve PnP at the location of node_modules in the modules option
2 parents c200a08 + 6ec84c2 commit aa18aea

File tree

4 files changed

+79
-9
lines changed

4 files changed

+79
-9
lines changed

lib/PnpPlugin.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,19 @@ module.exports = class PnpPlugin {
5151
});
5252
}
5353
} catch (error) {
54+
if (
55+
error.code === "MODULE_NOT_FOUND" &&
56+
error.pnpCode === "UNDECLARED_DEPENDENCY"
57+
) {
58+
// This is not a PnP managed dependency.
59+
// Try to continue resolving with our alternatives
60+
if (resolveContext.log) {
61+
resolveContext.log(`request is not managed by the pnpapi`);
62+
for (const line of error.message.split("\n").filter(Boolean))
63+
resolveContext.log(` ${line}`);
64+
}
65+
return callback();
66+
}
5467
return callback(error);
5568
}
5669

lib/ResolverFactory.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -375,15 +375,17 @@ exports.createResolver = function(options) {
375375
new SelfReferencePlugin("raw-module", exportsField, "resolve-as-module")
376376
);
377377
});
378-
if (pnpApi) {
379-
plugins.push(new PnpPlugin("raw-module", pnpApi, "relative"));
380-
}
381378
modules.forEach(item => {
382-
if (Array.isArray(item))
379+
if (Array.isArray(item)) {
383380
plugins.push(
384381
new ModulesInHierachicDirectoriesPlugin("raw-module", item, "module")
385382
);
386-
else plugins.push(new ModulesInRootPlugin("raw-module", item, "module"));
383+
if (item.includes("node_modules") && pnpApi) {
384+
plugins.push(new PnpPlugin("raw-module", pnpApi, "relative"));
385+
}
386+
} else {
387+
plugins.push(new ModulesInRootPlugin("raw-module", item, "module"));
388+
}
387389
});
388390

389391
// module

test/fixtures/pnp-a/m2/a.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = function a() {
2+
return "This is nested m1/a";
3+
};

test/pnp.js

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,22 @@ describe("pnp", () => {
4242
if (pnpApi.mocks.has(request)) {
4343
return pnpApi.mocks.get(request);
4444
} else {
45-
throw new Error(`No way`);
45+
const err = /** @type {any} */ (new Error(`No way`));
46+
err.code = "MODULE_NOT_FOUND";
47+
err.pnpCode = "UNDECLARED_DEPENDENCY";
48+
throw err;
4649
}
4750
}
4851
});
4952
resolver = ResolverFactory.createResolver({
5053
extensions: [".ts", ".js"],
5154
aliasFields: ["browser"],
5255
fileSystem: nodeFileSystem,
53-
pnpApi
56+
alias: {
57+
alias: path.resolve(fixture, "pkg")
58+
},
59+
pnpApi,
60+
modules: ["node_modules", path.resolve(fixture, "../pnp-a")]
5461
});
5562
});
5663
it("should resolve by going through the pnp api", done => {
@@ -145,15 +152,60 @@ describe("pnp", () => {
145152
done();
146153
});
147154
});
148-
it("should skip normal modules when pnp resolves", done => {
155+
it("should prefer normal modules over pnp resolves", done => {
149156
pnpApi.mocks.set("m1/a.js", path.resolve(fixture, "pkg/a.js"));
150157
resolver.resolve(
151158
{},
152159
path.resolve(__dirname, "fixtures"),
153160
"m1/a.js",
154161
{},
155162
(err, result) => {
156-
if (!err) return done(new Error("Resolving should fail"));
163+
if (err) return done(err);
164+
result.should.equal(path.resolve(fixture, "../node_modules/m1/a.js"));
165+
done();
166+
}
167+
);
168+
});
169+
it("should prefer alias over pnp resolves", done => {
170+
pnpApi.mocks.set(
171+
"alias/index.js",
172+
path.resolve(fixture, "pkg/dir/index.js")
173+
);
174+
resolver.resolve(
175+
{},
176+
path.resolve(__dirname, "fixtures"),
177+
"alias/index.js",
178+
{},
179+
(err, result) => {
180+
if (err) return done(err);
181+
result.should.equal(path.resolve(fixture, "pkg/index.js"));
182+
done();
183+
}
184+
);
185+
});
186+
it("should prefer pnp over modules after node_modules", done => {
187+
pnpApi.mocks.set("m2/a.js", path.resolve(fixture, "pkg/index.js"));
188+
resolver.resolve(
189+
{},
190+
path.resolve(__dirname, "fixtures"),
191+
"m2/a.js",
192+
{},
193+
(err, result) => {
194+
if (err) return done(err);
195+
result.should.equal(path.resolve(fixture, "pkg/index.js"));
196+
done();
197+
}
198+
);
199+
});
200+
it("should fallback to alternatives when pnp resolving fails", done => {
201+
resolver.resolve(
202+
{},
203+
path.resolve(__dirname, "fixtures"),
204+
"m2/a.js",
205+
{},
206+
(err, result) => {
207+
if (err) return done(err);
208+
result.should.equal(path.resolve(fixture, "../pnp-a/m2/a.js"));
157209
done();
158210
}
159211
);

0 commit comments

Comments
 (0)