ES2015

ES2015 (formalmente ES6) é uma um passo incrível para a linguagem JavaScript. Ele traz novos recursos e simplificação para padrões que exigiam um código boilerplate significativo no ES5. Isso inclui classes, funções de seta e módulos. Neste episódio, vamos falar sobre ferramentas que usamos para aproveitar ao máximo o ES2015 ao criar apps JavaScript da Web.

Transpilação com Babel

Embora os mecanismos JavaScript estejam progresso na implementação do ES2015 os recursos de forma nativa, existe um problema. Para usar o conjunto completo de recursos hoje você vai precisar transcompilar seu código de volta para ES5, para que possa ser interpretado pelos navegadores atuais. Felizmente, existem ferramentas como o Babel o processo é bem fácil.

Como usar o Babel no seu processo de build

O Babel permite escrever código JavaScript usando ES2015. e os transpila para ES5 para que funcione em navegadores que não são compatíveis com esses recursos atualmente. Adicionar o Babel ao seu processo de compilação pode ser feito dessa forma.

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

O único recurso que o Babel não pode transcompilar é "Módulos". Com os módulos no ES6, criar classes e exportar / importar classes entre arquivos. Para transcompilar módulos transmitir seu JavaScript pela Browserify, que mescla os e depois passar pelo Babelify (uma versão do Babel que pode lidar com a saída 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/'));
});

Vários arquivos JavaScript

O exemplo acima exige que você defina um arquivo específico, que pode se tornar um pouco de um fardo, Matt faz o seguinte em Gulp para pesquisar e transcompilar arquivos e termina com .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();
});

linting e verificações de estilo

Há poucas opções ao inspecionar seu código em busca de possíveis problemas e estilo compliance.

JSHint e JSCS

JSHint e JSCS são os mais comuns usadas na verificação de estilo de JavaScript de hoje em dia.

O JSHint destacará quaisquer possíveis problemas no seu código, bem como chamará qualquer padrões geralmente considerados como incorretas.

O JSCS examinará o estilo do seu código, o que inclui coisas como garantir apenas tabulações ou espaços são usados e os espaços são colocados em lugares consistentes.

Para usar JSHint e JSCS no código ES2015, você precisa adicionar "esnext": true ao seu Arquivos .jshintrc e .jscsrc

ESLint

O ESLint é uma ferramenta alternativa de linter e verificador de estilo. Esta ferramenta está fazendo muito trabalho e tem alguns recursos interessantes em relação ao JSHint como indicar os ambientes para os quais o JavaScript é escrito e definir o nível de erro / aviso para problemas específicos.

O ESLint é totalmente personalizável e fornece regras de inspeção personalizadas no assento do motorista, se as opções podem ser desativadas ou atenuadas por meio de de configuração do Terraform. Além disso, se você estiver usando o React, o ESLint também funciona com JavaScript.

Configurar o ESLint no seu processo de compilação também não é muito difícil.

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

A equipe do Babel mantém o babel-estlint, uma ferramenta que permite inspecionar qualquer código Babel válido usando ESLint. Enquanto ESLint oferece suporte a analisadores personalizados, algumas das sintaxes com suporte do Babel não são diretamente compatível com ESLint, essa é outra opção se você precisar flexibilidade. Isso pode ser configurado personalizando a seção parser do seu Arquivo .eslintrc:

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

Dan Abramov tem um texto excelente sobre a configuração do ESLint e do babel-eslint em Lint Como se de 2015. Ela também aborda como integrar SublimeLinter-eslint em seu fluxo de trabalho para o suporte a inspeção ES2015 no Sublime Text.

Qual plataforma deve usar? Experimente e escolha a que funciona melhor para você.

Destaque de sintaxe ES2015

Obviamente, é recomendável que o código ES2015 tenha a sintaxe destacada corretamente. Qa gostam de usar o babel-sublime, que pode ser instalado pelo Package Control. Durante a configuração, recomendamos que você o defina como padrão para todos os arquivos. você precisa destacar para trabalhar. Isso inclui JS, obviamente, também cobre JSX se estiver usando React.

Documentando ES2015

Historicamente, usamos muito o JSDoc para documentar nosso código JavaScript. Infelizmente, há problemas pendentes relacionados ao suporte ao ES2015, que serão abordados no JSDoc 3. No entanto, há um número crescente de alternativas disponíveis enquanto aguardamos a atualização. O ESDoc é uma dessas opções, e Jonathan Creamer tem um artigo recente sobre ele que vale a pena ler.

Como criar arquivos Gulp.js com o Babel

Se você estiver usando o Gulp no seu processo de build, o Gulpfiles agora pode ser criados com qualquer sintaxe compatível com o Babel. Fazemos isso no Web Starter Kit e essa configuração é relativamente trivial. Usar uma versão recente do Gulp e do A CLI Gulp, basta renomear gulpfile.js para gulpfile.babel.js e o Gulp interpretar e transcompilar automaticamente seu gulpfile ES2015 usando o Babel.

Recursos favoritos do ES2015

Módulos

Os módulos são uma forma de exportar valores, funções e classes de um arquivo, como que você pode importá-los para outro arquivo.

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

Este site tem ótimos exemplos e explicações de Módulos.

Strings de modelo

As strings de modelo permitem substituir uma porta de uma string por uma variável.

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

// => "Yo, Brendan!"

O bom das strings de modelo é que a substituição é um código ou seja, é possível usar funções ou expressões inline.

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.

Para saber mais, leia esta postagem do blog Addy.

Literais de objetos abreviados

Os literais de objeto permitem que você não precise definir a chave e o valor ao criar um objeto, se a variável tiver o mesmo nome da chave com a qual você que um objeto precisa ter.

Isso significa:

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

Fica assim:

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

Nomes de propriedades computados

Esse recurso do ES2015 permite criar nomes de propriedades dinamicamente em um objeto. Os documentos do Mozilla é uma ótima fonte de informações e têm uma ótima exemplo.

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

Funções de seta gorda

As funções de seta fat permitem que você escreva funções abreviadas, em que:

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

Fica assim:

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

Além de ter uma sintaxe mais curta, um ótimo recurso do uso da seta de ponta é que o escopo do objeto é o mesmo da instrução em anexo. Isso significa que não é preciso chamar .bind(this) na sua função ou criar uma var que = this.

muitos outros exemplos MDN.

Repositório de ferramentas ES6 da Addy

A Addy está ocupado mantendo uma lista de ferramentas ES2015 e, se as ferramentas acima não estiverem, talvez esteja usando o Grunt em vez do Gulp, talvez isso uma resposta para você.

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

O conteúdo acima também inclui links para outras ferramentas do Babel que podem ajudar durante testes de unidade e muito mais.

Livros para ler

Há dois livros que você pode comprar on-line sem custo financeiro para saber mais sobre ES2015. Noções básicas sobre o ECMAScript 6 Escrito por Nicholas C. Zakas e Conheça o ES6 escrito por Dr. Axel Rauschmayer.

Torre de Babel

Se quiser aprender sobre os recursos ES2015 na sua linha de comando, tower-of-babel oferece um uma série de exercícios que podem ser interessantes. Todos eles explicam usando o Babel.

Outros recursos caso você tenha interesse: