TypeScript поддерживает работу с модулями. Модули являются концепцией, привнесенной стандартом ES2015. Модули в некотором смысле похожи на пространства имен: они могут заключать различные классы, интерфейсы, функции, объекты. Модули выделяются в отдельные файлы, что позволяет сделать код приложения более ясным и чистым, и в то же время позволяет использовать модули в других приложения.
В TypeScript, как и в стандарте ECMAScript 2015, любой файл, который содержит выражения import или export верхнего уровня, рассматривается как модуль. Модули выполняются не в глобальном контексте, а в своей собственной области видимости. То есть переменные, функции, классы. интерфейсы и т.д., определенные внутри модуля, не доступны извне, пока они не будут явным образом экспортированы. А чтобы другой модуль мог их использовать, он должен их импортировать.
Если файл не содержит выражений import или export верхнего уровня, он рассматривается как обычный скрипт, содержимое которого доступно в глобальной области видимости. Такие файлы можно склеить в один с помощью параметра компиляции --outFile , которому передается название выходного файла.
Чтобы сделать из простого скрипта модуль, достаточно добавить в файл
export {};
Этот модуль ничего не экспортирует, но тем не менее это модуль.
Все модули имеют определенный формат и относятся к определенном типу. Всего мы можем использовать следующие типы модулей:
AMD (Asynchronys Module Definition)
CommonJS (используется по умолчанию, если параметр --target
равен "ES3" или "ES5")
UMD (Universal Module Definition)
System
ES 2015
ES 2020
ESNext
Модули типов ES2015 и ES2020 практически одинаковы за тем исключение, что ES2020 имеет поддержку для динамического импорта и выражения импорта import.meta
.
Рассмотрим модули на примере модулей типа ES2015/ES2020, поскольку это один из наиболее популярных типов (наряду с CommonJS), кроме того, этот тип модулей современные браузеры поддерживают по умолчанию.
Определим простейший модуль. Для этого создадим файл message.ts, в котором определим следующий код:
export default function hello() { console.log("Hello Typescript"); }
Здесь определена обычная функция hello()
, которая выводит некоторое сообщение на консоль. Но она определена с ключевым словом export,
а это значит, что данный файл представляет модуль, а функцию hello()
можно импортировать в другие модули.
Кроме того, здесь применяется ключевое слово default, которое устанавливает тип, экспортируемый по умолчанию.
Теперь подключим эту функцию в другой файл. Для этого возьмем файл main.ts:
import hello from "./message.js"; hello();
Для подключения функционала из другого модуля применяется ключевое слово import, после которого идут названия подключаемых компонентов - в данном случае функция hello. Затем после оператора from указывается модуль, из которого идет импорт. В данном случае указываем "./message.js". В данном случае предполагается что оба скомпилированных модуля - main.js и message.js будут находиться в одной папке.
При компиляции из командной строки или терминала для установки модуля необходимо передать соответствующее значение параметру --module
:
tsc --module commonjs main.ts // для CommonJS tsc --module amd main.ts // для AMD tsc --module umd main.ts // для UMD tsc --module system main.ts // для SytemJS tsc --module esnext main.ts // для ESNext
В данном случае у нас оба модуля - main.ts и message.ts являются модулями ES, то есть в качестве типа модуля необходимо выбрать "ES2015", "ES2020" или "ESNext". Для данного конкретного случае не столь важно, какой именно из этих трех типов выбирать, поэтому выберем последний вариант.
Сначала перейдем в командной строке/консоли с помощью команды cd к папке, где расположены файлы main.ts и message.ts. Так, в моем случае они расположены в папке c:\typescript
Далее для компиляции модулей введем команду:
tsc main.ts --module esnext
После этого в папке появятся файлы main.js и message.js.
Для загрузки модулей определим в папке со скомпилированными файлами веб-страницу index.html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Metanit.com</title> </head> <body> <h2>Модули в TypeScript</h2> <script type="module" src="main.js"></script> </body> </html>
Для загрузки главного модуля приложения - main.js определяется элемент <script>
, у которого устанавливается атрибут type="module"
.
Загрузка модулей производится через AJAX, поэтому скомпилированные модули должны быть размещены на веб-сервере. То есть у нас не получится просто кинуть страницу в веб-браузер, как, например, это было в первых темах. Поэтому прежде всего надо определиться с веб-сервером. Веб-сервер может быть любым. В данном случае воспользуемся самым демократичным вариантом - Node.js. Но опять же вместо node.js это может быть любая другая технология сервера - php, asp.net, python и т.д. либо какой-то определенный веб-сервер типа Apache или IIS.
Итак, создадим в папке с файлами модулей файл сервера. Пусть он будет называться server.js и будет иметь следующий код:
const http = require("http"); const fs = require("fs"); http.createServer(function(request, response){ // получаем путь после слеша let filePath = request.url.substr(1); if(filePath == "") filePath = "index.html"; fs.readFile(filePath, function(error, data){ if(error){ response.statusCode = 404; response.end("Resourse not found!"); } else{ if(filePath.endsWith(".js")) response.setHeader("Content-Type", "text/javascript"); response.end(data); } }); }).listen(3000, function(){ console.log("Server started at 3000"); });
Это самый примитивный сервер, который отдает пользователю статические файлы. Для создания сервера применяется функция http.createServer()
,
а для считывания и отправки файлов - функция fs.readFile()
. Если имя файла не указано, то отправляется файл index.html
.
Сервер будет запускаться по адресу http://localhost:3000/
Стоит отметить, что при отправке модулей js нам надо устанавливать mime-тип отправляемого контента в "text/javascript"
:
if(filePath.endsWith(".js")) response.setHeader("Content-Type", "text/javascript");
Структура финального проекта:
Теперь запустим сервер с помощью команды
node server.js
После запуска сервера мы можем перейти в браузере по адресу http://localhost:3000, нам отобразится страница, а в консоли браузера мы сможем увидеть результат работы нашего кода на typescript:
Вместо того, чтобы указывать тип модуля в консоли при компиляции, можно использовать соответствующие параметры в файле конфигурации tsconfig.json. Так, параметр module задает тип модуля:
{ "compilerOptions": { "noImplicitAny": true, "noEmitOnError": true, "strictNullChecks": true, "outFile": "main.js" "target": "es2015", "module": "esnext" } }