Describe the bug
Hi team, I ran into a confusing issue with getPublicPath and wanted to ask whether the current behavior is intentional or a bug. If it's intentional, could the docs mention it?
What confused me
The docs say getPublicPath accepts "a stringified function or a stringified return expression", and both are executed via new Function to get the publicPath. The main example in the docs uses the function form:
getPublicPath: `function() {return "https://" + window.cdn_host + "/app/"}`,
But when I tried it, the function form didn't actually change my chunk loading URLs. Only the "return" form did.
What I found in the source
In RemoteEntryPlugin.addPublicPathEntry, there's a branch on startsWith('function'):
if (!getPublicPath.startsWith('function')) {
code = `${compiler.webpack.RuntimeGlobals.publicPath} = new Function(...)()`;
// ↑ assigns to __webpack_require__.p
} else {
code = `(${getPublicPath}())`;
// ↑ just runs the function, return value is discarded
}
So:
- return form (
return "https://...") → generates __webpack_require__.p = new Function(...)() → writes the value into webpack's publicPath. Webpack's chunk loader (__webpack_require__.e / .l) picks it up.
- function form (
function(){ return "https://..." }) → generates (function(){...}()) → runs but throws away the return value. __webpack_require__.p stays at whatever output.publicPath was at compile time.
The function form does still end up in the manifest's metaData.getPublicPath, so the MF runtime side (loadRemote loading the expose chunk itself) works. But webpack's native chunk loader (loading sub-chunks inside an expose) doesn't use the manifest — it uses __webpack_require__.p, which the function form never touched.
The real-world symptom
I have a host that's also loaded as a qiankun sub-app. output.publicPath is '/' (relative). When embedded in another domain:
- The MF runtime loaded expose chunks from the correct CDN (manifest
getPublicPath worked).
- But webpack's chunk loader loaded the expose's sub-chunks from
'/', which resolved to the host page domain (wrong), returned index.html, and threw ChunkLoadError: Unexpected token '<'.
Switching the exact same getPublicPath string from function(){...} to a bare return ... body fixed it — sub-chunks now load from the CDN too.
My question
Is the startsWith('function') split intentional?
- If yes (e.g. the function form is meant only for manifest
metaData, and you expect users to set __webpack_public_path__ separately for webpack chunks) — could the docs say so? Right now the docs present both forms as equivalent and even use the function form as the example, so it's easy to assume it covers webpack's chunk loader too.
- If no — it looks like the else branch just forgot the
__webpack_require__.p = prefix.
Repro
Function form (sub-chunks use compile-time publicPath, not the CDN):
getPublicPath: `function () { return 'https://cdn.example.com/' }`,
// builds: (function () { return 'https://cdn.example.com/' }()) ← discarded
Return form (works):
getPublicPath: `try { return 'https://cdn.example.com/' } catch(e) {} return '/'`,
// builds: __webpack_require__.p = new Function("try { return '...' } ...")() ← assigned
Tested on @module-federation/rspack / @module-federation/enhanced 2.7.0.
Thanks!
Reproduction
Reproduction
Used Package Manager
npm
System Info
System, Binaries, Browsers
Validations
Describe the bug
Hi team, I ran into a confusing issue with
getPublicPathand wanted to ask whether the current behavior is intentional or a bug. If it's intentional, could the docs mention it?What confused me
The docs say
getPublicPathaccepts "a stringified function or a stringified return expression", and both are executed vianew Functionto get the publicPath. The main example in the docs uses the function form:But when I tried it, the function form didn't actually change my chunk loading URLs. Only the "return" form did.
What I found in the source
In
RemoteEntryPlugin.addPublicPathEntry, there's a branch onstartsWith('function'):So:
return "https://...") → generates__webpack_require__.p = new Function(...)()→ writes the value into webpack's publicPath. Webpack's chunk loader (__webpack_require__.e/.l) picks it up.function(){ return "https://..." }) → generates(function(){...}())→ runs but throws away the return value.__webpack_require__.pstays at whateveroutput.publicPathwas at compile time.The function form does still end up in the manifest's
metaData.getPublicPath, so the MF runtime side (loadRemote loading the expose chunk itself) works. But webpack's native chunk loader (loading sub-chunks inside an expose) doesn't use the manifest — it uses__webpack_require__.p, which the function form never touched.The real-world symptom
I have a host that's also loaded as a qiankun sub-app.
output.publicPathis'/'(relative). When embedded in another domain:getPublicPathworked).'/', which resolved to the host page domain (wrong), returnedindex.html, and threwChunkLoadError: Unexpected token '<'.Switching the exact same
getPublicPathstring fromfunction(){...}to a barereturn ...body fixed it — sub-chunks now load from the CDN too.My question
Is the
startsWith('function')split intentional?metaData, and you expect users to set__webpack_public_path__separately for webpack chunks) — could the docs say so? Right now the docs present both forms as equivalent and even use the function form as the example, so it's easy to assume it covers webpack's chunk loader too.__webpack_require__.p =prefix.Repro
Function form (sub-chunks use compile-time publicPath, not the CDN):
Return form (works):
Tested on
@module-federation/rspack/@module-federation/enhanced2.7.0.Thanks!
Reproduction
Reproduction
Used Package Manager
npm
System Info
Validations