Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Babel + grunt to work with ES6 - how to transform require statements?

I want to start using ES6, and I want to use grunt to manage my files. This is my project structure so far:

Gruntfile.js
package.json
dist/
src/
  index.es6

And this is what index.es6 looks like:

import MapGL from 'react-map-gl';
const data = [];
const viewport = new Viewport();

These packages are all defined in package.json and installed.

How do I turn this ES6 file into ES5 JavaScript? Right I'm able to turn it into JavaScript of a sort, but it's not transforming the require statements at all.

This is my current Gruntfile:

module.exports = function(grunt) {
  require('load-grunt-tasks')(grunt);
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      options: {
        separator: ';'
      },
      dist: {
        src: ['src/**/*.js'],
        dest: 'dist/<%= pkg.name %>.js'
      }
    },
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
      },
      dist: {
        files: {
          'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
        }
      }
    },
    jshint: {
      files: ['src/index.js', 'test/index.js'],
      options: {
        reporterOutput: '',
        esnext: true,
        globals: {
          console: true,
          module: true,
          document: true
        }
      }
    },
    babel: {
        files: {
            expand: true,
            src: ['src/*.es6'],
            ext: '-compiled.js'
        },
        options: {
            sourceMap: true,
            presets: ['babel-preset-es2015']
        }
    },
    watch: {
      files: ['<%= jshint.files %>'],
      tasks: ['babel', 'jshint', 'concat']
    }
  });
  grunt.registerTask('default', ['babel', 'jshint', 'concat', 'uglify']);
};

Running grunt produces the following files:

Gruntfile.js
package.json
dist/
  myproject.js
src/
  index.es6
  index-compiled.js
  index-compiled.map

But myproject.js contains the line var _reactMapGl = require('react-map-gl'); which fails in the browser.

like image 851
Richard Avatar asked Dec 09 '16 19:12

Richard


People also ask

Is babel needed for ES6?

Absolutely can and do use ES6 W/O babel. All major browsers support the vast majority of features natively (see CanIUse.com), in fact, the only major feature not supported is the import/export of modules. For these, you still have to manually import your modules in the correct order using script tags in the HTML.

How do you Transpile using babel?

You can use babel-standalone to transpile ES6 to ES5 in a browser environment. You just need to load the “babel-standalone” in your script as highlighted below and write the script you want to transpile, in script tag with type “text/babel” or “text/jsx”. Babel will automatically compile and execute the script.

How do I Transpile ES5?

Transpiled using babel to ES5"use strict"; var a = 1; if (a == 1) { var _a = 2; console. log(_a); } console. log(a); If you see the ES5 code the let keyword is replaced with the var keyword.


1 Answers

Yes, as per @Matthew Herbst recommendation, Browserify will handle the import bindings for the ES6 modules. Also a package named babelify will help to handle your babel browserify transform.

The following seems to work well:

Use babel-cli instead of babel.

  1. It's worth noting that Babel has been replaced with babel-cli as of babel 6 (see their blog for more info on that). So, firstly, remove/uninstall it from your package.json (if it exists!):

    $ npm uninstall babel --save-dev

    ...and uninstall grunt-babel:

    $ npm uninstall grunt-babel --save-dev

  2. Install babel-cli and also include the babel preset for all es2015 plugins:

    $ npm install --save-dev babel-cli babel-preset-es2015

  3. Next, create a .babelrc file and save it in your projects root directory containing the following code:

    {
        "presets": ["es2015"]
    }

grunt-browserify

  1. Next, install grunt-browserify and save it to your package.json:

    $ npm install grunt-browserify --save-dev

babelify

  1. Install babelify to handle your babel browserify transform:

    $ npm install babelify --save-dev

Gruntfile.js

  1. Next update your Gruntfile.js by deleting the existing babel task:
    // DELETE the following...
    babel: {
        files: {
            expand: true,
            src: ['src/*.es6'],
            ext: '-compiled.js'
        },
        options: {
            sourceMap: true,
            presets: ['babel-preset-es2015']
        }
    },
  1. ...and adding the following browserify task instead:
    browserify: {
        dist: {
            files: {
                // destination for transpiled js : source js
                'dist/myproject.js': 'src/index.es6'
            },
            options: {
                transform: [['babelify', { presets: "es2015" }]],
                browserifyOptions: {
                    debug: true
                }
            }
        }
    }
  1. Registering your grunt tasks: It's likely that you will also need to update and change the order of the tasks in the array passed to grunt.registerTask. To this:
grunt.registerTask('default', [
    'jshint',
    //'concat', <-- Probably don't need to concat the files, assuming index.es6 imports the necessary modules.
    'browserify:dist',
    'uglify'
]);

Additional note:

There may be some benefits in using react presets in addition to the es2015 presets - which would entail modifying points 2, 3, and 7 above accordingly, however, I haven't used it myself.

Hope this helps!

like image 179
RobC Avatar answered Oct 22 '22 21:10

RobC