Since I've been porting my long-term project from CoffeeScript to native JavaScript I thought it'd be a good idea to share how it's working now.
Assuming we've got a brand new SailsJS application, the first thing we need is to install grunt-babel
and configure the task.
# Install the Grunt task
npm i grunt-babel --save-dev
npm i babel-preset-es2015 --save-dev
Create a new file in tasks/config/
called babel.js
with the following contents:
# tasks/config/babel.js
module.exports = function(grunt) {
grunt.config.set('babel', {
dev: {
options: {
presets: ['es2015']
},
files: [{
expand: true,
cwd: 'assets/js/',
src: ['**/*.js', '!dependencies/**/*.js'],
dest: '.tmp/public/js/',
ext: '.js'
}]
}
});
grunt.loadNpmTasks('grunt-babel');
};
Open tasks/register/compileAssets.js
and change coffee:dev
to babel:dev
(around line ~7).
That's it.
You can now use ES2015 JavaScript in your Sails assets. Your "future JavaScript" will be transformed by Babel so that most current browser can handle it.
What about AngularJS?
Having the features of ES6 makes developing Angular way more comfortable.
Controllers
Controllers can easily be implemented through classes now, for example:
class HelloController {
constructor() {
this.message = 'Hello World';
}
}
awesomeApp
.controller('HelloController', HelloController);
While accessing class members like this:
<div ng-controller="HelloController as HelloCtrl">
{{ HelloCtrl.message }}
</div>
See here for additional information about why using controller As ctrl
and not using $scope
.
Controllers and dependency injection
You may have some dependencies for your controllers. They're automatically injected by Angular, for example:
class HelloController {
constructor($element) {
this.message = 'Hello World';
console.log($element);
}
}
If you want to use your dependencies in other methods of your class simply bind them to this
:
class HelloController {
constructor($element) {
this.message = 'Hello World';
this.$element = $element;
this.doStuff();
}
doStuff() {
console.log(this.$element);
}
}
Note: Probably not the most elegant solution. If someone has a better one feel free to tell me.
Services
Basically the same as for controllers:
class GreetingsService {
greet() {
console.log('Hello!');
}
}
awesomeApp
.factory('GreetingsService ', GreetingsService);
Used like this:
class HelloController {
constructor($element, GreetingsService) {
this.message = 'Hello World';
GreetingsService.greet();
}
}
Directives
Even directives are that simple:
class DoStuff {
constructor() {
this.restrict = 'E';
}
template() {
return 'Hey {{name}}';
}
link(scope, elem, attrs) {
scope.name = 'Bob';
}
}
awesomeApp
.directive('doStuff', DoStuff);