[Разработка веб-сайтов, TypeScript] Карманная книга по TypeScript. Часть 8. Модули (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Мы продолжаем серию публикаций адаптированного и дополненного перевода "Карманной книги по TypeScript".
Другие части:
- Часть 1. Основы
- Часть 2. Типы на каждый день
- Часть 3. Сужение типов
- Часть 4. Подробнее о функциях
- Часть 5. Объектные типы
- Часть 6. Манипуляции с типами
- Часть 7. Классы
Определение модуля
В TS, как и в ECMAScript2015, любой файл, содержащий import или export верхнего уровня (глобальный), считается модулем.
Файл, не содержащий указанных ключевых слов, является глобальным скриптом.
Модули выполняются в собственной области видимости, а не в глобальной. Это означает, что переменные, функции, классы и т.д., объявленные в модуле, недоступны за пределами модуля до тех пор, пока они в явном виде не будут из него экспортированы. Кроме того, перед использованием экспортированных сущностей, их следует импортировать в соответствующий файл.
Не модули
Для начала, давайте разберемся, что TS считает модулем. Спецификация JS определяет, что любой файл без export или await верхнего уровня является скриптом, а не модулем.
Переменные и типы, объявленные в скрипте, являются глобальными (имеют глобальную область видимости), для объединения нескольких файлов на входе в один на выходе следует использовать либо настроку компилятора outFile, либо несколько элементов script в разметке (указанных в правильном порядке).
Если у нас имеется файл, который не содержит import или export, но мы хотим, чтобы этот файл считался модулем, просто добавляем в него такую строку:
export {}
Модули в TS
Существует 3 вещи, на которые следует обращать внимание при работе с модулями в TS:
- Синтаксис: какой синтаксис я хочу использовать для импорта и экспорта сущностей?
- Разрешение модулей: каковы отношения между названиями модулей (или их путями) и файлами на диске?
- Результат: на что должен быть похож код модуля?
Синтаксис
Основной экспорт в файле определяется с помощью export default:
// @filename: hello.ts
export default function helloWorld() {
console.log('Привет, народ!')
}
Затем данная функция импортируется следующим образом:
import hello from './hello.js'
hello()
В дополнению к экспорту по умолчанию, из файла может экспортироваться несколько переменных и функций с помощью export (без default):
// @filename: maths.ts
export var pi = 3.14
export let squareTwo = 1.41
export const phi = 1.61
export class RandomNumberGenerator {}
export function absolute(num: number) {
if (num < 0) return num * -1
return num
}
Указанные сущности импортируются так:
import { pi, phi, absolute } from './maths.js'
console.log(pi)
const absPhi = absolute(phi)
// const absPhi: number
Дополнительный синтаксис импорта
Название импортируемой сущности можно менять с помощью import { old as new }:
import { pi as π } from './maths.js'
console.log(π)
/*
(alias) var π: number
import π
*/
Разные способы импорта можно смешивать:
// @filename: maths.ts
export const pi = 3.14
export default class RandomNumberGenerator {}
// @filename: app.ts
import RNGen, { pi as π } from './maths.js'
RNGen
/*
(alias) class RNGen
import RNGen
*/
console.log(π)
/*
(alias) const π: 3.14
import π
*/
Все экспортированные объекты при импорте можно поместить в одно пространство имен с помощью * as name:
// @filename: app.ts
import * as math from './maths.js'
console.log(math.pi)
const positivePhi = math.absolute(math.phi)
// const positivePhi: number
Файлы можно импортировать без указания переменных:
// @filename: app.ts
import './maths.js'
console.log('3.14')
В данном случае import ничего не делает. Тем не менее, весь код из maths.ts вычисляется (оценивается), что может привести к запуску побочных эффектов, влияющих на другие объекты.
Специфичный для TS синтаксис модулей
Типы могут экспортироваться и импортироваться с помощью такого же синтаксиса, что и значения в JS:
// @filename: animal.ts
export type Cat = { breed: string, yearOfBirth: number }
export interface Dog {
breeds: string[]
yearOfBirth: number
}
// @filename: app.ts
import { Cat, Dog } from './animal.js'
type Animals = Cat | Dog
TS расширяет синтаксис import с помощью import type, что позволяет импортировать только типы.
// @filename: animal.ts
export type Cat = { breed: string, yearOfBirth: number }
// 'createCatName' cannot be used as a value because it was imported using 'import type'.
// 'createCatName' не может использоваться в качестве значения, поскольку импортируется с помощью 'import type'
export type Dog = { breeds: string[], yearOfBirth: number }
export const createCatName = () => 'fluffy'
// @filename: valid.ts
import type { Cat, Dog } from './animal.js'
export type Animals = Cat | Dog
// @filename: app.ts
import type { createCatName } from './animal.js'
const name = createCatName()
Такой импорт сообщает транспиляторам, вроде Babel, swc или esbuild, какой импорт может быть безопасно удален.
Синтаксис ES-модулей с поведением CommonJS
Синтаксис ES-модулей в TS напрямую согласуется с CommonJS и require из AMD. Импорт с помощью ES-модулей в большинстве случаев представляет собой тоже самое, что require в указанных окружениях, он позволяет обеспечить полное совпадение TS-файла с результатом CommonJS:
import fs = require('fs')
const code = fs.readFileSync('hello.ts', 'utf8')
Синтаксис CommonJS
CommonJS — это формат, используемый большинством npm-пакетов. Даже если вы используете только синтаксис ES-модулей, понимание того, как работает CommonJS, поможет вам в отладке приложений.
Экспорт
Идентификаторы экпортируются посредством установки свойства exports глобальной переменной module:
function absolute(num: number) {
if (num < 0) return num * -1
return num
}
module.exports = {
pi: 3.14,
squareTwo: 1.41,
phi: 1.61,
absolute
}
Затем эти файлы импортируются с помощью инструкции require:
const maths = require('maths')
maths.pi
// any
В данном случае импорт можно упростить с помощью деструктуризации:
const { squareTwo } = require('maths')
squareTwo
// const squareTwo: any
Взаимодействие 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:
import { valueOfPi } from './constants.js'
export const twoPi = valueOfPi * 2
ES2020
import { valueOfPi } from './constants.js'
export const twoPi = valueOfPi * 2
CommonJS
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.twoPi = void 0;
const constants_js_1 = require("./constants.js");
exports.twoPi = constants_js_1.valueOfPi * 2;
UMD
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "./constants.js"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.twoPi = void 0;
const constants_js_1 = require("./constants.js");
exports.twoPi = constants_js_1.valueOfPi * 2;
});
Пространства имен (namespaces)
TS имеет собственный модульный формат, который называется namespaces. Данный синтаксис имеет множество полезных возможностей по созданию сложных файлов определений и по-прежнему активно используется в DefinitelyTyped. Несмотря на то, что namespaces не признаны устаревшими (deprecated), большая часть его возможностей нашла воплощение в ES-модулях, поэтому настоятельно рекомендуется использовать официальный синтаксис.
VPS серверы от Маклауд быстрые и безопасные.
Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации!
оригинал
===========
Источник:
habr.com
===========
===========
Автор оригинала: The TypeScript Handbook
===========Похожие новости:
- [Разработка веб-сайтов, JavaScript] Идеальный инструмент для создания прогрессивных веб-приложений или Все, что вы хотели знать о Workbox. Часть 1
- [Высокая производительность, Разработка веб-сайтов, MySQL, Go, Big Data] Как мы весь интернет сканировали
- [Разработка под Android, История IT, Смартфоны] Android: 12 лет истории дизайна ОС (перевод)
- [Облачные вычисления, Облачные сервисы] Руководство по пограничным вычислениям для архитектора. Самое важное (перевод)
- [Лайфхаки для гиков, Здоровье] Как подружиться со своей интернет-зависимостью: практическое руководство (перевод)
- [Управление разработкой, DevOps] Процесс — это не продукт: антиманифест методологии разработки ПО (перевод)
- [Информационная безопасность, Читальный зал, История IT] Имя им — легион. Самые громкие акции Anonymous
- [Научно-популярное, Финансы в IT, Транспорт] Как ажиотажный спрос на туалетную бумагу привел к дефициту электроники
- [CSS, JavaScript, ReactJS, TypeScript] Темизация. История, причины, реализация
- [Разработка веб-сайтов, Программирование, Haskell, Функциональное программирование] Создаем веб-приложение на Haskell с использованием Reflex. Часть 4
Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_typescript, #_vds, #_vps, #_typescript_kniga_po_typescript (typescript книга по typescript), #_osnovy (основы), #_blog_kompanii_maklaud (
Блог компании Маклауд
), #_razrabotka_vebsajtov (
Разработка веб-сайтов
), #_typescript
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 25-Ноя 05:10
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Мы продолжаем серию публикаций адаптированного и дополненного перевода "Карманной книги по TypeScript". Другие части:
Определение модуля В TS, как и в ECMAScript2015, любой файл, содержащий import или export верхнего уровня (глобальный), считается модулем. Файл, не содержащий указанных ключевых слов, является глобальным скриптом. Модули выполняются в собственной области видимости, а не в глобальной. Это означает, что переменные, функции, классы и т.д., объявленные в модуле, недоступны за пределами модуля до тех пор, пока они в явном виде не будут из него экспортированы. Кроме того, перед использованием экспортированных сущностей, их следует импортировать в соответствующий файл. Не модули Для начала, давайте разберемся, что TS считает модулем. Спецификация JS определяет, что любой файл без export или await верхнего уровня является скриптом, а не модулем. Переменные и типы, объявленные в скрипте, являются глобальными (имеют глобальную область видимости), для объединения нескольких файлов на входе в один на выходе следует использовать либо настроку компилятора outFile, либо несколько элементов script в разметке (указанных в правильном порядке). Если у нас имеется файл, который не содержит import или export, но мы хотим, чтобы этот файл считался модулем, просто добавляем в него такую строку: export {}
Модули в TS Существует 3 вещи, на которые следует обращать внимание при работе с модулями в TS:
Синтаксис Основной экспорт в файле определяется с помощью export default: // @filename: hello.ts
export default function helloWorld() { console.log('Привет, народ!') } Затем данная функция импортируется следующим образом: import hello from './hello.js'
hello() В дополнению к экспорту по умолчанию, из файла может экспортироваться несколько переменных и функций с помощью export (без default): // @filename: maths.ts
export var pi = 3.14 export let squareTwo = 1.41 export const phi = 1.61 export class RandomNumberGenerator {} export function absolute(num: number) { if (num < 0) return num * -1 return num } Указанные сущности импортируются так: import { pi, phi, absolute } from './maths.js'
console.log(pi) const absPhi = absolute(phi) // const absPhi: number Дополнительный синтаксис импорта Название импортируемой сущности можно менять с помощью import { old as new }: import { pi as π } from './maths.js'
console.log(π) /* (alias) var π: number import π */ Разные способы импорта можно смешивать: // @filename: maths.ts
export const pi = 3.14 export default class RandomNumberGenerator {} // @filename: app.ts import RNGen, { pi as π } from './maths.js' RNGen /* (alias) class RNGen import RNGen */ console.log(π) /* (alias) const π: 3.14 import π */ Все экспортированные объекты при импорте можно поместить в одно пространство имен с помощью * as name: // @filename: app.ts
import * as math from './maths.js' console.log(math.pi) const positivePhi = math.absolute(math.phi) // const positivePhi: number Файлы можно импортировать без указания переменных: // @filename: app.ts
import './maths.js' console.log('3.14') В данном случае import ничего не делает. Тем не менее, весь код из maths.ts вычисляется (оценивается), что может привести к запуску побочных эффектов, влияющих на другие объекты. Специфичный для TS синтаксис модулей Типы могут экспортироваться и импортироваться с помощью такого же синтаксиса, что и значения в JS: // @filename: animal.ts
export type Cat = { breed: string, yearOfBirth: number } export interface Dog { breeds: string[] yearOfBirth: number } // @filename: app.ts import { Cat, Dog } from './animal.js' type Animals = Cat | Dog TS расширяет синтаксис import с помощью import type, что позволяет импортировать только типы. // @filename: animal.ts
export type Cat = { breed: string, yearOfBirth: number } // 'createCatName' cannot be used as a value because it was imported using 'import type'. // 'createCatName' не может использоваться в качестве значения, поскольку импортируется с помощью 'import type' export type Dog = { breeds: string[], yearOfBirth: number } export const createCatName = () => 'fluffy' // @filename: valid.ts import type { Cat, Dog } from './animal.js' export type Animals = Cat | Dog // @filename: app.ts import type { createCatName } from './animal.js' const name = createCatName() Такой импорт сообщает транспиляторам, вроде Babel, swc или esbuild, какой импорт может быть безопасно удален. Синтаксис ES-модулей с поведением CommonJS Синтаксис ES-модулей в TS напрямую согласуется с CommonJS и require из AMD. Импорт с помощью ES-модулей в большинстве случаев представляет собой тоже самое, что require в указанных окружениях, он позволяет обеспечить полное совпадение TS-файла с результатом CommonJS: import fs = require('fs')
const code = fs.readFileSync('hello.ts', 'utf8') Синтаксис CommonJS CommonJS — это формат, используемый большинством npm-пакетов. Даже если вы используете только синтаксис ES-модулей, понимание того, как работает CommonJS, поможет вам в отладке приложений. Экспорт Идентификаторы экпортируются посредством установки свойства exports глобальной переменной module: function absolute(num: number) {
if (num < 0) return num * -1 return num } module.exports = { pi: 3.14, squareTwo: 1.41, phi: 1.61, absolute } Затем эти файлы импортируются с помощью инструкции require: const maths = require('maths')
maths.pi // any В данном случае импорт можно упростить с помощью деструктуризации: const { squareTwo } = require('maths')
squareTwo // const squareTwo: any Взаимодействие 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) использовать, зависит от того, в какой среде будет выполняться код (какие возможности поддерживаются этой средой). Это может включать в себя поддержку старых браузеров, более низкую версию Node.js или специфические ограничения, накладываемые такими средами выполнения, как, например, Electron. Коммуникация между модулями происходит через загрузчик модулей (module loader), определяемый в настройке module. Во время выполнения загрузчик отвечает за локализацию и установку всех зависимостей модуля перед его выполнением. Ниже приведено несколько примеров использования синтаксиса ES-модулей с разными настройками module: import { valueOfPi } from './constants.js'
export const twoPi = valueOfPi * 2 ES2020 import { valueOfPi } from './constants.js'
export const twoPi = valueOfPi * 2 CommonJS "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); exports.twoPi = void 0; const constants_js_1 = require("./constants.js"); exports.twoPi = constants_js_1.valueOfPi * 2; UMD (function (factory) {
if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "./constants.js"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.twoPi = void 0; const constants_js_1 = require("./constants.js"); exports.twoPi = constants_js_1.valueOfPi * 2; }); Пространства имен (namespaces) TS имеет собственный модульный формат, который называется namespaces. Данный синтаксис имеет множество полезных возможностей по созданию сложных файлов определений и по-прежнему активно используется в DefinitelyTyped. Несмотря на то, что namespaces не признаны устаревшими (deprecated), большая часть его возможностей нашла воплощение в ES-модулях, поэтому настоятельно рекомендуется использовать официальный синтаксис. VPS серверы от Маклауд быстрые и безопасные. Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации! оригинал =========== Источник: habr.com =========== =========== Автор оригинала: The TypeScript Handbook ===========Похожие новости:
Блог компании Маклауд ), #_razrabotka_vebsajtov ( Разработка веб-сайтов ), #_typescript |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 25-Ноя 05:10
Часовой пояс: UTC + 5