ES2015

ES2015 (ชื่อเดิมคือ ES6) เป็นก้าวหน้าที่ยอดเยี่ยมสำหรับภาษา JavaScript โดยจะนำฟีเจอร์ใหม่ๆ และการใส่น้ำตาลสำหรับรูปแบบที่ต้องใช้ต้นแบบจำนวนมากใน ES5 ซึ่งรวมถึงคลาส ฟังก์ชันลูกศร และโมดูล ในตอนนี้ เราจะพูดถึงเครื่องมือที่เราใช้ให้ใช้ประโยชน์จาก ES2015 อย่างเต็มที่เมื่อสร้างเว็บแอป JavaScript

การขนส่งด้วย Babel

แม้ว่าเครื่องมือ JavaScript กำลังคืบหน้าอย่างมากในการนำฟีเจอร์ ES2015 ไปใช้ตามปกติ แต่ก็มี Getcha เพียง 1 รายการ หากต้องการใช้ชุดฟีเจอร์ที่สมบูรณ์ในวันนี้ คุณจะต้องเปลี่ยนรูปแบบโค้ดกลับไปเป็น ES5 เพื่อให้เบราว์เซอร์ปัจจุบันตีความได้ โชคดีที่มีเครื่องมืออย่าง Babel อยู่ซึ่งทำให้กระบวนการนี้ เป็นไปอย่างราบรื่น

การใช้ Babel ในขั้นตอนการสร้างของคุณ

Babel ช่วยให้คุณนำ JavaScript ที่เขียนขึ้นโดยใช้ฟีเจอร์ ES2015 และแปลงกลับไปเป็น ES5 เพื่อให้ทำงานได้ในเบราว์เซอร์ที่ไม่รองรับฟีเจอร์เหล่านี้ในปัจจุบัน การเพิ่ม Babel ลงในกระบวนการสร้างก็สามารถทำได้เช่นกัน

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

คุณลักษณะหนึ่งที่ Babel ทำไม่ได้คือโมดูล โมดูลใน ES6 ช่วยให้คุณสร้างคลาสและส่งออก / นำเข้าคลาสระหว่างไฟล์ได้ ในการสลับโมดูล ให้ส่ง JavaScript ผ่าน Browserify ซึ่งจะรวมไฟล์ต่างๆ แล้วส่งผ่าน Babelify (เวอร์ชัน Babel ที่จัดการเอาต์พุตจาก 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/'));
});

ไฟล์ JavaScript หลายไฟล์

จากตัวอย่างข้างต้น คุณต้องกำหนดไฟล์บางไฟล์ซึ่งอาจกลายเป็นภาระหนัก Matt จะดำเนินการต่อไปนี้ใน Gulp เพื่อค้นหาและเปลี่ยนรูปแบบไฟล์ที่ลงท้ายด้วย .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();
});

การตรวจสอบ Lint และรูปแบบ

มีบางตัวเลือกเมื่อเรียกใช้โค้ดสำหรับปัญหาที่อาจเกิดขึ้นและสไตล์การปฏิบัติตามข้อกำหนด

JSHint และ JSCS

JSHint และ JSCS เป็นเครื่องมือที่นิยมใช้กันมากที่สุดสำหรับการตรวจสอบสไตล์ JavaScript ในปัจจุบัน

JSHint จะไฮไลต์ปัญหาที่เป็นไปได้ในโค้ด รวมถึงระบุรูปแบบที่มักถือว่าเป็นแนวทางปฏิบัติที่ไม่ดี

JSCS จะดูรูปแบบของโค้ด ซึ่งรวมถึงสิ่งต่างๆ เช่น การตรวจสอบว่ามีการใช้เฉพาะแท็บหรือเว้นวรรค และวางเว้นวรรคในตําแหน่งที่สอดคล้องกัน

หากต้องการใช้ JSHint และ JSCS กับโค้ด ES2015 คุณต้องเพิ่ม "esnext": true ลงในไฟล์ .jshintrc และ .jscsrc

ESLint

ESLint เป็นเครื่องมือวิเคราะห์โค้ดทางเลือกและเครื่องมือตรวจสอบรูปแบบในหนึ่งเดียว เครื่องมือนี้ช่วยให้มีน้ำมากขึ้นและมีฟีเจอร์ดีๆ เหนือ JSHint เช่น ความสามารถในการระบุสภาพแวดล้อมที่คุณเขียน JavaScript และตั้งค่าระดับข้อผิดพลาด / คำเตือนสำหรับปัญหาที่เฉพาะเจาะจง

ESLint สามารถปรับแต่งได้อย่างเต็มที่ และมีกฎการปรับค่าข้อมูลที่กำหนดเอง ซึ่งคุณสามารถเลือกได้เองว่าจะสามารถปิดหรือปรับลดตัวเลือกของตัวเลือกผ่านไฟล์การกำหนดค่าได้หรือไม่ นอกจากนี้ หากคุณใช้ React โปรแกรม ESLint ยังทำงานร่วมกับ JSX ได้อีกด้วย

การตั้งค่า ESLint ในกระบวนการสร้างของคุณไม่ใช่เรื่องยากเกินไปเช่นกัน

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

ทีม Babel ดูแลรักษา babel-estlint ซึ่งเป็นเครื่องมือที่ให้คุณค้นหาโค้ด Babel ที่ถูกต้องโดยใช้ ESLint แม้ว่า ESLint จะรองรับโปรแกรมแยกวิเคราะห์ที่กำหนดเอง แต่ ESLint ยังไม่รองรับไวยากรณ์บางรูปที่ ESLint รองรับโดยตรง ดังนั้นจึงเป็นอีกตัวเลือกหนึ่งหากคุณต้องการความยืดหยุ่นมากกว่านี้ ซึ่งตั้งค่าได้โดยปรับแต่งส่วน parser ของไฟล์ .eslintrc ดังนี้

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

Dan Abramov เขียนได้ดีเกี่ยวกับการตั้งค่า ESLint และ Babel-eslint ใน Lint Like It's 2015 นอกจากนี้ยังครอบคลุมถึงวิธีผสานรวม SublimeLinter-eslint กับเวิร์กโฟลว์สำหรับการสนับสนุน Lint ของ ES2015 ใน Sublime Text

คุณควรใช้สิ่งใด ลองใช้งานและตัดสินใจเลือกวิธีที่เหมาะกับคุณที่สุด

การไฮไลต์ไวยากรณ์ ES2015

แน่นอนว่าคุณจะต้องไฮไลต์โค้ด ES2015 ที่มีการไฮไลต์ไวยากรณ์อย่างถูกต้อง เราสนุกไปกับการใช้ babel-sublime ซึ่งติดตั้งได้จากการควบคุมแพ็กเกจ ขณะตั้งค่า เราขอแนะนำให้คุณตรวจสอบให้แน่ใจว่าได้ตั้งค่าเป็นค่าเริ่มต้นสำหรับไฟล์ใดๆ ที่คุณต้องการไฮไลต์ แน่นอนว่าจะมี JS แต่ก็อาจครอบคลุมถึง JSX หากใช้ React อยู่

เอกสารประกอบ ES2015

ที่ผ่านมาเราอาศัย JSDoc เป็นหลักสำหรับการบันทึกโค้ด JavaScript ของเรา แต่ต้องขออภัยเนื่องจากมีปัญหาที่ยังไม่ได้รับการแก้ไขสำหรับการรองรับ ES2015 (เนื่องจากเราจะกล่าวถึงใน JSDoc 3) แต่ก็มีทางเลือกอื่นๆ เพิ่มขึ้นในระหว่างที่เรารอการแก้ไข ESDoc เป็นตัวเลือกหนึ่ง และ Jonathan Creamer ก็ยังได้เขียนข้อความล่าสุดเกี่ยวกับเรื่องนี้ที่น่าอ่าน

การสร้างไฟล์ Gulp.js ด้วย Babel

หากคุณกำลังใช้ Gulp สำหรับกระบวนการสร้าง ตอนนี้สามารถสร้าง Gulpfiles โดยใช้ไวยากรณ์ใดก็ได้ที่ Babel รองรับ เราดำเนินการนี้ใน Web Starter Kit และการตั้งค่าค่อนข้างน้อย เมื่อใช้ Gulp และ Gulp CLI เวอร์ชันล่าสุด เพียงเปลี่ยนชื่อ gulpfile.js เป็น gulpfile.babel.js จากนั้น Gulp จะตีความและเปลี่ยนรูปแบบไฟล์ Gulp ของ ES2015 โดยใช้ Babel โดยอัตโนมัติ

ฟีเจอร์โปรดของ ES2015

โมดูล

โมดูลเป็นวิธีการส่งออกค่า ฟังก์ชัน และคลาสจากไฟล์หนึ่ง โดยที่คุณสามารถนำเข้าไปยังไฟล์อื่นได้

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

เว็บไซต์นี้มีตัวอย่างและคำอธิบายที่ดีบางส่วนเกี่ยวกับโมดูล

สตริงเทมเพลต

สตริงเทมเพลตช่วยให้คุณแทนที่พอร์ตของสตริงด้วยตัวแปรได้

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

// => "Yo, Brendan!"

ข้อดีของสตริงเทมเพลตคือการแทนที่จะเป็นการดำเนินการ JavaScript ซึ่งหมายความว่าคุณจะใช้ฟังก์ชันหรือนิพจน์ในบรรทัดได้

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.

ดูข้อมูลเพิ่มเติมจากบล็อกโพสต์ที่มีประโยชน์นี้ของ Addy

เลขตรงของออบเจ็กต์ชวเลข

ลิเทอรัลของออบเจ็กต์ช่วยให้คุณไม่ต้องกำหนดคีย์และค่าเมื่อสร้างออบเจ็กต์หากตัวแปรมีชื่อเหมือนกับคีย์ที่คุณต้องการให้ออบเจ็กต์มี

ซึ่งมีความหมายดังนี้

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

เปลี่ยนเป็น:

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

ชื่อพร็อพเพอร์ตี้ที่คำนวณ

ฟีเจอร์นี้ใน ES2015 ช่วยให้คุณสร้างชื่อพร็อพเพอร์ตี้แบบไดนามิกบนออบเจ็กต์ได้ เอกสารของ Mozilla เป็นแหล่งข้อมูลที่ดีและมีตัวอย่างที่ยอดเยี่ยมนี้

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

ฟังก์ชันลูกศรไขมัน

ฟังก์ชันลูกศรไขมันช่วยให้คุณเขียนฟังก์ชันแบบสั้นๆ ได้ในกรณีต่อไปนี้

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

เปลี่ยนเป็น:

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

นอกจากจะมีไวยากรณ์ที่สั้นกว่าแล้ว คุณลักษณะที่ยอดเยี่ยมอย่างหนึ่งของการใช้ฟังก์ชันลูกศรไขมันคือขอบเขตของวัตถุที่เป็นเช่นเดียวกับคำสั่งที่แนบมา ซึ่งหมายความว่าคุณไม่จำเป็นต้องเรียก .bind(this) ในฟังก์ชันหรือสร้าง var ที่ = this

มีตัวอย่างอื่นๆ อีกมากมายใน MDN

ที่เก็บเครื่องมือ ES6 ของ Addy

Addy ยุ่งอยู่กับการเก็บรายชื่อเครื่องมือของ ES2015 และหากเครื่องมือข้างต้นไม่เหมาะกับคุณ บางทีคุณอาจลองใช้ Grunt แทน Gulp นี่อาจมีคำตอบให้คุณ

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

ข้อมูลด้านบนยังรวมถึงลิงก์ไปยังเครื่องมือ Babel เพิ่มเติมที่ช่วยได้ในระหว่างการทดสอบหน่วยและส่วนอื่นๆ

หนังสือสำหรับอ่าน

มีหนังสือ 2 เล่มที่คุณดูได้ฟรีทางออนไลน์เพื่อเรียนรู้เกี่ยวกับ ES2015 ทำความเข้าใจเกี่ยวกับ ECMAScript 6 เขียนโดย Nicholas C. Zakas และ Exploring ES6 เขียนโดย Dr. Axel Rauschmayer

หอคอย Babel

หากสนใจเรียนรู้ฟีเจอร์ของ ES2015 ในบรรทัดคำสั่ง tower-of-babel มีชุดแบบฝึกหัดที่คุณอาจสนใจ ทุกคนใช้ Babel เพื่อศึกษา

แหล่งข้อมูลอื่นๆ หากสนใจ