javascriptecmascript-6babeljsgulp-babel

gulp-babel with babel-preset-env ignores browserslist


I'm trying to transpile some ES2015 code with Babel using gulp-babel but Babel seems to ignore my browserslist. Babel transpiles some modern features, but not all that would be needed to target the specified browser.

In my minimal example I use Element.remove() and target IE 9. Then, as IE 9 doesn't support that feature, I would expect Babel to transpile that line to something like Element.parentNode.removeChild(Element). But that doesn't happen and instead my Element.remove() line is unchanged.

The results don't change if I enter my browserslist in a .browserslistrc file or just remove my browserslist completely.

As this is my first attempt at transpiling code, I guess that I could just be mistaken as to what Babel actually should do.

Minimal example

In my test folder I have a package.json

{
    "name": "test",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "@babel/core": "^7.0.0-beta.51",
        "@babel/preset-env": "^7.0.0-beta.51",
        "gulp": "^3.9.1",
        "gulp-babel": "^8.0.0-beta.2"
    },
    "browserslist": "IE 9"
}

and a gulpfile.js

const gulp = require('gulp'),
    babel = require('gulp-babel');

gulp.task('js', function() {
    return gulp.src('src/script.js')
        .pipe(babel({
            presets: ['@babel/preset-env']
        }))
        .pipe(gulp.dest('dist'));
});

The ES6 file script.js in the "src" folder is

window.addEventListener('load', () => {
    const myId = 'test';
    const myDiv = document.getElementById(`${myId}`);
    myDiv.remove();
});

which Babel (through the Gulp task js) transpiles to another script.js (in the "dist" folder)

"use strict";
window.addEventListener('load', function() {
    var myId = 'test';
    var myDiv = document.getElementById("".concat(myId));
    myDiv.remove();
});

So, the arrow function is replaced by a normal function, const is changed to var and the template literal is changed to regular string concatenation, but the remove() is left as is.

Am I doing something wrong here? Or is it simply that I expect too much of Babel?


Solution

  • I was mistaken as to what Babel actually does with code. As per the Babel website “Babel only transforms syntax” so the observed behavior is exactly what should be expected.

    I guess there are more clever solutions out there (such as Polyfill.io), but right now I’m solving these things with regular expressions in my gulpfile.js through gulp-replace with

    const gulp = require('gulp'),
        babel = require('gulp-babel'),
        replace = require('gulp-replace');
    
    gulp.task('js', function() {
        return gulp.src('src/script.js')
            .pipe(babel({
                presets: ['@babel/preset-env']
            }))
            .pipe(replace(/(\S*)\.remove\s*\(.*?\)\s*;/g, '$1.parentNode.removeChild($1);'))
            .pipe(gulp.dest('dist'));
    });