ES2015

ES2015 (anciennement ES6) est une avancée considérable pour le langage JavaScript. Elle apporte de nouvelles fonctionnalités et de nouvelles fonctionnalités de sucre pour les modèles nécessitant un code récurrent important dans ES5. Cela inclut les cours, les fonctions fléchées et les modules. Dans cet épisode, nous abordons les outils que nous utilisons pour tirer pleinement parti d'ES2015 lorsque nous créons des applications Web JavaScript.

Transpilation avec Babel

Bien que les moteurs JavaScript progressent dans l'implémentation des fonctionnalités ES2015 de manière native, il existe un seul obstacle. Pour utiliser l'ensemble complet de fonctionnalités aujourd'hui, vous devrez retranspiler votre code vers ES5 afin qu'il puisse être interprété par les navigateurs actuels. Heureusement, des outils comme Babel existent qui rendent ce processus très simple.

Utiliser Babel dans votre processus de création

Babel vous permet de récupérer du code JavaScript écrit à l'aide des fonctionnalités ES2015 et de le transpiler en ES5 afin qu'il puisse fonctionner dans les navigateurs qui ne sont pas compatibles avec ces fonctionnalités à l'heure actuelle. L'ajout de Babel à votre processus de compilation peut se faire de cette manière.

var gulp = require('gulp');
var babel = require('gulp-babel');

gulp.task('default', function () {
    return gulp.src('src/app.js')
        .pipe(babel())
        .pipe(gulp.dest('dist'));
});

La seule fonctionnalité que Babel ne peut pas transpiler est celle des modules. Les modules d'ES6 vous permettent de créer des classes et d'exporter / importer des classes entre des fichiers. Pour transpiler les modules, transmettez votre code JavaScript via Browserify, qui fusionne les fichiers, puis le transmet via Babelify (une version de Babel qui peut gérer la sortie de Browserify).

var babelify = require('babelify');
var source = require('vinyl-source-stream');
var browserify = require('browserify');

gulp.task('babelify', function() {
  browserify({ entries: './src.js', debug: true })
    .transform(babelify)
    .bundle()
    .pipe(source('bundle.js'))
    .pipe(gulp.dest('./dist/js/'));
});

Plusieurs fichiers JavaScript

L'exemple ci-dessus nécessite que vous définissiez un fichier spécifique, ce qui peut devenir un peu fastidieux. Matt effectue les opérations suivantes dans Gulp pour rechercher et transpiler les fichiers se terminant par .es6.js.

var config = {
  src: 'src/scripts',
  dest: 'dist/scripts'
};
var es6FileGlob = '/**/*.es6.js';

var gulp = require('gulp');
var plugins = require('gulp-load-plugins')();
var glob = require('glob');
var path = require('path');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');

// Takes an array of bundles to run through browserify and babelify
function transpileES6Modules(browserifyFileEntries) {
  browserifyFileEntries.forEach(function(fileEntry) {
    var browserifyBundle = browserify({
        entries: [fileEntry.srcPath]
      })
      .transform(babelify);

    var finalStream = browserifyBundle.bundle()
      .on('log', plugins.util.log.bind(plugins.util, 'Browserify Log'))
      .on('error', plugins.util.log.bind(plugins.util, 'Browserify Error'))
      .pipe(source(fileEntry.outputFilename));

    return finalStream.pipe(gulp.dest(fileEntry.dest));
  });
}

// This takes a source path and finds all files ending
// with .es6.js and creates the bundles to run through browserify
// and babelify
function handleES6Scripts(srcPath) {
  var browserifyFileEntries = [];

  var es6Filepaths = glob.sync(srcPath + es6FileGlob);
  es6Filepaths.forEach(function(filepath) {
    var filename = path.basename(filepath);
    var directoryOfFile = path.dirname(filepath);
    var relativeDirectory = path.relative(
      srcPath,
      directoryOfFile);

    // Create an object and add to the browserify bundle array
    browserifyFileEntries.push({
      srcPath: './' + filepath,
      outputFilename: filename,
      dest: path.join(config.dest, relativeDirectory)
    });
  });

  transpileES6Modules(browserifyFileEntries);
}

gulp.task('scripts:es6', ['scripts:lint'], function(cb) {
  handleES6Scripts(config.src);

  cb();
});

Vérifications lint et style

Il existe quelques options d'analyse lint de votre code afin de détecter les problèmes potentiels et la conformité du style.

JSHint et JSCS

JSHint et JSCS sont les outils les plus couramment utilisés pour le contrôle du style JavaScript.

JSHint met en évidence les problèmes potentiels dans votre code ainsi que tous les modèles généralement considérés comme des mauvaises pratiques.

JSCS examine le style de votre code, y compris des éléments comme s'assurer que seuls les onglets ou les espaces sont utilisés et que les espaces sont placés à des endroits cohérents.

Pour utiliser JSHint et JSCS sur le code ES2015, vous devez ajouter "esnext": true à vos fichiers .jshintrc et .jscsrc.

ESLint

ESLint est un outil lint et un vérificateur de style alternatifs. Cet outil est très sollicité et propose des fonctionnalités intéressantes par rapport à JSHint, par exemple la possibilité d'indiquer les environnements pour lesquels votre code JavaScript est écrit et de définir le niveau d'erreur / d'avertissement pour des problèmes spécifiques.

ESLint est entièrement personnalisable et fournit des règles d'analyse lint personnalisées qui vous permettent de contrôler si les options peuvent être désactivées ou atténuées via ses fichiers de configuration. En outre, si vous utilisez React, ESLint fonctionne également avec JSX.

Configurer ESLint dans votre processus de compilation n'est pas non plus trop difficile.

var gulp = require('gulp'),
    eslint = require('gulp-eslint');

gulp.task('lint', function () {
    return gulp.src(['js/**/*.js'])
        // eslint() attaches the lint output to the eslint property
        // of the file object so it can be used by other modules.
        .pipe(eslint())
        // eslint.format() outputs the lint results to the console.
        // Alternatively use eslint.formatEach() (see Docs).
        .pipe(eslint.format())
        // To have the process exit with an error code (1) on
        // lint error, return the stream and pipe to failOnError last.
        .pipe(eslint.failOnError());
});

gulp.task('default', ['lint'], function () {
    // This will only run if the lint task is successful...
});

L'équipe Babel gère babel-estlint, un outil qui vous permet d'effectuer l'analyse lint de tout code Babel valide à l'aide d'ESLint. Bien qu'ESLint soit compatible avec les analyseurs personnalisés, une partie de la syntaxe prise en charge par Babel n'est pas directement compatible avec ESLint. Il s'agit donc d'une autre option si vous avez besoin d'encore plus de flexibilité. Vous pouvez le configurer en personnalisant la section parser de votre fichier .eslintrc:

{
  "parser": "babel-eslint",
  "rules": {
    "strict": 0
  }
}

Dan Abramov a rédigé un excellent article sur la configuration d'ESLint et de babel-eslint dans Lint Like It's 2015. Il explique également comment intégrer SublimeLinter-eslint dans votre workflow pour prendre en charge le linting ES2015 dans Sublime Text.

Quelle solution devez-vous utiliser ? Essayez-les et choisissez ce qui vous convient le mieux.

Mise en surbrillance de la syntaxe ES2015

Il va sans dire que la syntaxe de votre code ES2015 doit être mise en surbrillance correctement. Nous pouvons utiliser babel-sublime, qui peut être installé depuis l'outil Package Control. Lors de la configuration, nous vous recommandons de la définir comme valeur par défaut pour tous les fichiers à mettre en surbrillance. Cela inclura bien sûr JS, mais peut également couvrir JSX si vous utilisez React.

Documentation ES2015

Nous avons toujours largement utilisé JSDoc pour documenter notre code JavaScript. Malheureusement, il existe des problèmes non résolus concernant la compatibilité avec ES2015 (qui doivent être résolus dans le document JSDoc 3), mais il existe de plus en plus d'alternatives disponibles en attendant que le retard soit rattrapé. ESDoc fait partie de ces solutions, et Jonathan Cream a récemment publié un résumé à ce sujet, qui mérite d'être lu.

Créer des fichiers Gulp.js avec Babel

Si vous utilisez Gulp pour votre processus de compilation, vous pouvez désormais créer des fichiers Gulpfile à l'aide de n'importe quelle syntaxe compatible avec Babel. Nous le faisons dans le Web Starter Kit, et la configuration est relativement simple. À l'aide d'une version récente de Gulp et de la CLI Gulp, il vous suffit de renommer gulpfile.js en gulpfile.babel.js. Gulp interprétera et transpilera automatiquement votre fichier gulpfile ES2015 à l'aide de Babel.

Fonctionnalités ES2015 préférées

Modules

Les modules vous permettent d'exporter des valeurs, des fonctions et des classes à partir d'un fichier afin de pouvoir les importer dans un autre fichier.

export function exampleFunction() {
  console.log('I\'m an example. #TrueStory');
}



import { exampleFunction } from './example-function';
import BaseController from './base-controller';

export default class ExampleController extends BaseController {
  constructor() {
    super();

    exampleFunction();
  }

  doSomething() {
    console.log('What should I do? Change the DOM? Print a dancing shark to the console?');
  }
}

Ce site contient d'excellents exemples et explications concernant les modules.

Chaînes du modèle

Les chaînes de modèle vous permettent de remplacer un port d'une chaîne par une variable.

// Simple string substitution
var name = "Brendan";
console.log('Yo, ${name}!');

// => "Yo, Brendan!"

L'avantage des chaînes de modèle est que la substitution est une exécution JavaScript, ce qui signifie que vous pouvez utiliser des fonctions ou des expressions intégrées.

var a = 10;
var b = 10;
console.log('a+b = ${a+b}.');
//=> a+b = 20.

function fn() { return "I am a result. Rarr"; }
console.log('foo ${fn()} bar');
//=> foo I am a result. Rarr bar.

Pour en savoir plus, consultez cet article de blog pratique d'Addy.

Littéraux d'objet abrégés

Les littéraux d'objet vous évitent d'avoir à définir la clé et la valeur lors de la création d'un objet, si la variable porte le même nom que la clé que vous souhaitez attribuer à l'objet.

Signification:

function createObject(name, data) {
  return { name: name, data: data };
}

Transforme ce format:

function createObject(name, data) {
  return { name, data };
}

Noms de propriétés calculés

Dans ES2015, cette fonctionnalité vous permet de créer des noms de propriété de manière dynamique sur un objet. Les documents Mozilla sont une excellente source d'informations et incluent cet excellent exemple.

var a = {
  ["foo" + ++i]: i,
  ["foo" + ++i]: i,
  ["foo" + ++i]: i
};

console.log(a.foo1); // 1
console.log(a.foo2); // 2
console.log(a.foo3); // 3

Fonctions de la flèche grasse

Les fonctions de flèche grasse vous permettent d'écrire des fonctions abrégées où:

button.addEventListener('click', function(event) {
  console.log('The button has received a click', event);
});

Transforme ce format:

button.addEventListener('click', (event) => {
  console.log('The button has received a click', event);
});

En plus d'avoir une syntaxe plus courte, l'une des principales caractéristiques de l'utilisation des fonctions de flèche grasse est que le champ d'application de l'objet est identique à l'instruction englobante. Cela signifie que vous n'avez pas besoin d'appeler .bind(this) sur votre fonction ni de créer une var qui = this.

Vous trouverez beaucoup d'autres exemples sur le Réseau de Recherche (MDN).

Dépôt d'outils ES6 d'Addy

Addy tient à tenir une liste d'outils ES2015. Si les outils ci-dessus ne vous conviennent pas, si vous utilisez Grunt au lieu de Gulp, cette solution a peut-être la réponse à votre question.

https://github.com/addyosmani/es6-tools

Ce qui précède inclut également des liens vers d'autres outils Babel qui peuvent être utiles lors des tests unitaires et au-delà.

Livres à lire

Vous pouvez consulter sans frais deux livres en ligne pour en savoir plus sur ES2015. Comprendre ECMAScript 6, écrit par Nicholas C. Zakas et Exploring ES6, écrit par le Dr Axel Rauschmayer.

Tour de Babel

Si vous souhaitez découvrir les fonctionnalités de l'ES2015 via la ligne de commande, tower-of-babel propose une série d'exercices qui pourraient vous intéresser. Ils utilisent tous Babel.

Autres ressources utiles: