ES2015

ES2015 (precedentemente ES6) è un un ottimo passo avanti per il linguaggio JavaScript. Offre nuove funzionalità e sugaring per modelli che hanno richiesto un boilerplate significativo in ES5. Questo include classi, funzioni freccia e moduli. In questo episodio parleremo degli strumenti che utilizziamo per sfruttare appieno ES2015 durante la creazione di app web JavaScript.

Traspilazione con Babel

Anche se i motori JavaScript stanno rendendo progressi nell'implementazione di ES2015 funzionalità native, c'è una cosa da fare. Per utilizzare il set completo di funzionalità oggi, sarà necessario eseguire il transpile del codice fino a ES5, interpretati dai browser attuali. Per fortuna esistono strumenti come Babel che questo processo è quasi indolore.

Utilizzo di Babel nel processo di creazione

Babel ti consente di prendere JavaScript scritto utilizzando ES2015 e lo trasla di nuovo a ES5 in modo che possa funzionare nei browser non supportano attualmente queste funzionalità. L'aggiunta di Babel al processo di compilazione può essere fatto in questo modo.

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'));
});

L'unica funzionalità che Babel non può trapelare sono i moduli. I moduli in ES6 ti consentono creare corsi ed esportare / importare classi tra i file. Come trapanare i moduli passare il codice JavaScript Browserify, che unirà i e poi passarlo a Babelify. (una versione di Babel che può gestire l'output da 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/'));
});

File JavaScript multipli

L'esempio precedente richiede la definizione di un file specifico, che potrebbe diventare un po' di un peso, Matt svolge le seguenti operazioni in Gulp per cercare e traslare i file che termina con .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();
});

Controlli di rivestimento e stile

Esistono poche opzioni per l'analisi tramite lint del codice per possibili problemi e stili conformità.

JSHint e JSCS

JSHint e JSCS sono le più comuni usati per il controllo dello stile di JavaScript odierno.

JSHint evidenzia eventuali problemi nel codice e richiama eventuali generalmente considerati come pratiche scorrette.

JSCS esaminerà lo stile del tuo codice, inclusi elementi come garantire vengono utilizzate solo schede o spazi e gli spazi vengono inseriti in posizioni coerenti.

Per utilizzare JSHint e JSCS sul codice ES2015 devi aggiungere "esnext": true al tuo .jshintrc e .jscsrc file

ESLint

ESLint è un linter e uno stile alternativi in uno. Questo strumento è molto utile e ha alcune interessanti funzionalità rispetto a JSHint come la possibilità di indicare gli ambienti per i quali è scritto il codice JavaScript e impostare il livello di errore / avviso per problemi specifici.

ESLint è completamente personalizzabile e fornisce regole di analisi tramite lint personalizzate nel punto al conducente della possibilità di disattivare o abbassare le opzioni tramite di configurazione dei deployment. Inoltre, se usi React, ESLint funziona anche con JSX.

Anche la configurazione di ESLint nel processo di compilazione non è troppo 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...
});

Il team di Babel mantiene babel-estlint, uno strumento che ti consente di lint qualsiasi codice Babel valido utilizzando ESLint. Mentre ESLint supporta i parser personalizzati, parte della sintassi supportata da Babel non è supportata da ESLint, quindi è un'altra opzione se hai bisogno di una maggiore flessibilità. Puoi configurare questa funzionalità personalizzando la sezione parser del tuo .eslintrc file:

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

Dan Abramov ha un'ottima conoscenza su come configurare ESLint e babel-eslint in Lint Mi piace 2015. Inoltre, spiega come integrare SublimeLinter-eslint in il tuo flusso di lavoro per il supporto tramite lint in ES2015 in Sublime Text.

Che cosa dovresti usare? Provali e segui quelli che funzionano meglio per te.

Evidenziazione della sintassi di ES2015

È ovvio che il codice ES2015 deve evidenziare la sintassi in modo corretto. Me piace usare babel-sublime, che può da Controllo pacchetti. Durante la configurazione, assicurati di impostarlo come predefinito per tutti i file occorre evidenziare su cui lavorare. Include ovviamente JS, ma anche JSX se usi React.

Documentare ES2015

Storicamente ci siamo affidati molto a JSDoc per documentare il nostro codice JavaScript. Purtroppo, presenta problemi aperti per il supporto di ES2015 (che dovranno essere risolti nel documento JSDoc 3), tuttavia sono disponibili un numero crescente di alternative in attesa che vengano risolte. ESDoc è una di queste opzioni e Jonathan Creamer ha pubblicato di recente un risultato che vale la pena leggere.

Creazione di file Gulp.js con Babel

Se utilizzi Gulp per il processo di compilazione, ora i file Gulp possono essere utilizzando qualsiasi sintassi supportata da Babel. Lo ribadiamo in Web Starter Kit ed è relativamente banale da configurare. Utilizzando una versione recente di Gulp e CLI Gulp, rinomina semplicemente gulpfile.js in gulpfile.babel.js e Gulp lo farà interpretare e transpilare automaticamente il file gulpfile di ES2015 utilizzando Babel.

Funzionalità preferite di ES2015

Moduli

I moduli sono un modo per esportare valori, funzioni e classi da un file come puoi importarli in un altro file.

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?');
  }
}

Questo sito contiene alcuni ottimi esempi e spiegazioni Moduli.

Stringhe modello

Le stringhe del modello consentono di sostituire la porta di una stringa con una variabile.

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

// => "Yo, Brendan!"

L'aspetto positivo delle stringhe del modello è che la sostituzione è un file JavaScript di esecuzione, il che significa che puoi usare funzioni o espressioni in linea.

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.

Puoi scoprire di più in questo pratico post del blog di Addy.

Caratteri letterali oggetto in forma breve

I valori letterali oggetto consentono di evitare di definire la chiave e il valore quando creando un oggetto, se la variabile ha lo stesso nome della chiave che vuoi oggetto di valutazione.

Significato:

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

Diventa questo:

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

Nomi proprietà calcolate

Questa funzionalità di ES2015 consente di creare nomi di proprietà in modo dinamico su una . I documenti su Mozilla sono un'ottima fonte di informazioni e offrono esempio.

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

Funzioni Freccia grassa

Le funzioni Freccia grassa consentono di scrivere funzioni in forma breve dove:

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

Diventa questo:

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

Oltre ad avere una sintassi più breve, un'ottima caratteristica dell'uso della freccia grassa è che l'ambito dell'oggetto è lo stesso dell'istruzione che lo contiene. Ciò significa che non devi chiamare .bind(this) sulla tua funzione o create a var that = this.

Ci sono molti altri esempi sulla MDN.

Repository degli strumenti ES6 di Addy

Addy è impegnata a mantenere un elenco di strumenti di ES2015 e se quelli riportati sopra più adatta a te, forse stai usando Grunt invece di Gulp, allora potrebbe essere una risposta.

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

Quanto sopra include anche link ad altri strumenti Babel che possono aiutarti durante test delle unità e non solo.

Libri da leggere

Esistono due libri che puoi consultare senza costi online per saperne di più ES2015. Informazioni su ECMAScript 6 scritto da Nicholas C. Zakas e esplorazione di ES6 scritto da Dottoressa Axel Rauschmayer

Torre di Babele

Se ti interessa apprendere le caratteristiche di ES2015 dalla riga di comando, tower-of-babel offre una serie di esercizi che potrebbero interessarti. Tutti spiegano in dettaglio Babele.

Altre risorse in caso di interesse: