ES6 модули (ECMAScript 6 modules)

В этой статье сделан обзор системы модулей в ES6.

Старая система модулей JavaScript

В JavaScript нет встроенной поддержки модулей, но сообщество создало несколько прекрасных решений этой проблемы. Среди самых популярных можно выделить два таких:

Система модулей CommonJS: предпочтительно для использования в Node.js

Особенности:
– компактный синтаксис
– спроектировано для синхронной загрузки зависимостей
– главная среда использование – бек-енд

Asynchronous Module Definition, более известен как AMD

Самой популярной реализацией является библиотека RequireJS
Особенности:
– более сложный синтаксис, позволяющий работать AMD, без использования eval() (или этапа компиляции)
– спроектировано для асинхронной загрузки зависимостей
– в большинстве случаев используется в клиентском JS

ES6 модули

Основная цель ECMAScript 6 модулей создание единый формат для тех, кто использует CommonJS и AMD.
Стандарт ES6 модулей делится на две части:
– декларативный синтаксис для импорта и экспорта
– программный API – для настройки того как модули загружаются и опциональной загрузки.
Есть два типа экспортов: именованные и по умолчанию(default)
Модуль может экспортировать несколько сущностей просто указав слово export перед определением функции, класса, переменной. Эти экспорты можно различить по их именам, по тому они называются named exports.

// utils.js
import * as moment from "moment";
export function getUtcTimeStamp(x) {
    return moment().utc().valueOf();
}
export function tomorrowTimestamp() {
    return moment.utc().add(1, "days").hours(0).minutes(0).seconds(0).millisecond(0).valueOf();
}

//controller.js
import { getUtcTimeStamp, tomorrowTimestamp } from 'util';
console.log(getUtcTimeStamp()); // 1513003142000
console.log(tomorrowTimestamp()); // 1513036800000

В примере ниже показывается как загрузить весь модуль и присвоить ему какое-то имя

//controller.js
import * as util from 'util';
console.log(util.getUtcTimeStamp()); // 1513003142000
console.log(util.tomorrowTimestamp()); // 1513036800000

Эквивалентный код с использованием синтаксиса CommonJS будет выглядеть так

// utils.js
const moment =require("moment");
function getUtcTimeStamp(x) {
    return moment().utc().valueOf();
}
function tomorrowTimestamp() {
    return moment.utc().add(1, "days").hours(0).minutes(0).seconds(0).millisecond(0).valueOf();
}
//controller.js
var getUtcTimeStamp=require("utils.js").getUtcTimeStamp;
var tomorrowTimestamp=require("utils.js").tomorrowTimestamp;
console.log(getUtcTimeStamp()); // 1513003142000
console.log(tomorrowTimestamp()); // 1513036800000
   

Default export

Модули, которые экспортируют только одно значение довольно популярны в Node.js сообществе. Также они популярны в фронт-енд разработке, где часто используется практика один класс на модуль.
Пример default export

// Controller.js
export default class { ... };

//index.js
import Controller from 'Controller';
let ctrl=new Controller();

Одновременное использование named и default экспортов

Этот паттерн очень популярен в JavaScript. Библиотека это одна функция, а все дополнительные сервисы предоставляются через через свойства этой функции. Библиотеки jQuery, Underscore.js используют этот шаблон.


Структура Underscore.js с использованием CommonJS

//underscore.js
var _ = function (obj) {
    // library code
};
var each = _.each = _.forEach =
    function (object, iter, ctx) {
        ...
    };
module.exports = _;
};
//index.js
var _ = require('underscore');
var forEach = _.forEach;

Если использовать ES6 модули, то функция _ это dafault экспорт, а each и forEach именованные экспорты. И как оказалось можно использовать два типа экспортов одновременно.

Underscore.js EcmaScript 6 version

//underscore.js
export  default  function (obj) {
    // library code
};
export function forEach (object, iter, ctx) {
        ...
    };
export { forEach as each };
};
//index.js
import _, { forEach } from 'underscore';

С первого взгляда обе версии выглядят одинаково, но ES6 версия имеет плоскую структуру, а CommonJS вложенную. Что делает возможным статический анализ кода.

Заключение

ECMAScript 6 модули имеют компактный синтаксис, статическую структуру модулей, решают проблему несовместимости стандартов CommonJS и AMD

 

nazarmsx

 

Leave a Reply

Your email address will not be published. Required fields are marked *