Skip to content
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

Preset for env/targets #3476

Closed
wants to merge 1 commit into from

Conversation

Projects
None yet
@hzoo
Copy link
Member

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 Apr 21, 2016

@codecov-io

This comment has been minimized.

Copy link

commented Apr 21, 2016

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

This comment has been minimized.

Copy link
Member

commented Apr 22, 2016

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

This comment has been minimized.

Copy link
Member Author

commented Apr 22, 2016

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

@sindresorhus

This comment has been minimized.

Copy link
Member

commented Apr 22, 2016

@hzoo Only for Node.js yes.

@hzoo hzoo added the i: discussion label Apr 22, 2016

@milesj

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Apr 24, 2016

node.green also has tons of info.

@reconbot

This comment has been minimized.

Copy link

commented Apr 28, 2016

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.

@hzoo hzoo referenced this pull request May 5, 2016

Closed

Add as part of a env preset #12

@mrmckeb

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Member Author

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 referenced this pull request Jul 30, 2016

Merged

july-31 #1

9 of 9 tasks complete

@hzoo hzoo force-pushed the preset-env branch from 962b626 to ec63801 Aug 5, 2016

@zoontek

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Member Author

commented Aug 5, 2016

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

@ai

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Member Author

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

This comment has been minimized.

Copy link
Contributor

commented Aug 5, 2016

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

@milesj

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Member Author

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

This comment has been minimized.

Copy link

commented Aug 14, 2016

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

This comment has been minimized.

Copy link
Member

commented Aug 25, 2016

https://github.com/kangax/compat-table doesn't have raw data yet. There is an issue kangax/compat-table#785

@zoontek zoontek referenced this pull request Aug 30, 2016

Closed

Handle raw data generation #896

@hzoo hzoo referenced this pull request Sep 1, 2016

Closed

This is awesome #1

@hzoo

This comment has been minimized.

Copy link
Member Author

commented Sep 3, 2016

Probably better as a separate repo, so moving to https://github.com/babel/babel-preset-env

@sdkennedy

This comment has been minimized.

Copy link

commented Sep 3, 2016

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

This comment has been minimized.

Copy link
@baoti

baoti Sep 4, 2016

What is it?

@hzoo

This comment has been minimized.

Copy link
Member Author

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

This comment has been minimized.

Copy link
Member Author

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

This comment has been minimized.

Copy link
Contributor

commented Nov 2, 2016

@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

This comment has been minimized.

Copy link
Member Author

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

This comment has been minimized.

Copy link

commented Nov 2, 2016

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

@hzoo

This comment has been minimized.

Copy link
Member Author

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.