-
Notifications
You must be signed in to change notification settings - Fork 4.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
Published NPM package silently depend on the 'regeneratorRuntime' global #13890
Comments
Related PR where we changed how we transpile packages: #9643. Just noting that |
Yes, I looked at that PR before filing, because I remember that some discussion about this already happened. When Gutenberg runs in the WordPress environment as a plugin, there is the
That's great, then we need to just enable the |
We also have this note left in all transpiled packages: This package assumes that your code will run in an ES2015+ environment. If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using core-js or @babel/polyfill will add support for these methods. Learn more about it in Babel docs. Should it be expanded instead to include the note about |
The trouble is that
Currently, published NPM packages import the helpers from import _objectSpread from "@babel/runtime/helpers/esm/objectSpread";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; and they declare a dependency on The scripts intended to be loaded by WordPress, the ones in If we enabled The best solution is therefore to declare |
One option I've seen some packages take is to include the untranspiled sources in the npm package (in addition to the regular transpiled code), and leave it to the consumer to use them at their own risk. It's not in any way the recommended usage, but it's there if you really want to do it, and there are no guarantees that it will never break should the project opt for a different Babel config. I think that approach could work particularly well in our scenario, since the Calypso and Gutenberg teams work so closely together, and could communicate in anticipation of any eventual breaking changes. If anyone outside of Automattic wants to rely on the sources they could too, but again, it would come with no guarantees. This approach would allow for a single, holistic transpilation, which would make it easier to avoid duplicated code and hard-to-find runtime bugs like this one. |
Actually, from https://unpkg.com/@wordpress/api-fetch@2.2.8/src/ this already appears to be the case. @jsnajdr What do you think of Calypso switching to consume the sources instead? |
In the majority of cases, we add an entry point for React Native which is for the "react-native": "src/index", See also in: https://unpkg.com/@wordpress/api-fetch@2.2.8/package.json If there is also a way to mark it explicitly in
Let's explore it. I will discuss it with @aduth to ensure it doesn't conflict with anything done previously. I can see |
Mostly reiterating things already mentioned, but for my own sake in organizing my thoughts:
So, I think the prior suggestion to only assume a regenerator as part of WordPress' specific build would be fine. I'd guess as far as actual changes, this includes removing the following lines from
(The first of these is confusing, but it's already the default setting) And secondly, adding something in the root I too am curious toward some of the points described in the original comment and I think illustrated by the misunderstanding described in my first point here about how specifically |
I was thinking about the same approach the other day. I even tried something slightly similar in the past in #9275 but I'm sure making it external would be more accurate in this case. |
Yes, that should work very well :)
If the polyfill import import '@babel/polyfill'; is left untransformed, it will always include the regenerator runtime, as well as the complete suite of JS polyfills from CoreJS. It's the
This line should stay. If it was set to
to
That opens the door for a polyfill that doesn't pollute the global namespace. But CoreJS polyfills always do both: modify the globals and provide importable exports. We'd have to use the But we don't want to do anything like that. We ship code that uses the It's only the expectation that the |
It was mentioned for removal only because the default is |
@sgomes That would be optimal as it potentially produces the most optimized code. But I don't like the following quote at all 😄
The published Is there really something that qualifies as an "undocumented API" that's comprehensible only to insiders? I only know about the slightly unusual way to transpile JSX (with |
Oh yes, I misunderstood that. What I really wanted to say is "this value ( |
It's not so much an undocumented API as an implicit one, in the form of Babel configurations; what JS features (and potentially what version of them) we're enabling. For example, class field declarations, private fields, etc. If at some point Gutenberg decides to add support for a newer syntax feature and make use of it in its code, every consumer of its sources will have to add that support too. I was suggesting that it would be easier to coordinate such changes inside Automattic, so as to avoid breakage. Otherwise, if Gutenberg would like to treat all clients equally and support building from source, then it would have to start treating its sources as an interface unto itself and view them as an officially supported product, with all the versioning requirements that would entail. Adding support for a new JS feature would be a major version change, for example. |
Related pull request: #14130 |
Discussed in Slack yesterday with @swissspidy (link requires registration): https://wordpress.slack.com/archives/C02QB2JS7/p1556142662462000 While this is fixed in the code, some packages still need to be published for it to be reflected ( Remaining task: Audit and publish packages which would have been impacted by this fix and have not been published since it was merged. |
I double checked the latest version of and it looks good. I also enforced publishing all packages last time I did major/minor version bump. |
Some published packages, e.g.,
@wordpress/api-fetch
, use async/await internally and the published transpiled sources (inbuild
orbuild-module
) therefore depend on theregeneratorRuntime
global.When imported into an app that's transpiled to a target that supports async/await natively, there is suddenly no one who would provide the
regeneratorRuntime
global and the app starts crashing. Even if the app containsimport '@babel/polyfill'
, the preset-env plugin won't include the regenerator runtime, because it's not needed by the transpilation target.This started happening in Calypso recently:
Possible solution:
The root cause of the issue is that the published package depends on something that it doesn't declare as NPM dependency. The dependency is silent and implicit.
Using
regenerator: true
flag in thetransform-runtime
plugin would convert the global reference into an import statement:Then the NPM package would have to declare a
@babel/runtime
dependency inpackage.json
. That makes the existing dependency explicit rather than adding a new one.Using a transpiled code in an environment that doesn't need it is still suboptimal, but at least not broken. Shipping untranspiled code in NPM packages is AFAIK still an active research area in the JS community rather that something we can use today 🙂
The text was updated successfully, but these errors were encountered: