Skip to content
This repository has been archived by the owner on May 11, 2018. It is now read-only.

Discussion: useBuiltIns (usage only, not "entry" point method) #284

Closed
hzoo opened this issue Apr 13, 2017 · 6 comments
Closed

Discussion: useBuiltIns (usage only, not "entry" point method) #284

hzoo opened this issue Apr 13, 2017 · 6 comments

Comments

@hzoo
Copy link
Member

hzoo commented Apr 13, 2017

Reference: older issue #20
Reference: #84
https://twitter.com/left_pad/status/847911365645938690

Problem

How can we import the minimal amount of polyfills required for an app? import 'babel-polyfill' is wasteful: you may not use a certain built-in in your code and your supported environment may already natively support it.

After #241, we now have an option (in 2.0-alpha) that will individually add only the used polyfills at the top of each file.

Instance/Prototype Methods (not solved, but it's fine)

The way we handle this is to be conservative and be ok with some false positives because it would still be less than importing the whole polyfill. In the future we could be smarter about knowing whether a variable is a string/array or not via inferring types or with type annotations from TS/FLow.

We handle this case, but we doesn't know if arr is actually an array or not.

var a = "includes"; arr[a];

node_modules/Third party libraries

  • Assume/use libraries that would provide a version of their library that includes the polyfills
  • Don't support them (assume that the user doesn't know the polyfills that are required for their dependencies and use the "entry" option which is safer)
  • Actually run Babel on node_modules which may not be safe depending on the code
  • Run as a separate pass (slower?) only the plugin that adds requires/imports so it doesn't change the rest of the code (maybe need webpack to add these polyfills to the entry point).

Figure out a way to determine the polyfills required for a library programmatically

  • package.json specify polyfills usage

  • crazy: Create a database/registry similar to https://github.com/DefinitelyTyped/DefinitelyTyped or compat-table but around polyfill/syntax usage. This can be automated by just running the Babel plugin over each library to determine the array of polyfills required (don't need manual PRs). Then babel-preset-env can use this information to import the correct polyfill automatically.

  • For React: https://unpkg.com/[email protected]/

  • Run the "use-built-ins-plugin" which runs over all of React to find the usage of a polyfill and instead of overwriting the file, we modify the plugin to just return a list of potential polyfills.

  • Add this information to some db for each library version

  • When preset-env encounters a require/import of React, we check the package.json to know the version used and then import the correct polyfill before the library is loaded.

@stale
Copy link

stale bot commented Jun 13, 2017

This issue has been automatically marked as stale because it has not had recent activity 😴. It will be closed if no further activity occurs. Thank you for your contributions 👌!

@deepak
Copy link

deepak commented Jul 31, 2017

i like the idea of creating a polyfill registry.
but even for a legacy inherited codebase, i just want to find the list of polyfills.

If we can:

  1. parse js and use the AST to identify methods to polyfill
  2. run the javascript code on a mocked browser, like jsdom but for the whole browsers 😱 and identify polyfills we need

i think (1) is static analysis
and (2) is a kind of integration test, more like testing if a link in broken in an html by writing a spider :-)

i guess, can always write integration tests and run it on saucelabs or browserstack to identify broken code :-)

@Smolations
Copy link

Smolations commented Oct 17, 2017

The way we handle this is to be conservative and be ok with some false positives because it would still be less than importing the whole polyfill.

This is bound to happen given how dynamic JS can be, but being smart about how to tell babel not to use a polyfill when not needed becomes a priority. One option is to tell babel to exclude the file, but this is obviously undesirable as all es6 files need to be transpiled. Another option is to exclude the polyfill using the preset's exclude option, but this becomes a problem if the polyfill actually becomes necessary for code changes in the future. When working on a team of people, communicating that a change to the .babelrc may sometimes be required would be difficult to coordinate.

Since this would be a file-by-file issue, I would propose some sort of comment-disabling system, similar to eslint's /* eslint-disable */ system. The comment exists in the file itself, so if the polyfill ever becomes required for that file, it will be easy to see that the comment will need to be removed. Type annotations would make it easier for babel to figure out variable types, but not everyone uses TS/Flow. If these annotations could be inferred from a special comment and/or, when the variable is a param, jsdoc comments (e.g. @param {string} myParam) that would help close the gap for others.

Re: node_modules/Third party libraries: Don't support them (assume that the user doesn't know the polyfills that are required for their dependencies and use the "entry" option which is safer)

Yes! These, as far as my experience has been, are always pre-transpiled for wide support, and only sometimes provide a special, es6 version for folks who don't care about support. I would agree that babel (and the project dev) should only care about polyfills that would apply to the current application code and ignore third party libs. It has an ancillary benefit of saving on processing/speed as well.

crazy: Create a database/registry

I'm not sure this would solve the previous issue of babel being unable to figure out the type of a variable. I think any of the suggestions similar to this will also hit the same problem. I would still advocate for a better exclusion strategy than the complexity of how babel would be able to figure out types for the countless use cases in code.

@tomchentw
Copy link

I had a somehow unrelated question for babel-preset-env: Why babel-polyfill is preferred compared with babel-runtime when useBuiltIns is kicked in?

@mgol
Copy link

mgol commented Oct 18, 2017

@tomchentw It's not only preferred with babel-preset-env, babel-runtime has issues in general. It cannot polyfill instance methods, for example, so array.includes(element) will fail in older browsers.

@babel-bot
Copy link

This issue has been moved to babel/babel#6626.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants