Я уже некоторое время ищу и читаю связанную с этим информацию, но все еще не могу разобраться с этим.
Когда я создаю библиотеку или пакет с использованием машинописного текста, мне нравится устанавливать declaration
в true, так что когда компилятор ts скомпилирует исходный код, он автоматически сгенерирует файлы объявлений для меня.Типичная библиотека или пакет обычно имеет входной файл и набор файлов, зависящих друг от друга.Таким образом, выходные данные для результата сборки будут выглядеть так:
.
├── build
| ├── entry.js (or entry.min.js in production)
| ├── entry.d.ts (it depends on moduleA)
| ├── moduleA.d.ts (it depends on moduleB)
| ├── moduleB.d.ts
| ├── types.d.ts (contains shared types for every body)
| └── util.d.ts (declarations for some random util functions)
В package.json
я бы просто установил это:
{
...
"main": "./build/entry.js",
"types": "./build/entry.d.ts",
...
}
Проблема в том, что entry.js
имеетвсе API, которые я хотел бы представить потребителям, entry.d.ts
не имеет всех типов, которые я хотел бы также представить.Это потому, что, хотя entry.ts
имеет import
s из types.ts
, объявления типов не будут автоматически импортироваться из него.Потребитель может захотеть использовать некоторые перечисления, которые я хранил в types.ts
(таким образом types.d.ts
), а не в entry.ts
(таким образом entry.d.ts
).
Одним из способов использования типов является его повторный экспорт в файле ввода, например:
export * from './types';
// or
export { EnumA } from './types';
, что позволит потребителю сделать это:
import * as types from 'mylib';
// or
import { EnumA } from 'mylib';
Это то, чем я сейчас занимаюсь, это скорее ручной процесс, и есть большая вероятность, что я забуду экспортировать некоторые типы, которые потребителю действительно нужны для использования моей библиотеки.Я мог бы просто поместить все мои типы / интерфейсы / перечисления в один файл types.ts
и экспортировать все, но я не уверен, что это правильно. Команда машинописи
использует пространства имен для обработки этого(например, типы серверов и типы служб ), но IMO является избыточным, поскольку мы уже используем модули ES6.Подробнее об этом в этом посте Отличный пример чашки для объяснения пространств имен с модулями .
Еще один обходной путь - позволить потребителю сделать
import * as types from 'mylib/build/types'
Но IMO это тожеплохая практика, так как мы по существу раскрываем детали реализации потребителям, которые мы можем изменить в будущем.
Я также хочу добавить к вышесказанному, что если я хочу создать библиотеку для кодов ES5 со структурой commonjs или AMD, машинописный официальный документ говорит об использовании export =
.По-видимому, это больше не позволит вам использовать export * from './types'
, поэтому вышеуказанные обходные пути больше не будут работать.
Вот где я сейчас нахожусь.Какие-либо предложения?Сейчас я склоняюсь к использованию пространства имен, как это делают команды машинописи, но я хотел бы услышать больше мыслей.