Skip to content

Preset for env/targets#3476

Closed
hzoo wants to merge 1 commit intomasterfrom
preset-env
Closed

Preset for env/targets#3476
hzoo wants to merge 1 commit intomasterfrom
preset-env

Conversation

@hzoo
Copy link
Copy Markdown
Member

@hzoo hzoo commented Apr 21, 2016

Moved to https://github.com/babel/babel-preset-env

Mostly for a discussion (no implementation atm)

This will most likely be maintained by the community (moved into another repo). I'm just doing this off of #3331 to get preset options. Also no actual implementation yet (need data).

Basic idea to be able to specify an environment/s so that babel wouldn't transform what is already implemented natively.

This can be useful given that the latest browsers/node have implemented a good amount of es2015 already unlike a few years ago, and there are currently numerous presets for each environment (babel-preset-node5, babel-preset-modern, etc). We are at the point where you might not need the es2015 preset at all (and we would like to see an automated solution).

TL;DR

{
  presets: [
    ["targets", {
      chrome: 50,
      node: 5
    }]
  ]
}

Also this isn't about dynamically doing this at runtime but just a similar configuration where an environment is mapped to a set of plugins beforehand.

EDIT: Another recent discussion https://gist.github.com/addyosmani/bb6e2939f943226e68e87396c4931040

Previous Discussions:

  • T272: Blacklist presets (created Dec 2014)
  • T631: Generate blacklist based on targets
  • T2842: environment awareness
  • and others: T462, T686, T1918
  • zloirock/core-js#188 different build for core-js that could be applied for babel-plugin-transform-runtime or polyfill based on environment.

Some other articles

How do we get the data?

Many people will probably think of using something like https://github.com/kangax/compat-table/. This would be great will we could use these resources and just create a mapping to transforms. Looking at https://github.com/Fyrd/caniuse it looks like it defers to kangax's table for es2015.

I don't think we can just run a single test since that doesn't actually mean the environment supports the whole feature/transform.

It could just be a list and we update it when necessary (with community input/help).

How do you specify this in Babel?

Targets

Could be a builtin config value like targets/environments:

Like what buble is doing: https://gitlab.com/Rich-Harris/buble/blob/master/src/support.js

// .babelrc
{
  // format here isn't too important for the discussion but the idea is being able to declare targets/environments
  "targets": [
    "chrome50",
    "node5"
  ]
}

Targets would specify plugins that are implemented already and could act like a blacklist against the plugins passed in.

Preset (most likely option)

https://github.com/babel/babel/blob/preset-env/packages/babel-preset-env/src/index.js in this PR although it doesn't do anything or has an data right now.

This would depend on something like logan's pr: #3331 which allows passing options to presets.

Even if this isn't a builtin feature like a targets key in .babelrc, it could at least be a preset with options that allow you to specify the environments you support.

We don't have to do this only for es2015 since some stage-x features are also in development. Could do another option if users want to test in a browser that has a feature behind a flag.

// .babelrc
{
  presets: [
    ["env", {
      loose: true. // allow passing other options down?
      chrome: 50,
      node: 5,
    }]
  ]
}

Other?

@hzoo hzoo force-pushed the preset-env branch 2 times, most recently from b2c6cb1 to 962b626 Compare April 21, 2016 19:22
@codecov-io
Copy link
Copy Markdown

Current coverage is 85.54%

Merging #3476 into master will decrease coverage by -0.27% as of fd73893

@@            master   #3476   diff @@
======================================
  Files          197     197       
  Stmts        12227   12244    +17
  Branches      2521    2530     +9
  Methods          0       0       
======================================
- Hit          10493   10474    -19
- Partial        522     552    +30
- Missed        1212    1218     +6

Review entire Coverage Diff as of fd73893

Powered by Codecov. Updated on successful CI builds.

@sindresorhus
Copy link
Copy Markdown
Member

Would be super nice if it could just adhere to what's in the engines field in package.json. That way you wouldn't have to specify anything manually.

@hzoo
Copy link
Copy Markdown
Member Author

hzoo commented Apr 22, 2016

@sindresorhus is that only for node? Could def work as a default if it's there.

@sindresorhus
Copy link
Copy Markdown
Member

@hzoo Only for Node.js yes.

@milesj
Copy link
Copy Markdown

milesj commented Apr 23, 2016

I'd like to chime in here as I was planning to implement this feature until I noticed this issue. I've pretty much got it all planned out, just need to actually build it. Basically it would go:

  1. Each package would have a mapping in package.json of each browser and or target version in which this feature was released natively. For example, arrow functions (https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-arrow-functions) would have the following added to its package.json.
"browsers": {
  "chrome": 45,
  "firefox": 22,
  "ie": false,
  "edge": true,
  "safari": false,
  "opera": 33,
}

Based on the following links:

When babel is ran, it would work similar to autoprefixer, in which you can target individual browser versions, or you can do "last 3 versions", etc. It would then validate the browser version in each package, and determine whether to run the transformer or not. If a browser version is false or undefined, then the feature is not supported natively. If the browser version is true, then it does support it, but we do not know which version (mainly Edge).

  1. Where to get all the data? This is easy as each vendor has a status page:

We also have kangax and caniuse.

  1. What about mobile? Well, mobile is super tricky, as mobile chrome and desktop chrome are not always in sync and does not always support the same version, etc. I honestly don't have an answer to this besides building separate desktop and mobile bundles, in which all the transformers are ran for mobile. Open to suggestion on this one.

  2. This would also work nicely with presets, for example: babel-preset-chrome-latest, etc.

I would really love this feature, as I currently work on internal tools at my company, in which we only have to support Chrome 40+. This feature would lower our filesize and tech debt considerably.

This will be especially important since V8 has almost 100% ES2015 support: http://v8project.blogspot.se/2016/04/v8-release-51.html

@sotojuan
Copy link
Copy Markdown

node.green also has tons of info.

@hzoo hzoo added the PR: New Feature 🚀 A type of pull request used for our changelog categories label Apr 25, 2016
@reconbot
Copy link
Copy Markdown

As a node module author who wants to write for node 5 but has to support 0.10-6 and electron and NWJS. I support these efforts and hope they include non browsers too.

@mrmckeb
Copy link
Copy Markdown

mrmckeb commented Jun 12, 2016

It might be worth adding a the ability to just set latest for browsers, or perhaps -2 for "latest - 2 versions". This allows us to not worry about updating this setting on a regular basis, but still set some kind of definition around browser support.

Most browsers are evergreen now, so depending on your customer base, adding support for anything more than latest may just be a matter of allowing people a little time to get the latest update (I realise this may be different in the corporate world or other demographics).

Overall I think this feature will be great, it'll cut down on the size of exported code and will make pages more performant (no feature detection in some cases, less polyfills).

@hzoo
Copy link
Copy Markdown
Member Author

hzoo commented Jun 13, 2016

@mrmckeb for sure that would be a useful feature (given this is basically autoprefixer for babel), just need to update when new browsers come out

@hzoo hzoo mentioned this pull request Jul 30, 2016
9 tasks
@zoontek
Copy link
Copy Markdown

zoontek commented Aug 5, 2016

What about using https://github.com/ai/browserslist instead of specifying each browser version?

// .babelrc
{
  presets: [
    ["latest", {
      browsers: 'last 1 version, > 10%',
      browsers: ['last 1 version', '> 10%'], // alternative proposal
      node: 5
    }]
  ]
}

@hzoo
Copy link
Copy Markdown
Member Author

hzoo commented Aug 5, 2016

Yeah that sounds great - cc @ai if you have any tips or can help with this effort

@ai
Copy link
Copy Markdown
Contributor

ai commented Aug 5, 2016

@hzoo sure, Autoprefixer, cssnext and Babel will take same browsers from browserslist config. Browserslist API is simple. It load config automatically — just send file path to path option.

@hzoo
Copy link
Copy Markdown
Member Author

hzoo commented Aug 5, 2016

Yeah Babel is a bit different since we will also need other js environments like node, electron, etc. I think we can start with browsers as a proof of concept though since not sure how we want to do it.

@ai
Copy link
Copy Markdown
Contributor

ai commented Aug 5, 2016

I could add Electron and other env’s support to browserslist.

@milesj
Copy link
Copy Markdown

milesj commented Aug 5, 2016

Good thing you guys pinged this as I was itching to try it out. Has any work been done on this yet (besides this PR)?

@hzoo
Copy link
Copy Markdown
Member Author

hzoo commented Aug 5, 2016

Not that I know of? If anyone knows about anything please send a link (if it makes it easier to contribute we can move this to another repo and then merge it in afterwards)

Sorry, was busy doing other stuff (also merge preset options so this will actually work) but would like to start if we have a better idea of how it will work - it sounds like we can break it down into

  • what should the configuration options look like? Just an key with an array?
{
  presets: [
    ["env", {
      browsers: ['last 1 version', '> 10%']
    }]
  ]
}
  • How can we automatically get the data from @kangax tables, caniuse (which doesn't seem to actually have much js support in it)
    • I don't know how easy that is, so just make it easy to add the data manually since it's not going to change per version
  • How to map the data ^ to the actual babel transforms
  • Simple function to do least common denominator of transforms
  • an option to specify what target of javascript (es2015,etc, or if stage-3, etc)

Other Features

  • other cool things like using "engines" in package.json for node, etc

@jakepusateri
Copy link
Copy Markdown

I built something like this with auto-babel. It's currently working for node, and I had previously used sauce labs to run tests for browser support. I haven't updated it to work with babel 6 yet. I found the kangax raw data unsuitable for browserslist matching and caniuse missing JS feature support completely.

@chicoxyzzy
Copy link
Copy Markdown
Member

@hzoo
Copy link
Copy Markdown
Member Author

hzoo commented Sep 3, 2016

@sdkennedy
Copy link
Copy Markdown

I just stumbled across this post. I've also been working on a preset with this support.
https://github.com/sdkennedy/babel-preset-target

let loose = false;
let modules = true;
if (opts !== undefined){
>>>>>>> 56a3ede... babel-preset-env:packages/babel-preset-es2015/index.js
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is it?

@hzoo
Copy link
Copy Markdown
Member Author

hzoo commented Sep 6, 2016

Ok actually moving this PR to https://github.com/babel/babel-preset-env (when it's more stable we can add it back). Will need to transfer the comments we have here over there (and if anyone wants to add issues feel free)

Sounds like it would be good to combine efforts with @jakepusateri's https://github.com/jakepusateri/auto-babel that has auto node support and @sdkennedy's work on https://github.com/sdkennedy/babel-preset-target

@hzoo
Copy link
Copy Markdown
Member Author

hzoo commented Sep 24, 2016

So https://github.com/babel/babel-preset-env has a basic implementation now - 0.0.1.

Data is probably wrong but that can always be updated

@graingert
Copy link
Copy Markdown
Contributor

@hzoo This rocks, I used to use both babel-preset-modern-browsers and babel-preset-modern-node and it looks like this could replace both. Thanks!

@hzoo
Copy link
Copy Markdown
Member Author

hzoo commented Nov 2, 2016

We'd appreciate the help on preset-env to make it more robust but of course feel free to continue working on other presets as well! Hopefully we can work together on this since there seems to be a lot of edge cases to handle

cc @christophehurpeau @michaelcontento @jakepusateri

@michaelcontento
Copy link
Copy Markdown

babel-preset-modern-node has now been deprecated in favor of this. Great work and keep on rockin! 👍

@hzoo
Copy link
Copy Markdown
Member Author

hzoo commented Dec 12, 2016

Just FYI https://github.com/babel/babel-preset-env is 1.0 now! Has a lot of new stuff

  • electron,
  • auto node based on process
  • can modify polyfills based on env
  • debug mode (log out plugins used)
  • etc

@hzoo hzoo mentioned this pull request Oct 5, 2017
@lock lock Bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Oct 6, 2019
@lock lock Bot locked as resolved and limited conversation to collaborators Oct 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

i: discussion outdated A closed issue/PR that is archived due to age. Recommended to make a new issue PR: New Feature 🚀 A type of pull request used for our changelog categories

Projects

None yet

Development

Successfully merging this pull request may close these issues.