Bug report
After upgrading to webpack@5.108.0, our production bundle started throwing a runtime error:
TypeError: Cannot read properties of undefined (reading 'y')
The generated bundle contains code like this:
But the actual exported name on the imported module is a mangled export named zy, so the generated code should be:
It looks like the mangled export name string "zy" is being passed to propertyAccess(...) as an ArrayLike<string>, causing it to be rendered as .z.y.
Regression
This only started after webpack@5.108.0.
With webpack@5.107.2, the same project builds correctly.
This looks related to:
Triggering pattern
The issue appears when a namespace import is used as a whole value / escapes, for example code like this from a dependency:
import * as tmp from "react-router";
const rc = tmp;
const location = rc.useLocation();
In our case this comes from @ahooksjs/use-url-state, which imports react-router this way.
The generated namespace getter incorrectly accesses the mangled export as a property path:
instead of:
Suspected cause
In lib/optimize/ConcatenatedModule.js, the new decoupled namespace object generation path seems to call:
const usedName = exportInfo.getUsedName(undefined, runtime);
ExportInfo#getUsedName(...) returns a string such as "zy".
Later, for external modules, it is rendered with:
`${info.name}${propertyAccess(usedName)}`
But propertyAccess(...) expects an array-like path. Since strings are also array-like, "zy" becomes .z.y.
Relevant code path in the 5.108.0 release appears to be around:
const usedName = exportInfo.getUsedName(undefined, runtime);
// ...
info.type === "external"
? `${info.name}${propertyAccess(usedName)}`
: getFinalName(...)
A possible fix may be to wrap string used names before passing them to propertyAccess, for example:
propertyAccess([usedName])
or use exportsInfo.getUsedName([exportInfo.name], runtime) consistently with the other path in RuntimeTemplate.
Expected behavior
If an export is mangled to a multi-character name like "zy", webpack should generate:
not:
Actual behavior
webpack generates:
which crashes at runtime because module.z is undefined.
Environment
webpack: 5.108.0
webpack 5.107.2: works
target: web
mode: production
optimization.mangleExports: enabled
The affected runtime dependency in my bundle is react-router, accessed through @ahooksjs/use-url-state.
Bug report
After upgrading to
webpack@5.108.0, our production bundle started throwing a runtime error:The generated bundle contains code like this:
But the actual exported name on the imported module is a mangled export named
zy, so the generated code should be:It looks like the mangled export name string
"zy"is being passed topropertyAccess(...)as anArrayLike<string>, causing it to be rendered as.z.y.Regression
This only started after
webpack@5.108.0.With
webpack@5.107.2, the same project builds correctly.This looks related to:
Triggering pattern
The issue appears when a namespace import is used as a whole value / escapes, for example code like this from a dependency:
In our case this comes from
@ahooksjs/use-url-state, which importsreact-routerthis way.The generated namespace getter incorrectly accesses the mangled export as a property path:
instead of:
Suspected cause
In
lib/optimize/ConcatenatedModule.js, the new decoupled namespace object generation path seems to call:ExportInfo#getUsedName(...)returns a string such as"zy".Later, for external modules, it is rendered with:
`${info.name}${propertyAccess(usedName)}`But
propertyAccess(...)expects an array-like path. Since strings are also array-like,"zy"becomes.z.y.Relevant code path in the
5.108.0release appears to be around:A possible fix may be to wrap string used names before passing them to
propertyAccess, for example:or use
exportsInfo.getUsedName([exportInfo.name], runtime)consistently with the other path inRuntimeTemplate.Expected behavior
If an export is mangled to a multi-character name like
"zy", webpack should generate:not:
Actual behavior
webpack generates:
which crashes at runtime because
module.zis undefined.Environment
The affected runtime dependency in my bundle is
react-router, accessed through@ahooksjs/use-url-state.