-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
[Bug]: Safari class fields implementation is buggy - ReferenceError: Can't find variable #14289
Comments
Hey @liamcmitchell-sc! We really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we're a limited number of volunteers, so it's possible this won't be addressed swiftly. If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack community that typically always has someone willing to help. You can sign-up here for an invite. |
also hit this - just wanted to say great repro steps and workaround @liamcmitchell-sc 🙌 |
We will need a bugfix plugin so when
We will need a new test in Experiments on this bugAnother affected example {
let a = [];
new class {
c = a[(0)];
}
} This one runs without let a = [42];
{
let a = [];
new class {
c = a[(0)];
}
} and this works as expected let a = [];
new class {
c = a[(0)];
} So the bug is that, when resolving referenced identifiers within field initializer ( So we don't have to apply the bug fix when
When |
Do plugins know if compiled code is run at the top level or bundled into functions?
The parenthesized expressions in my case are produced by Webpack Terser after all Babel transformations. Without knowing what transforms will happen after Babel, the fix would have to trigger if any variable is referenced. |
Good point, we should probably be more conservative and apply the fix even if the plugin is at the top level.
I'd consider this something to be fixed in terser, since it takes working code and produces non-working code. It's identical to how Terser has a |
I propose to fix this bug by wrapping class fields initializers in an IIFE if they contain any reference to a variable defined in the parent scope, and that reference is not nested within another function: let a = [];
{
let b = [];
new class {
x = a[0];
y = b[0];
z = () => b[0];
};
} becomes let a = [];
{
let b = [];
new class {
x = a[0];
y = (() => b[0])();
z = () => b[0];
};
} I don't think we should explicitly check for parentheses, because they are hard to predict in a transform. In some cases they are explicit, while in other cases they are implicitly printed by the generator (for example, when printing a multiplication between a number and a sum). Also, even if the class field currently does not contain parentheses they could be easily introduced by new transforms that transform an expression nested within the class field value. Also, we'll need tests to make sure that the bugfix plugin works with all our other class-related plugins. |
Quick note to say that the WebKit bug has been fixed and no longer reproduces in Safari 16, but of course the issue still applies in Safari 15. |
Just faced and fought this bug for 3 days. So it's not clear to me where should be fixed. In babel or in terser? |
One important note for the workaround, if you start to use private methods you'll also need to include If you start to use private methods in an environment that doesn't transform them but have applied the workaround to include
I would update the workaround to include both: {
presets: [
[
'@babel/preset-env',
{
include: [
// See https://github.com/babel/babel/issues/14289
'@babel/plugin-proposal-class-properties',
// Private methods cannot be used with the class properties transform, ensure they're transformed as well
'@babel/plugin-transform-private-methods'
],
},
]
],
} This is easy to see in the REPL. The following fails without the additional transform, but is compiled correctly with both transforms: class C {
#privateProp;
#method() {}
} |
Faced similar issue for below code snippet in Safari < 16 with error - "Reference error: Cant find variable t".
The variable Seeking insights into the transient nature of this error. Any ideas on what might have caused this intermittent failure? |
* Update public_class_fields for Safari Marks Safari 14-15 as having partial support for public class fields. While they do have a basic implementation, there is a critical bug which leads to exceptions in many cases. The exceptions are especially hard to identify/debug because they are resolved when dev-tools are open. The bug is resolved in Safari 16. References: - Safari bug: https://bugs.webkit.org/show_bug.cgi?id=236843 - `babel/babel` discussion regarding adding 'bugfix' behavior for this issue: babel/babel#14289 * Update javascript/classes.json Co-authored-by: Queen Vinyl Da.i'gyu-Kazotetsu <[email protected]> --------- Co-authored-by: Queen Vinyl Da.i'gyu-Kazotetsu <[email protected]>
This is to detect https://bugs.webkit.org/show_bug.cgi?id=236843, which affects Safari 15 and below. Discussion in babel/babel#14289
This is to detect https://bugs.webkit.org/show_bug.cgi?id=236843, which affects Safari 15 and below. Discussion in babel/babel#14289
This is to detect https://bugs.webkit.org/show_bug.cgi?id=236843, which affects Safari 15 and below. Discussion in babel/babel#14289
This is a workaround for https://bugs.webkit.org/show_bug.cgi?id=236843, and aims to resolve babel#14289. Pending: - acceptance of compat-table/compat-table#1892 - reviewing test failures
This is a workaround for https://bugs.webkit.org/show_bug.cgi?id=236843, and aims to resolve babel#14289. Pending: - acceptance of compat-table/compat-table#1892 - reviewing test failures
This is a workaround for https://bugs.webkit.org/show_bug.cgi?id=236843, and aims to resolve babel#14289. It adds the new compat-table check to the requirements for transform-class-properties, which means that transform will now apply for Safari < 16 (previously Safari < 14.5). It also introduces a bugfix transformation which can be used as an alternative to transform-class-properties on Safari 15. This bugfix transformations wraps potentially-affected initializers in an IIFE. A number of shortcuts are added to avoid transforming initializers which are guaranteed to be unaffected by the bug.
This is a workaround for https://bugs.webkit.org/show_bug.cgi?id=236843, and aims to resolve babel#14289. It adds the new compat-table check to the requirements for transform-class-properties, which means that transform will now apply for Safari < 16 (previously Safari < 14.5). It also introduces a bugfix transformation which can be used as an alternative to transform-class-properties on Safari 15. This bugfix transformations wraps potentially-affected initializers in an IIFE. A number of shortcuts are added to avoid transforming initializers which are guaranteed to be unaffected by the bug.
This is a workaround for https://bugs.webkit.org/show_bug.cgi?id=236843, and aims to resolve babel#14289. It adds the new compat-table check to the requirements for transform-class-properties, which means that transform will now apply for Safari < 16 (previously Safari < 14.5). It also introduces a bugfix transformation which can be used as an alternative to transform-class-properties on Safari 15. This bugfix transformations wraps potentially-affected initializers in an IIFE. A number of shortcuts are added to avoid transforming initializers which are guaranteed to be unaffected by the bug.
This is a workaround for https://bugs.webkit.org/show_bug.cgi?id=236843, and aims to resolve babel#14289. It adds the new compat-table check to the requirements for transform-class-properties, which means that transform will now apply for Safari < 16 (previously Safari < 14.5). It also introduces a bugfix transformation which can be used as an alternative to transform-class-properties on Safari 15. This bugfix transformations wraps potentially-affected initializers in an IIFE. A number of shortcuts are added to avoid transforming initializers which are guaranteed to be unaffected by the bug.
This is a workaround for https://bugs.webkit.org/show_bug.cgi?id=236843, and aims to resolve babel#14289. It adds the new compat-table check to the requirements for transform-class-properties, which means that transform will now apply for Safari < 16 (previously Safari < 14.5). It also introduces a bugfix transformation which can be used as an alternative to transform-class-properties on Safari 15. This bugfix transformations wraps potentially-affected initializers in an IIFE. A number of shortcuts are added to avoid transforming initializers which are guaranteed to be unaffected by the bug.
This is a workaround for https://bugs.webkit.org/show_bug.cgi?id=236843, and aims to resolve babel#14289. It adds the new compat-table check to the requirements for transform-class-properties, which means that transform will now apply for Safari < 16 (previously Safari < 14.5). It also introduces a bugfix transformation which can be used as an alternative to transform-class-properties on Safari 15. This bugfix transformations wraps potentially-affected initializers in an IIFE. A number of shortcuts are added to avoid transforming initializers which are guaranteed to be unaffected by the bug.
💻
How are you using Babel?
babel-loader (webpack)
Input code
This bug can be triggered by input code like the following, when compiled with webpack and a babel config with preset-env that targets latest Safari/iOS (class fields are not transformed).
Current and expected behavior
Extra parens in class fields cause ReferenceErrors in Safari, see webkit bug: https://bugs.webkit.org/show_bug.cgi?id=236843
Generated code will produce an error like "ReferenceError: Can't find variable a".
Until the webkit implementation is fixed, class fields should continue to be transpiled when targeting Safari/iOS.
Environment
@babel/core 7.17
@babel/preset-env 7.16.11
@babel/compat-data 7.16.8
webpack 5.38.1
Possible solution
Remove Safari and iOS from
proposal-class-properties
compat data:https://github.com/babel/babel/blob/v7.17.5/packages/babel-compat-data/data/plugins.json#L19-L29
Does this require updating the upstream compatibility data?
https://github.com/kangax/compat-table
Workaround
If anyone else experiences this issue, the easy fix is to force transformation of class properties in preset-env config:
The text was updated successfully, but these errors were encountered: