By Scott Davis on May 18, 2018
Implementing Babel via Grunt
This article will take 2 minutes to read
Have you ever felt your excitement build after seeing some cool, new JavaScript feature only to find out that it isn’t supported in all of the browsers that your app supports? Bummer! If you’ve ridden this rollercoaster of emotions before, Babel might just be your favorite new tool.
Babel allows you to write your code with all of the features that the cool-kids are using such as async/await, template literals, arrow functions, const & let variable declaration, and many more. It does this by compiling your modern code to backwards-compatible code that is supported in all major browsers.
It does take a bit of setup but it’s well worth the investment of time. Once you start using some of these newer language features you’ll wonder how you ever got by without them. Here are the steps that we take when “babelifying” our grunt-based projects:
- Install node dependencies:
npm i grunt-babel babel-preset-latest babel-plugin-transform-remove-strict-mode --save-dev
We use the last plugin to remove the
"use strict"
that Babel writes to all output files. This is because dojo 1 has issues with strict mode. -
Move the
src/app
folder to_src/app
as well as any other files insrc
that are committed to source control such asindex.html
. This is because we are going to git ignore thesrc
folder entirely since it will only hold Babel output as well as other dependencies. -
Update
.gitignore
to ignore the entiresrc
directory. This is a major simplification from the previous version which had to ignore each bower dependency explicitly. - Add babel grunt task configuration:
babel: { options: { sourceMap: true, presets: ['latest'], plugins: ['transform-remove-strict-mode'] }, src: { files: [{ expand: true, cwd: '_src/app/', src: ['**/*.js'], dest: 'src/app/' }] } }
- Add a copy task config for copying all of the non-js files from
_src
tosrc
:copy: { dist: { files: [{expand: true, cwd: 'src/', src: ['*.html'], dest: 'dist/'}] }, src: { expand: true, cwd: '_src', src: ['**/*.html', '**/*.css', '**/*.png', '**/*.jpg', 'secrets.json', 'app/package.json'], dest: 'src' } }
-
If you are using a CSS pre-processor you may want to repoint it’s grunt task configuration to the
_src
folder. -
You’ll also want to repoint the linter, watch, and bump tasks to the
_src
folder. -
Add the new babel and copy tasks to the watch task config. Using grunt-newer will make things more efficient.
- Add a new clean sub task to clean
src/app
:clean: { build: ['dist'], deploy: ['deploy'], src: ['src/app'] }
- Add babel, clean and copy tasks to the build and default tasks:
grunt.registerTask('default', [ 'eslint', 'clean:src', 'babel', 'stylus:src', 'copy:src', 'connect', 'jasmine:main:build', 'watch' ]); grunt.registerTask('build-prod', [ 'clean:src', 'babel', 'stylus:src', 'copy:src', 'newer:imagemin:main', 'dojo:prod', 'uglify:prod', 'copy:dist', 'processhtml:main' ]);
- You may also need to update your
.eslintrc
file to be at the correct Ecma version that you’ll be writing your code inparserOptions: { ecmaVersion: 8 }
Here’s a commit that contains most of these steps. It seems like I always forget a few things. :)
Writing modern JavaScript is fun and it encourages better programming patterns. I hope that you’ll give Babel a try.