Пользователь
0,0
рейтинг
11 июля 2014 в 00:50

Разработка → JavaScript модули перевод tutorial

Перевод статьи «JavaScript Modules» с сайта jsmodules.io.

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

Создание модуля


В качестве упражнения, мы построим простой asap модуль, который позволит назначать выполнение действий «как только так сразу» асинхронным образом. В Node.js, вы можете сделать это при помощи process.nextTick, есть и разные подходы, которые работают во многих браузерах. Мы создадим модуль, который будет работать в любом окружении.1

Начнем с создания нового файла для нашего модуля. Назовём его asap.js. Модуль предоставляет единственную функцию, что называется экспорт по умолчанию(default export). Вы можете делать экспорт по умолчанию при помощи конструкции export default.
var asap;
var isNode = typeof process !== "undefined" &&
             {}.toString.call(process) === "[object process]";

if (isNode) {
  asap = process.nextTick;
} else if (typeof setImmediate !== "undefined") {
  asap = setImmediate;
} else {
  asap = setTimeout;
}

export default asap;

Импорт модуля


Чтобы импортировать asap из другого модуля, мы используем следующий синтаксис:
import asap from "asap";

asap(function() {
  console.log("hello async world!");
});

Эта конструкция принимает дефолтную функцию экспортированную модулем asap и хранит в переменной asap, которую мы позже можем вызвать.

Именованный экспорт


Иногда модули должны экcпортировать несколько вещей, которые можно использовать по имени.

Например, в jQuery есть один главный экспорт (функция jQuery) и несколько дополнительных именованных экспортов (ajax, getJSON, animate и пр.). В модуле Node.js mkdirp есть экспорт по умолчанию, который создает директорию и именованный экспорт под названием sync, который делает то же, но синхронно.

В нашем случае, в дополнение к экспорту по умолчанию, asap модуль может также предоставлять функцию later, которая назначает выполнение кода на момент, когда другие сетевые или UI процессы уже произошли.

Наш модуль выглядит так же, кроме того, что мы добавили новое объявление экспорта.
var asap;
var isNode = typeof process !== "undefined" &&
             {}.toString.call(process) === "[object process]";

if (isNode) {
  asap = process.nextTick;
} else if (typeof setImmediate !== "undefined") {
  asap = setImmediate;
} else {
  asap = setTimeout;
}

export default asap;
export var later = isNode ? process.setImmediate : asap;

Именованный импорт


Теперь, когда мы экспортировали later, мы можем импортировать его в другом модуле.
import { later } from "asap";

later(function() {
  console.log("Running after other network events");
});

Для любопытных, вы можете импортировать экспорт по умолчанию и именованные экспорты одной инструкцией импорта:
import asap, { later } from "asap";

И это все, что нужно сделать!

Удобства


Переименование именованного импорта

Иногда, импортируя именованный экспорт, вам нужно дать ему собственное локальное имя.
import { unlink as rm } from "fs";

rm(filename, function(err) { /* check errors */ });

Импорт в пространство имен

Может быть удобным, импортировать все именованные экспорты модуля в единственное локальное пространство имен2.
import * as fs from "fs";

fs.unlink(filename, function(err) { /* check errors */ });

Сокращенный способ экспорта

Вы можете делать любое объявление в JavaScript (например var или function) именованным экспортом предваряя его ключевым словом export.
// exports this function as "requestAnimationFrame"
export function requestAnimationFrame() {
  // cross-browser requestAnimationFrame
}

// exports document.location as "location"
export var location = document.location; 

Это также работает для новых объявлений, например class или let
// exports this class as "File"
export class File() { /* implementation */ }

// exports "0.6.3" as "VERSION"
export let VERSION = "0.6.3";

Эти имена также доступны в локальной области видимости модуля, так что вы можете использовать их и в других функциях модуля.
Группирование экспорта

Вы можете экспортировать любое количество локальных переменных одной инструкцией.
function getJSON() {
  // implementation
}

function postJSON() {
  // implementation
}

function animate() {
  // implementation
}

Групповое объявление экспорта можно поместить в любом месте файла, так вы можете размещать импорт и экспорт друг за другом, вверху модуля.

Особенности


JavaScript модули имеют несколько приятных особенностей, которые упрощают их использование и рефакторинг.
  • JavaScript модули поддерживают отложенное связывание между модулями, как для именованного экспорта так и для экспорта по умолчанию. Оно просто работает.
  • JavaScript модули разделяют имена существующие в экспорте по умолчанию (и цепочках прототипов) и другим именованным экспортом, предотвращая конфликты.
  • С JavaScript модулями проще определить, что именно вы импортируете просто посмотрев на синтаксис. Это улучшает сообщения об ошибках, а также упрощает создание таких инструментов, как browserify или JSHint, которые должны работать надежно.

Примечания


1 Для реального использования данный модуль должен бы быть более детализированным, но для нашего примера этого достаточно.
2 Примечание переводчика: похоже, что импорт в пространство имен будет выглядеть следующим образом module fs from "fs";
Перевод: jsmodules.io
Йосиф Крошный @jojo97
карма
14,2
рейтинг 0,0
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (10)

  • +6
    Оригинальный текст статьи довольно сложный, поэтому я попытался упрощать по мере возможности. Если есть какие-то конкретные замечания буду рад услышать и исправить.
  • 0
    Отличная статья, спасибо. Вот еще любопытная ссылка
  • 0
    Вместо этого import * as fs from "fs"; будет так module fs from "fs";.
    По крайней мере в текущем черновике.
    • +1
      Может вы и правы. Точного подтверждения, что в ECMAScript 6 так и будет, я не получил. Думаю это еще может измениться.
  • 0
    > В новой версии JavaScript
    В какой?
    • 0
      В оригинале не пишет, но я полагаю, что речь идет о ECMAScript 6
  • 0
    вдохновленная идеей модулей Node.js.

    Более верно говорить о стандартах Commonjs, которые частично реализованы в Node
    • 0
      Да, на сайте статьи есть даже сравнение с Commonjs, но в самом тексте именно о ноде писалось
  • 0
    "… вы можете импортировать экспорт по умолчанию и несколько именованных экспорта одной инструкцией импорта… " за перевод спасибо, в целом понятно. но это предолжение на ночь мне стоило читать
    • 0
      Спасибо, кое-как исправил, пишите если есть лучше идеи)

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