Skip to content

Commit 25f0983

Browse files
fix: support webpack publicPath: 'auto' (#312)
* fix: ignore webpack `publicPath: 'auto'` when generating manifest paths\n\nTreat 'auto' as runtime-resolved publicPath so we don’t serialize it into the manifest. Adds a unit test covering the behavior.\n\nRefs #307 * test: port two 'publicPath: auto' cases from #308 (credit @chouchouji)\n\n- publicPath 'auto' + basePath still prefixes manifest keys\n- publicPath 'auto' + plugin publicPath override applies to values\n\nRefs #307 --------- Co-authored-by: CharlieHelps <[email protected]>
1 parent 6be4e24 commit 25f0983

2 files changed

Lines changed: 71 additions & 1 deletion

File tree

src/hooks.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,13 @@ const emitHook = function emit(
8080
publicPath: true
8181
});
8282

83-
const publicPath = options.publicPath !== null ? options.publicPath : stats.publicPath;
83+
// Webpack v5 supports `output.publicPath: 'auto'`, which resolves the publicPath
84+
// at runtime based on the current script/asset location. In that mode, the
85+
// string value 'auto' should not be serialized into the manifest. Treat it as
86+
// an "unset" publicPath so manifest values remain unprefixed and consumers can
87+
// resolve at runtime. See https://webpack.js.org/guides/public-path/#automatic-publicpath
88+
const resolvedPublicPath = options.publicPath !== null ? options.publicPath : stats.publicPath;
89+
const publicPath = resolvedPublicPath === 'auto' ? '' : resolvedPublicPath;
8490
const { basePath, removeKeyHash } = options;
8591

8692
emitCountMap.set(manifestFileName, emitCount);

test/unit/paths.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,70 @@ test('prefixes paths with a public path', async (t) => {
7272
});
7373
});
7474

75+
test("does not prefix paths when webpack's publicPath is 'auto'", async (t) => {
76+
const config = {
77+
context: __dirname,
78+
entry: {
79+
one: '../fixtures/file.js'
80+
},
81+
output: {
82+
filename: `[name].${hashLiteral}.js`,
83+
path: join(outputPath, 'public-auto'),
84+
// Webpack will resolve the publicPath at runtime; the manifest should not contain 'auto'.
85+
publicPath: 'auto'
86+
}
87+
} as any;
88+
const { manifest, stats } = await compile(config, t);
89+
90+
t.deepEqual(manifest, {
91+
'one.js': `one.${(stats as any).hash}.js`
92+
});
93+
});
94+
95+
test("prefixes definitions with a base path when webpack's publicPath is 'auto'", async (t) => {
96+
const config = {
97+
context: __dirname,
98+
entry: {
99+
one: '../fixtures/file.js'
100+
},
101+
output: {
102+
filename: `[name].${hashLiteral}.js`,
103+
path: join(outputPath, 'public-auto-with-basePath'),
104+
publicPath: 'auto'
105+
}
106+
} as any;
107+
108+
const { manifest, stats } = await compile(config, t, {
109+
basePath: '/app/'
110+
});
111+
112+
t.deepEqual(manifest, {
113+
'/app/one.js': `one.${(stats as any).hash}.js`
114+
});
115+
});
116+
117+
test("uses plugin 'publicPath' override when webpack's publicPath is 'auto'", async (t) => {
118+
const config = {
119+
context: __dirname,
120+
entry: {
121+
one: '../fixtures/file.js'
122+
},
123+
output: {
124+
filename: `[name].${hashLiteral}.js`,
125+
path: join(outputPath, 'public-auto-with-override'),
126+
publicPath: 'auto'
127+
}
128+
} as any;
129+
130+
const { manifest, stats } = await compile(config, t, {
131+
publicPath: '/cdn/'
132+
});
133+
134+
t.deepEqual(manifest, {
135+
'one.js': `/cdn/one.${(stats as any).hash}.js`
136+
});
137+
});
138+
75139
test(`prefixes paths with a public path and handle ${hashLiteral} from public path`, async (t) => {
76140
const config = {
77141
context: __dirname,

0 commit comments

Comments
 (0)