Skip to content
This repository has been archived by the owner on Apr 27, 2021. It is now read-only.

How convert to babel/traceur options list to defer to browser's features #9

Open
backspaces opened this issue Jun 25, 2015 · 12 comments
Assignees

Comments

@backspaces
Copy link

[We had a short twitter chat .. you mentioned it'd be good to have longer one.]

Both babel and traceur have two workflows: static & dynamic. Static transpiles the es6 to es5 before use, while dynamic uses in-browser transpilation.

Both modes have options to include/exclude features of the transpilers, mainly to defer to the browser if it has the given feature.

This issue is to use es-feature-tests to create the options file appropriate to the browser being used, to build the options file for babel/traceur to defer to the browser. This would primarily be useful in the dynamic workflow.

It need not be a direct part of the project/repo .. but simply to document how to convert from the es-feature-tests results to an options file which exclude options already available in the browser.

@getify
Copy link
Owner

getify commented Jun 25, 2015

Very interesting feature request. Can you by any chance give an example of such an options file? I haven't seen or heard of this before.

@getify getify self-assigned this Jun 25, 2015
@backspaces
Copy link
Author

Hi Kyle, sorry to be late. The TLDR is that babel and traceur both have options files that include the ability to ignore transpiling features. We can use es-feature-tests to dynamically build the appropriate features file for either babel or traceur

History:
Here's a somewhat obsolete script that sets traceur's options:
http://backspaces.net/temp/features/test.html

Open the console to see its results. It writes out the native es6 features and the resulting options object, then sets the traceur options object. Only tested on chrome. Very primitive but I wanted to see if it would work in principle.

The idea is that, running traceur dynamically .. i.e. in-browser compilation, the options object can be set to tell traceur to ignore features already supported in the browser. Polyfills already do that so not required for testing. I think!

Traceur's current object is discussed here:
https://github.com/google/traceur-compiler/wiki/Options-for-Compiling
Running "traceur" on the commandline prints out the options that can be set.

Babel has a similar approach:
https://babeljs.io/docs/usage/options/

I'm using babel via jspm which itself has a way to pass options to babel, see last line of:
https://babeljs.io/docs/setup/#jspm

So basically I think we can use es-feature-tests to build these option files for dynamic transpilation, deferring to the browser implementation if present.

@getify
Copy link
Owner

getify commented Jun 28, 2015

👍

@getify
Copy link
Owner

getify commented Aug 30, 2015

@backspaces have you tried out the --output=babel yet? Would love some feedback. Haven't finished the traceur yet, tho.

@backspaces
Copy link
Author

Alas, no .. I've gotten involved in a webgl mooc that's taking 150% of my time! :)

When it's over, I plan to revisit my current es6 workflow which currently is dead simple, dynamic jspm with no change beyond the initial config.

I am somewhat concerned about module and module loading. Not sure if the standard is converging, and judging from several friends using es6, they are not using modules.

One reason is that using es6 w/o modules is backward compatible .. just use <script> tags. And module loading (jspm, webpack) is just one more annoying tech to learn .. and bicker about which of them to use. Sigh.

Hope all is well!

@lgvo
Copy link

lgvo commented Sep 23, 2015

I'm looking for something like that but was thinking in using only for node.js and static transpile.

I have tried --output=babel and it seems great. But what I'm looking for is to eliminate what the runtime environment already have support from been transpiled.

For me a option to test all ES6 support and output only the whitelist wil be helpful, for backend I can use what iojs/node4 has support and transpile only the missing stufs.

Something like that:

var supports = require("es-feature-tests");

var mappings = {
    "es6.arrowFunctions": ["arrow"],
    "es6.blockScoping": ["letConst","letLoop","constLoop"],
    // .... all mappings
};

supports("all", function(results, timestamp) {

    var options = [];

    Object.getOwnPropertyNames(mappings).forEach(function(name) {

        var hasSupport = mappings[name].reduce(function(support, test) {
            return support && results[test]; 
        }, true);

        if (!hasSupport) {
            options.push(name);
        }
    });
    console.log(options);
});

I also see the benefit of the two options, for something like jspm would improve the workflow.
Something like that should work:

var supports = require("es-feature-tests"),
    testify = require("es-feature-tests/testify");

var requirements = testify
    .scan({dirs: '.', excludes: 'node_modules', recursive: true, output: 'babel'}).whitelist;

var mappings = { /* ... mappings */ };

supports("all", function(results, timestamp) {
    var options = [];
    requirements.forEach(function(name) {

        var hasSupport = mappings[name].reduce(function(support, test) {
            return support && results[test]; 
        }, true);

        if (!hasSupport) {
            options.push(name);
        }
    });
    console.log(options);
});

In my case (runtime iojs 3.3.1):

Testify output: (testify -R --dir=. --exclude=node_modules --output=babel)

{"whitelist":[
"es6.arrowFunctions",
"es6.blockScoping",
"es6.constants",
"es6.destructuring",
"es6.modules",
"es6.parameters.default",
"es6.parameters.rest",
"es6.properties.shorthand",
"es6.spec.templateLiterals",
"es6.spread",
"es6.templateLiterals"
]}

Support full ES6 code output:

[ 'es6.arrowFunctions',
  'es6.destructuring',
  'es6.modules',
  'es6.parameters.default',
  'es6.parameters.rest',
  'es6.regex.sticky',
  'es6.regex.unicode',
  'es6.spread',
  'es6.tailCall' ]

Only options the code need to work:

[ 'es6.arrowFunctions',
  'es6.destructuring',
  'es6.modules',
  'es6.parameters.default',
  'es6.parameters.rest',
  'es6.spread' ]

Nice work with the tool by the way, I already have what I need, but if you like I can work on some pull request.

Best regards.

@getify
Copy link
Owner

getify commented Sep 23, 2015

@igvo this is fantastic feedback. I'll try to come back and digest this ASAP and provide some thoughts. Thanks so much! :)

@backspaces
Copy link
Author

Yay! Just finishing a webgl mooc where I used all es6 via jspm/babel and
boy am I loving it. Also surprised how much of es6 is available in the
chrome console now. I can test my promises really easily, and use =>
functions .. all in console. As a CoffeeScript surviver, sure is nice to
have JS with a pretty face!

On Wed, Sep 23, 2015 at 3:36 PM, Kyle Simpson notifications@github.com
wrote:

@igvo this is fantastic feedback. I'll try to come back and digest this
ASAP and provide some thoughts. Thanks so much! :)


Reply to this email directly or view it on GitHub
#9 (comment)
.

@lgvo
Copy link

lgvo commented Sep 23, 2015

@getify I end up using blacklist instead of whitelist.
So maybe a option that print what the engine have support can help too.

@bahmutov
Copy link

I have not mapped all detected features to Babel plugins, only default parameters for now. But I have both these features tested and Babel running inside a ServiceWorker. This allows to intercept code and transpile it for missing features only. Source https://github.com/bahmutov/babel-service demo at https://babel-service-demo.herokuapp.com/ (Chrome, Chrome Canary, Opera, Firefox with flags)

@ErikBean
Copy link

This^! I am working on a project using Electron, so have control of what version chromium the client code runs on. This means that we only need to transpile for the es6/7 features that that version does not support natively, great use case for dynamic .babelrc generation. @bahmutov I cloned your babel-service repo, but it's a webpack bundle :'(. Does your code use an object like in a Babel 6 .babelrc? Or does it just internally generate a whitelist like this project does with the --output=babel option? If it uses the first approcah it could just be written to a file, that would be awesome! Seems like the issue of matching a whitelist to a set of plugins is the primary challenge.

@bahmutov
Copy link

bahmutov commented Jul 5, 2016

@ErikBean I would love to help and answer any questions, maybe open an issue at https://github.com/bahmutov/babel-service/issues ?

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

No branches or pull requests

5 participants