[Перевод] Карманная книга по TypeScript. Часть 8. Модули

@
image

Мы продолжаем серию публикаций адаптированного и дополненного перевода "Карманной книги по TypeScript".

Другие части:

Обратите внимание: для большого удобства в изучении книга была оформлена в виде прогрессивного веб-приложения.

Определение модуля

В TS, как и в ECMAScript2015, любой файл, содержащий import или export верхнего уровня (глобальный), считается модулем.

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

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

Не модули

Для начала, давайте разберемся, что TS считает модулем. Спецификация JS определяет, что любой файл без export или await верхнего уровня является скриптом, а не модулем.

Переменные и типы, объявленные в скрипте, являются глобальными (имеют глобальную область видимости), для объединения нескольких файлов на входе в один на выходе следует использовать либо настроку компилятора outFile, либо несколько элементов script в разметке (указанных в правильном порядке).

Если у нас имеется файл, который не содержит import или export, но мы хотим, чтобы этот файл считался модулем, просто добавляем в него такую строку:

Модули в TS

Существует 3 вещи, на которые следует обращать внимание при работе с модулями в TS:

  • Синтаксис: какой синтаксис я хочу использовать для импорта и экспорта сущностей?
  • Разрешение модулей: каковы отношения между названиями модулей (или их путями) и файлами на диске?
  • Результат: на что должен быть похож код модуля?

Синтаксис

Основной экспорт в файле определяется с помощью export default:

Затем данная функция импортируется следующим образом:

В дополнению к экспорту по умолчанию, из файла может экспортироваться несколько переменных и функций с помощью export (без default):

Указанные сущности импортируются так:

Дополнительный синтаксис импорта

Название импортируемой сущности можно менять с помощью import { old as new }:

Разные способы импорта можно смешивать:

Все экспортированные объекты при импорте можно поместить в одно пространство имен с помощью * as name:

Файлы можно импортировать без указания переменных:

В данном случае import ничего не делает. Тем не менее, весь код из maths.ts вычисляется (оценивается), что может привести к запуску побочных эффектов, влияющих на другие объекты.

Специфичный для TS синтаксис модулей

Типы могут экспортироваться и импортироваться с помощью такого же синтаксиса, что и значения в JS:

TS расширяет синтаксис import с помощью import type, что позволяет импортировать только типы.

Такой импорт сообщает транспиляторам, вроде Babel, swc или esbuild, какой импорт может быть безопасно удален.

Синтаксис ES-модулей с поведением CommonJS

Синтаксис ES-модулей в TS напрямую согласуется с CommonJS и require из AMD. Импорт с помощью ES-модулей в большинстве случаев представляет собой тоже самое, что require в указанных окружениях, он позволяет обеспечить полное совпадение TS-файла с результатом CommonJS:

Синтаксис CommonJS

CommonJS — это формат, используемый большинством npm-пакетов. Даже если вы используете только синтаксис ES-модулей, понимание того, как работает CommonJS, поможет вам в отладке приложений.

Экспорт

Идентификаторы экпортируются посредством установки свойства exports глобальной переменной module:

Затем эти файлы импортируются с помощью инструкции require:

В данном случае импорт можно упростить с помощью деструктуризации:

Взаимодействие CommonJS с ES-модулями

Между CommonJS и ES-модулями имеется несовпадение, поскольку ES-модули поддерживают "дефолтный" экспорт только объектов, но не функций. Для преодоления данного несовпадения в TS используется флаг компиляции esModuleInterop.

Настройки, связанные с разрешением модулей

Разрешение модулей — это процесс определения файла, указанного в качестве ссылки в строке из инструкции import или require.

TS предоставляет две стратегии разрешения модулей: классическую и Node. Классическая стратегия является стратегией по умолчанию (когда флаг module имеет значение, отличное от commonjs) и включается для обеспечения обратной совместимости. Стратегия Node имитирует работу Node.js в режиме CommonJS с дополнительными проверками для .ts и .d.ts.

Существует большое количество флагов, связанных с разрешением модулей: moduleResolution, baseUrl, paths, rootDirs и др.

Настройки для результатов разрешения модулей

Имеется две настройки, которые влияют на результирующий JS-код:

  • target — определяет версию JS, в которую компилируется TS-код
  • module — определяет, какой код используется для взаимодействия модулей между собой

То, какую цель (target) использовать, зависит от того, в какой среде будет выполняться код (какие возможности поддерживаются этой средой). Это может включать в себя поддержку старых браузеров, более низкую версию Node.js или специфические ограничения, накладываемые такими средами выполнения, как, например, Electron.

Коммуникация между модулями происходит через загрузчик модулей (module loader), определяемый в настройке module. Во время выполнения загрузчик отвечает за локализацию и установку всех зависимостей модуля перед его выполнением.

Ниже приведено несколько примеров использования синтаксиса ES-модулей с разными настройками module:

ES2020

CommonJS

UMD

Пространства имен (namespaces)

TS имеет собственный модульный формат, который называется namespaces. Данный синтаксис имеет множество полезных возможностей по созданию сложных файлов определений и по-прежнему активно используется в DefinitelyTyped. Несмотря на то, что namespaces не признаны устаревшими (deprecated), большая часть его возможностей нашла воплощение в ES-модулях, поэтому настоятельно рекомендуется использовать официальный синтаксис.

VPS серверы от Маклауд быстрые и безопасные.

Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации!

Данные о правообладателе фото и видеоматериалов взяты с сайта «Хабрахабр», подробнее в Правилах сервиса
Анализ
×