_interopRequireWildcard cache incompatible with modules that export shared mutable reused objects (protobufjs)
Describe the bug
Note that I'm reporting this as "it works with tsc and not with swc", not because I think what protobufjs is doing makes any sense at all --
With static-module compilation using protobufjs-cli you'll basically get a number of (UMD) files that roughly look like this:
a.proto.js
const root = require('protobufjs');
root.A1 = {};
root.A2 = {};
module.exports = root;
b.proto.js
const root = require('protobufjs');
root.B1 = {};
root.B2 = {};
module.exports = root;
So you end up with require('a.proto.js') === require('b.proto.js').
Since _interopRequireWildcard uses a WeakMap as a cache which is going to compare keys by reference, it will cache the outputs of a.proto.js, but then return a.proto.js's exports when importing b.proto.js. Because tsc doesn't use a cache for __importStar, it doesn't have this problem.
I think that what protobufjs is doing is ridiculous, but it's technically a lib that breaks with swc.
Input code
import * as A from './a.proto.js';
import * as B from './b.proto.js';
A.A1.func();
A.A2.func();
// Crashes because B1 and B2 aren't on B, only A1 and A2 👇
B.B1.func();
B.B2.func();
Config
{
"test": ".*.tsx?$",
"exclude": ["node_modules", "/lib/", "/lib-types/", "typings", ".*\\.d\\.ts"],
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": true,
"dynamicImport": true
},
"target": "es2021",
"externalHelpers": true
},
"module": { "type": "commonjs" }
}
Playground link
No response
Expected behavior
Not sure what it should do, since the only guaranteed fix is to just not have the cache. It could compare the length of the keys and if it's different, recalculate the cache and return the combined object? Not sure it's really worth fixing for ridiculous things like this.
The cache could include the file name maybe?
Actual behavior
Returns a.proto.js's exports for all imports and crashes when trying to call B.B1.func()
Workaround
Use --wrap es6 with protobufjs-cli and then transpile that with swc too.
Version
1.2.210
Additional context
No response
Some possible solutions:
- use
import A = require('./a.proto.js');syntax instead - try other
importInteropoption
This issue has been automatically closed because it received no activity for a month and had no reproduction to investigate. If you think this was closed by accident, please leave a comment. If you are running into a similar issue, please open a new issue with a reproduction. Thank you.