-
-
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
Polyfill Checker for Library Projects #8089
Comments
Hey @KevinAst! We really appreciate you taking the time to report an issue. The collaborators If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack |
I agree that polyfills should be done once by the consumer at the app level, and if you keep following the logic, all standards-based transpilation should really happen at the app level. I'm not sure I would want to bloat my packages with runtime checks though, considering how complex it is and the system should throw a native error anyway. If you did have runtime polyfill checking, it should only cover features not natively supported under your package engines and browserslist config, and of those features, only ones that are used in your package. A consumer might only import and use one function from the package that runs fine without polyfills, yet the polyfill checks would presumably scan the whole package and get upset about a polyfill missing for an unused API. You could use something like invariant so the runtime checks only appear in a dev environment. What would be awesome is a build-time report, that can be used to auto gen documentation. In my package readmes I try to manually maintain a recommended polyfills list in an environment support section, like this. As a side note, I wonder if a new dev tool would help the problem of inexperienced developers not being able to recognise certain errors as meaning something should be polyfilled. It could regex the error (i.e. fetch being undefined) and make suggestions. Not sure where it would live though, maybe as a browser extension. |
Thanks for your insight @jaydenseric. In regard to bloat of the library package, my assumption was that the overhead of polyfill checking would be very lean (both in size and speed) because polyfill resolution is not addressed. Just because it is potentially complex (i.e. involved) does not necessarily correlate to bloat. With that said, I would defer to someone with more familiarity of the internals. My goal was to adhere to the documented alternative recommendation in the most convenient and complete way (i.e. babel is "in the know"). The nice thing about this feature request is the complexity is encapsulated within babel's knowledge base. In regard to the native errors emitted from polyfill issues, these can very often be very obscure - even to seasoned developers. The goal would be to make this more fool-proof, identifying both the needed polyfill and the package requiring it. As an example of obscurity, the following error is emitted in an android/expo JS engine due to the usage of a "for of" loop ... Yikes!
In regard to a consumer not needing all the polyfills due to partial usage of the package, I see your point, however it really depends on the library - some would be more susceptible to partial usage than others. Taking this mindset a bit further, you would need to document required polyfills on a function-by-function basis, which seems a bit of an overkill to me. I agree that a documentation build-time report would be a very nice feature. I like what you are doing in this regard - within your documentation. In essence, both a run-time JS checker and built-time report are very close in nature - they are identifying polyfills required for a given library package. |
@KevinAst This sounds like a nice idea. We don't want all of our libraries to be providing their own polyfills when they may or may not be needed, so having a machine parsable output that identifies the ES feature dependencies would be ideal. Then when one is doing an app build, the ES feature dependencies could be included and the appropriate polyfills could be included for the target engine or output as documentation, etc. |
The following individuals contributed to the Library Polyfill Discussion which drove the W3C Polyfill Advice for Library Authors and therefore may have an interest in this feature request. Your insight is greatly appreciated. What say you: @nolanlawson @triblondon @hzoo @Rich-Harris @Kovensky @palmerj3 @bfred-it @TheLarkInn @reconbot @Draggha @tomccabe @georgezzhang @sokra @dmethvin @jacobangel |
I think optional lightweight runtime checks (to be run during module load in my usal cases) would be great. I think it would lower support tickets to have clear errors and making that easier is a win. |
This doesn't seem like a Babel feature to me, there could be code outside Babel that is using something that requires a polyfill. The solution @reconbot proposes sounds workable to me. It could have a big list of features that may need polyfilling and just insert stubs that say "Whoops you need the polyfill for X" for any that aren't defined in the current environment. |
Well other than having the browsers natively implement this sort of thing (which would be great but not very likely), then I think Babel IS the next best place to implement this. Since it is parsing and transforming the code, it knows what is needed. And even if you were going to use some sort of runtime checks, it seems like Babel would be the one to introduce them to the start up of the code. You certainly wouldn't want to check every time you want to use a promise or ES-feature, ideally just do it once on load. When @KevinAst was initially thinking about it, he came to the conclusion that Babel is the tool that has the necessary knowledge to know what is needed. So whether it is part of babel core or some sort of pluggin, it seems like a good place to do this. I can't see building a whole new tool to do this when it could be built on babel. |
@dmethvin - I'm not sure I understand your response. I thought that @reconbot was affirming the overall premise of this feature request. If a developer is running their library package through babel, what code would it not see? As @jeffbski highlights, my conclusion was that babel is a natural driver for this process because it is knowledgeable of the constructs used in the package, and can selectively apply these run-time checks (through a machine generated start-up function) taking the burden away from the developer manually checking this very tedious process. |
@KevinAst I assumed that someone was not running all their code through Babel. If the checks are runtime checks, why not just introduce stubs for any feature not present that will give good error messages? That way you're covered whether all the code goes through Babel or not. |
@dmethvin - I'm not sure where these run-time checks would come from. Are you suggesting something natively built-in to the JS engine would verify a es2015+ feature is supported before it executes? If so ...
Forgive me if I am misinterpreting your idea. I may be missing something rudimentary. With the current state of things, as a library developer using es2015+ features:
Thoughts? |
I believe @dmethvin is suggesting that the developer do it, while @KevinAst you are suggesting a plugin do it. I think it's hard to know what I think a way to generate a specific list of features that are used and need to be polyfilled for your target |
I'll describe the feature as succinctly as possible, if I got it wrong please replace with a better short paragraph.
|
@dmethvin - I think that sounds correct :-) @reconbot - Yes. I think we are saying the same thing. The only clarification I would make is: Because a library may run under any target env (under the privy of the client app), a run-time check alleviates any need for the library to specify a target env (i.e. the target is the JS engine that is executing at run-time). |
Is this still a thing with Using bellow babel dependencies in a
And when an app will use What would be a desired Thanks! |
Feature Request: Polyfill Checker for Library Projects
Feature Request ...
I would like to propose a new babel feature that would greatly simplify polyfill verification for library projects. This enhancement would emit a lightweight JavaScript executable that verifies the running JS engine supports the language constructs "used" in a specific library package.
Background ...
Library developers that use es2015+ constructs, face an issue as to whether they should polyfill their library or not (please refer to the W3C Polyfill Findings specifically Advice for library authors).
Personally, I am in the alternative camp that project libraries should NOT polyfill. Rather, that is the responsibility of the client app. My reasoning for this is:
As a library author you have absolutely NO idea what your target env is going to be. One can attempt to apply polyfills to a library (with "non polluting" due diligence), however that is from a perspective of potential problematic targets. If an antiquated target is run, there will still be issues.
In reality, we want babel to free us from this burden, and it is becoming better and better at doing this!
From an app perspective, applying the needed polyfills has become a fairly simple and straightforward process, with the advent of the "babel-polyfill" import, in conjunction with babel's "babel-preset-env" configured with useBuiltins:"usage".
This alternative tactic requires the library to:
Both of these tasks are tedious when done manually. It occurred to me that babel could assist in both of these tasks.
Feature Requirements ...
The requirements for this enhancement are:
Provide a run-time hook that verifies the language constructs found in the library project are available in the executing JavaScript engine. If not, return a summation (nicely formatted for human consumption) which can be used either in warning logs or an error processor.
In essence this requires some persistence as to what language constructs are "in use" for the library in question.
Accomplish this in a very lightweight way (both in deployment size and execution speed) so as to have minimal impact on the library package.
Proposed Solution ...
Due to both the "run-time hook" and "persistence" requirements, one solution would be for babel to support an option to emit a machine-generated "checker" file (ultimately included in the library project) that would perform these checks at run-time.
The contents of this "checker" would presumably be similar to what logically is accomplished by "babel-polyfill", except:
instead of resolving issues by applying needed polyfills, it merely summarizes and reports violations back to the invoker
it would only check the constructs that are in-use by the project library code (similar to how the useBuiltins:"usage" option operates)
As a result, this solution is very light-weight, and can be included in the library project without penalty. In essence it doesn't have to include the needed polyfills - it merely performs the conditional checks.
The babel option could be something like
genPolyfillChecker
where two items are specified:libName
: identifying the project's library name - for human consumption (in the the formatted messages), andoutputFile
: the emitted machine-generated "checker" fileThis generated PolyfillChecker
outputFile
would be included at the start of the library project's expansion, and could also be used as the genesis of any library documentation highlighting the required environment.Your consideration is greatly appreciated.
Thoughts?
The text was updated successfully, but these errors were encountered: