Hi,
I stumbled over the following issue which, while easy to resolve in many ways on the app dev side, I thought I might report - just in case.
It is triggered when all of the following are true:
- The module has a default export and at least one named export.
- The default export resolves to a value built from
Object.assign(Object.create(null), { ... }).
- Export collapsing is active (default behavior unless
noExportCollapse is enabled).
The stack trace pointed to
node_modules/babel-plugin-transform-modules-ui5/dist/modules/helpers/exports.js:77
But could be traced back to actually being a result of:
export function getPropertiesOfObjectAssignOrExtendHelper(
node,
blockScopeNode
) {
// Check all the args and recursively try to get props of identifiers (although they may be imported)
return flatten(
node.arguments.map((arg) => {
if (t.isObjectExpression(arg)) {
return arg.properties;
}
if (t.isIdentifier(arg)) {
// Recursive, although props will be empty if arg is an imported object
return getOtherPropertiesOfIdentifier(blockScopeNode, arg.name);
}
return []; // possible fix
})
).filter(Boolean); // possible fix
}
In here, the Object.create(null) of Object.assign(Object.create(null), { ... }) seems to add an undefined entry which later on fails in exports.js during:
if (!defaultExportProperty.key) {
continue;
}
Quick Repro
const babel = require("@babel/core");
const plugin = require("babel-plugin-transform-modules-ui5");
const cases = [
[
"withAsConst",
"const test=Object.assign(Object.create(null),{a:1}); export const TEST_CONSTANT='test' as const; export default test;",
],
[
"withoutAsConst",
"const test=Object.assign(Object.create(null),{a:1}); export const TEST_CONSTANT='test'; export default test;",
],
[
"typeLiteralAnnotation",
"const test=Object.assign(Object.create(null),{a:1}); export const TEST_CONSTANT:'test'='test'; export default test;",
],
["noNamedExport", "const test=Object.assign(Object.create(null),{a:1}); export default test;"],
[
"safeObjectAssign",
"const test=Object.assign({}, {a:1}); export const TEST_CONSTANT='test' as const; export default test;",
],
[
"twoStepCreateAssign",
"const test=Object.create(null); Object.assign(test,{a:1}); export const TEST_CONSTANT='test' as const; export default test;",
],
];
for (const [name, code] of cases) {
try {
babel.transformSync(code, {
filename: `${name}.ts`,
plugins: [plugin],
parserOpts: { plugins: ["typescript"] },
});
console.log(`${name}: OK`);
} catch (error) {
console.log(`${name}: FAIL -> ${String(error.message).split("\n")[0]}`);
}
}
One remark on contribution: I ran into several issues on windows in plenty of places in this repo, so I stopped bothering for now. I initially wanted to add a PR as well, as it is a seemingly small change/fix. But I also didn't want to overhaul half the repository just to get things working. I'm open though, maybe it was my mistake/error after all and maybe this isn't even a real issue that needs fixing. So an issue might even be the better way to go in the end. :)
BR
Hi,
I stumbled over the following issue which, while easy to resolve in many ways on the app dev side, I thought I might report - just in case.
It is triggered when all of the following are true:
Object.assign(Object.create(null), { ... }).noExportCollapseis enabled).The stack trace pointed to
node_modules/babel-plugin-transform-modules-ui5/dist/modules/helpers/exports.js:77But could be traced back to actually being a result of:
In here, the
Object.create(null)ofObject.assign(Object.create(null), { ... })seems to add an undefined entry which later on fails inexports.jsduring:Quick Repro
One remark on contribution: I ran into several issues on windows in plenty of places in this repo, so I stopped bothering for now. I initially wanted to add a PR as well, as it is a seemingly small change/fix. But I also didn't want to overhaul half the repository just to get things working. I'm open though, maybe it was my mistake/error after all and maybe this isn't even a real issue that needs fixing. So an issue might even be the better way to go in the end. :)
BR