Skip to content

Commit cd4c62e

Browse files
xiaoxiaojxclaude
andcommitted
fix: VirtualUrlPlugin absolute-path virtual module IDs getting concatenated with compiler context
When a virtual module ID is an absolute path (e.g. `virtual:C:/project/user.js`), context "auto" incorrectly joined the derived context with `compiler.context` via `path.join`, producing a concatenated path like `C:\cwd\C:\project`. Now absolute contexts are detected via `isAbsolute` (from `lib/util/fs`) and used directly. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
1 parent 5afe990 commit cd4c62e

File tree

4 files changed

+46
-5
lines changed

4 files changed

+46
-5
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"webpack": patch
3+
---
4+
5+
fix: VirtualUrlPlugin absolute path virtual module IDs getting concatenated with compiler context
6+
7+
When a virtual module ID is an absolute path (e.g. `virtual:C:/project/user.js`), the auto-derived context was incorrectly joined with `compiler.context`, producing a concatenated path like `C:\cwd\C:\project`. Now absolute-path contexts are used directly.

lib/schemes/VirtualUrlPlugin.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const { getContext } = require("loader-runner");
99

1010
const ModuleNotFoundError = require("../ModuleNotFoundError");
1111
const NormalModule = require("../NormalModule");
12-
const { join } = require("../util/fs");
12+
const { isAbsolute, join } = require("../util/fs");
1313
const { parseResourceWithoutFragment } = require("../util/identifier");
1414

1515
const DEFAULT_SCHEME = "virtual";
@@ -190,15 +190,19 @@ class VirtualUrlPlugin {
190190

191191
if (context === "auto") {
192192
const context = getContext(path);
193-
resourceData.context =
194-
context === path
195-
? compiler.context
193+
if (context === path) {
194+
resourceData.context = compiler.context;
195+
} else {
196+
const resolvedContext = fromVid(context, scheme);
197+
resourceData.context = isAbsolute(resolvedContext)
198+
? resolvedContext
196199
: join(
197200
/** @type {import("..").InputFileSystem} */
198201
(compiler.inputFileSystem),
199202
compiler.context,
200-
fromVid(context, scheme)
203+
resolvedContext
201204
);
205+
}
202206
} else if (context && typeof context === "string") {
203207
resourceData.context = context;
204208
} else {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const value = "helper-value";
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"use strict";
2+
3+
const path = require("path");
4+
const webpack = require("../../../../");
5+
6+
const { VirtualUrlPlugin } = webpack.experiments.schemes;
7+
8+
// The virtual module ID is an absolute path.
9+
// When context is "auto", the plugin should derive the context from that
10+
// absolute path directly, not concatenate it with compiler.context.
11+
const virtualModulePath = path.join(__dirname, "virtual-entry.js");
12+
13+
/** @type {import("webpack").Configuration} */
14+
const config = {
15+
entry: `virtual:${virtualModulePath}`,
16+
plugins: [
17+
new VirtualUrlPlugin({
18+
[virtualModulePath]: {
19+
context: "auto",
20+
source() {
21+
return "import { value } from './helper.js'; it('should resolve relative imports from absolute-path virtual modules', (done) => { expect(value).toBe('helper-value'); done(); });";
22+
}
23+
}
24+
})
25+
],
26+
validate: true
27+
};
28+
29+
module.exports = config;

0 commit comments

Comments
 (0)