-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Runtime error (edge case) due to __publicField() substitution #885
Comments
(This is to workaround a bug in esbuild: evanw/esbuild#885)
Thanks for the detailed report. I think this hasn't come up before because TypeScript forbids doing this entirely (doing this is a compile error). It should be reasonably straightforward to make this substitution though. I'll fix this in the next release. |
Thanks, @evanw. PS. You wouldn’t believe the hijinks some of us old-school ActionScripters get up to given half a chance ;) |
Somewhat related (I think), I've just come across another situation where this
The original JS code emitted by TypeScript looks like this (and original TS code here for reference): let MemMappedComponent = class MemMappedComponent extends AComponent {
constructor(sparse, dense, opts) {
opts = {
size: 1,
byteOffset: 0,
...opts,
};
const size = opts.size;
const stride = opts.stride || size;
super(opts.id, sparse, dense, opts.buf
? typedArray(opts.type, opts.buf, opts.byteOffset, dense.length * stride)
: typedArray(opts.type, dense.length * stride));
this.type = opts.type;
this.size = size;
this.stride = stride;
this.default = opts.default;
this.cache = opts.cache;
}
...
} This code works absolutely fine, however when serving the module via Skypack (which transpiles everything using esbuild), the ctor gets rewritten and then fails (as in the case above) at the first invocation of let MemMappedComponent = class MemMappedComponent2 extends AComponent {
constructor(sparse, dense, opts) {
__publicField(this, "type");
__publicField(this, "size");
__publicField(this, "stride");
__publicField(this, "cache");
opts = {
size: 1,
byteOffset: 0,
...opts
};
const size = opts.size;
const stride = opts.stride || size;
super(opts.id, sparse, dense, opts.buf ? typedArray(opts.type, opts.buf, opts.byteOffset, dense.length * stride) : typedArray(opts.type, dense.length * stride));
this.type = opts.type;
this.size = size;
this.stride = stride;
this.default = opts.default;
this.cache = opts.cache;
} Would it maybe be possible to check if the ctor contains a |
I can only reproduce this in very old versions of esbuild but not with newer versions. A problem like this was fixed in version 0.8.33 which was released last January, and I can't reproduce your problem in esbuild version 0.8.33 or newer. Which version of esbuild are you using? |
Thanks @evanw - that's great to know and helps me to re-address this to the right people. I don't know which version of your beautiful tool is used, since I only encounter the issue when trying to serve the module/package via the Skypack CDN (cc @FredKSchott), e.g. via: |
Summary
When a class…
…code bundled using esbuild crashes when the aforementioned property of the public field is accessed.
To reproduce
(In a
"type": "module"
node project.)(Minimum reproducible listing shown. See actual class for use case.)
Run the unbundled version (
node index.js
) and verify that it works (no errors; outputs===
).Bundle it using esbuild:
node test/index.js
) and verify that it crashes with an error similar to:QueryOperators.STRICT_EQUALS
was replaced with__publicField(QueryOperators, "STRICT_EQUALS", "===")
and thus an attempt to access it directly fails. Also note that if you remove the static getter, the substitution (and thus, the error) do not occur.Source of generated bundle follows:
Possible solution
When this substitution is detected, have all references to
this
in any objects rewritten to use the class name instead. (Not sure if this approach will have any side-effects in other parts of the generated code as I’m not familiar with the esbuild codebase).e.g., if the generated code included the following
__publicField()
call instead, it would work:Workaround
Until this bug is fixed, don’t refer to class fields using
this
in code you want to compile using esbuild. Use the class name instead. (Of course, you are more limited when it comes to third-party libraries.)The text was updated successfully, but these errors were encountered: