-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TypeError when accessing exported member with "circular" dependency on barrel file #96
Comments
@magic-akari I'm a newbie when it comes to Rust, but if you can point me in the right direction, I'd be happy to try and implement a fix for this myself. |
You are right. This issue is complex. In fact, this plugin only handles export statements, leaving all import statements untouched in their original positions. Regarding the following code: export * from "a";
export * from "b"; It will be transformed into: import * as _a from "a";
Object.keys(_a).forEach(function(key) {
if (key === "default" || key === "__esModule") return;
if (Object.prototype.hasOwnProperty.call(exports, key)) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
return _a[key];
},
configurable: true
});
});
import * as _b from "b";
Object.keys(_b).forEach(function(key) {
if (key === "default" || key === "__esModule") return;
if (Object.prototype.hasOwnProperty.call(exports, key)) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
return _b[key];
},
configurable: true
});
}); The reason for this approach is to account for other import statements, ensuring that the order of import statements remains unchanged. However, import statements are hoisted, so the final result will show all import statements at the beginning, which means the translated require statements will be at the beginning as well. |
That's what I was afraid of when I was looking through the code earlier. Is that right? If so, it sounds like maybe it's not something that could be fixed by this plugin? |
I'm considering a new approach. For example: module.exports = magicCopyAndMakeMutable(exports); |
So the exports won't be mutable until the whole file has been executed? I'm not too familiar with the details of Jest mocking, but would |
I tried playing around with the Another approach I tried was adding function mutableDefineProperty(obj, prop, attributes) {
return Object.defineProperty(
obj,
prop,
Object.assign({}, {configurable: true, enumerable: true}, attributes)
)
} Then replaced all instances of: Object.defineProperty(exports, /* rest of the params */); with mutableDefineProperty(exports, /* rest of the params */); That got the Jest tests with Any thoughts on that approach? |
You can refer to the workaround for Jest mentioned here: #103 (comment) |
Issue
Note that
module.type
in the swc config is set tocommonjs
for this issue.When a member (in this case, a TS enum) is re-exported in a barrel file and a sub-dependency of the barrel file imports that enum through the barrel file and tries to access it, a TypeError is thrown:
This is due to how
swc_mut_cjs_exports
groups all therequire
calls at the top of the transpiled file and then adds the keys to theexports
object after all of thoserequire
../enumDep
exportsSomeEnum
, and./anotherDep
eventually importsSomeEnum
from thetask.js
barrel file. But since the keys for./enumDep
haven't been added toexports
by the time./anotherDep
isrequire
d, theSomeEnum
ends up beingundefined
.Reproduction
I've set up a small repo with the reproduction of this and the README has info on the structure:
https://github.com/wadjoh/swc_mut_cjs_exports_debug_ts_enum
This is the structure of the TS code that causes an error when the transpiled code is executed:
Potential Fix
When
swc_mut_cjs_exports
transpiles star exports, this issue can be avoided by adding the keys to theexports
object immediately after the associatedrequire
call:I have manually modified output code in the linked reproduction repo that works fine when executed: https://github.com/wadjoh/swc_mut_cjs_exports_debug_ts_enum/blob/main/results/fixed_output_with_plugin/task.js
The text was updated successfully, but these errors were encountered: