Ссылки на проекты
Ссылки на проекты — это новая функция в TypeScript 3.0, которая позволяет структурировать программы TypeScript в более мелкие части.
Это позволяет значительно улучшить время сборки, обеспечить логическое разделение компонентов и организовать код новыми и лучшими способами.
Мы также внедряем новый режим для tsc, флаг --build, который работает в тандеме со ссылками на проекты, чтобы ускорить сборку TypeScript.
Пример проекта
Давайте рассмотрим довольно обычную программу и посмотрим, как ссылки на проекты помогут нам лучше ее организовать. Представьте, что у вас есть проект с двумя модулями, converter и units, и соответствующий тестовый файл для каждого:
/ ├── src/ │ ├── converter.ts │ └── units.ts ├── test/ │ ├── converter-tests.ts │ └── units-tests.ts └── tsconfig.json
Тестовые файлы импортируют файлы реализации и выполняют некоторое тестирование:
// converter-tests.ts import * as converter from "../src/converter"; assert.areEqual(converter.celsiusToFahrenheit(0), 32);
Ранее эта структура была довольно неудобной в работе, если вы использовали один файл tsconfig:
- Файлы реализации могли импортировать тестовые файлы
- Не было возможности собрать
testиsrcодновременно без появленияsrcв имени выходной папки, чего вы, вероятно, не хотите - Изменение только внутренностей в файлах реализации требовало проверки типов тестов снова, даже если это никогда не вызывало новых ошибок
- Изменение только тестов требовало повторной проверки типов реализации, даже если ничего не изменилось
Вы могли использовать несколько файлов tsconfig, чтобы решить некоторые из этих проблем, но появятся новые:
- Нет встроенной проверки обновлений, поэтому вы всегда запускаете
tscдважды - Вызов
tscдважды влечет за собой дополнительные затраты на время запуска -
tsc -wне может работать с несколькими конфигурационными файлами одновременно
Ссылки на проекты могут решить все эти проблемы и многое другое.
Что такое ссылка на проект?
Файлы tsconfig.json имеют новое свойство верхнего уровня, references. Это массив объектов, определяющий проекты для ссылки:
{
"compilerOptions": {
// The usual
},
"references": [
{ "path": "../src" }
]
} Свойство path каждой ссылки может указывать на каталог, содержащий файл tsconfig.json , или на сам конфигурационный файл (который может иметь любое имя).
При ссылке на проект происходят новые вещи:
- Импорт модулей из проекта, на который ссылаются, загрузит вместо этого его объявление выходного файла (
.d.ts) - Если проект, на который ссылаются, создает
outFile, объявления выходного файла.d.tsбудут видны в этом проекте - Режим сборки (см. ниже) автоматически соберет проект, на который ссылаются, если это необходимо
Разделение на несколько проектов значительно повышает скорость проверки типов и компиляции, уменьшает использование памяти при использовании редактора и улучшает соблюдение логических группировок вашей программы.
composite
Проекты, на которые ссылаются, должны иметь включенное новое значение composite. Эта настройка необходима, чтобы TypeScript мог быстро определить, где найти выходные данные проекта, на который ссылаются. Включение флага composite изменяет несколько вещей:
- Настройка
rootDir, если явно не задана, по умолчанию равна каталогу, содержащему файлtsconfig - Все файлы реализации должны соответствовать шаблону
includeили быть перечислены в массивеfiles. Если это ограничение нарушено,tscсообщит вам, какие файлы не были указаны -
declarationдолжен быть включен
declarationMap
Мы также добавили поддержку карты исходных данных объявлений. Если вы включите declarationMap, вы сможете использовать такие функции редактора, как «Перейти к определению» и «Переименовать», чтобы прозрачно перемещаться и редактировать код через границы проектов в поддерживаемых редакторах.
prepend с outFile
Вы также можете включить предварение вывода зависимости, используя параметр prepend в ссылке:
"references": [
{ "path": "../utils", "prepend": true }
] Предварение проекта включит вывод проекта над выводом текущего проекта. Все выходные файлы (.js, .d.ts, .js.map, .d.ts.map) будут правильно выведены.
tsc будет использовать только существующие файлы на диске для выполнения этого процесса, поэтому возможно создание проекта, где правильный выходной файл не может быть сгенерирован, потому что вывод некоторых проектов будет присутствовать более одного раза в результирующем файле. Например:
A ^ ^ / \ B C ^ ^ \ / D
В этой ситуации важно не предвариантно на каждой ссылке, потому что вы получите две копии A в выводе D - это может привести к неожиданным результатам.
Ограничения для ссылок на проекты
Ссылки на проекты имеют несколько компромиссов, о которых вам следует знать.
Поскольку зависимые проекты используют файлы .d.ts, которые созданы на основе их зависимостей, вам придется либо включить определенные выходные данные сборки, либо собрать проект после клонирования его, прежде чем вы сможете перейти к проекту в редакторе, не видя ложных ошибок.
При использовании VS Code (с TS 3.7) у нас есть скрытый процесс генерации .d.ts в памяти, который должен устранить это, но это влияет на производительность. Для очень больших составных проектов вы можете отключить это с помощью опции disableSourceOfProjectReferenceRedirect.
Кроме того, для сохранения совместимости с существующими рабочими процессами сборки tsc не будет автоматически собирать зависимости, если не вызван параметр --build. Давайте узнаем больше о --build.
Режим сборки для TypeScript
Долгожданная функция — это интеллектуальная инкрементальная сборка для проектов TypeScript. В версии 3.0 вы можете использовать флаг --build с tsc. Это фактически новая точка входа для tsc, которая ведет себя скорее как диспетчер сборки, чем простой компилятор.
Запуск tsc --build (tsc -b для краткости) выполнит следующие действия:
- Найти все зависимые проекты
- Определить, являются ли они актуальными
- Собрать устаревшие проекты в правильном порядке
Вы можете предоставить tsc -b несколько путей к файлам конфигурации (например, tsc -b src test). Так же как и tsc -p, указание имени файла конфигурации не требуется, если оно названо tsconfig.json.
Командная строка tsc -b
Вы можете указать любое количество файлов конфигурации:
> tsc -b # Use the tsconfig.json in the current directory > tsc -b src # Use src/tsconfig.json > tsc -b foo/prd.tsconfig.json bar # Use foo/prd.tsconfig.json and bar/tsconfig.json
Не беспокойтесь о порядке файлов, которые вы передаете в командной строке — tsc переупорядочит их при необходимости, чтобы зависимости всегда собирались первыми.
Также есть некоторые флаги, специфичные для tsc -b:
-
--verbose: Выводит подробную информацию для объяснения происходящего (может быть объединен с любым другим флагом) -
--dry: Показ того, что будет сделано, но ничего не собирает -
--clean: Удаление выходных данных указанных проектов (может быть объединен с--dry) -
--force: Считать все проекты устаревшими -
--watch: Режим наблюдения (не может быть объединен ни с каким флагом, кроме--verbose)
Ограничения
В нормальном режиме tsc будет генерировать выходные данные (.js и .d.ts в присутствии синтаксических или типовых ошибок, если не включен noEmitOnError. Делать это в системе инкрементальной сборки было бы очень плохо — если бы одна из ваших устаревших зависимостей имела новую ошибку, вы бы увидели ее только один раз, потому что последующая сборка пропустит сборку теперь актуального проекта. По этой причине tsc -b фактически действует так, как если бы noEmitOnError был включен для всех проектов.
Если вы включаете любые выходные данные сборки (.js, .d.ts, .d.ts.map, и т. д.), вам может потребоваться выполнить сборку с параметром --force после определенных операций с системой контроля версий, в зависимости от того, сохраняет ли ваш инструмент системы контроля версий временные метки между локальной копией и удаленной копией.
MSBuild
Если у вас есть проект msbuild, вы можете включить режим сборки, добавив
<TypeScriptBuildMode>true</TypeScriptBuildMode>
в ваш файл проекта. Это включит автоматическую инкрементальную сборку и очистку.
Обратите внимание, что, как и в случае с tsconfig.json / -p, существующие свойства проекта TypeScript не будут учитываться — все параметры должны управляться с помощью файла tsconfig.
Некоторые команды создали рабочие процессы на основе msbuild, в которых файлы tsconfig имеют одинаковый неявный порядок графика с управляемыми проектами, с которыми они сопряжены. Если ваша структура похожа, вы можете продолжить использование msbuild с tsc -p вместе со ссылками на проекты; они полностью совместимы.
Рекомендации
Общая структура
При наличии большего количества файлов tsconfig.json, как правило, рекомендуется использовать наследование файла конфигурации для централизации общих параметров компилятора. Таким образом, вы можете изменить параметр в одном файле, вместо того чтобы редактировать несколько файлов.
Еще один хороший подход — создать файл «solution» tsconfig.json, в котором просто указаны references для всех ваших проектов-листовых узлов и задано files в виде пустого массива (иначе файл solution вызовет двойную компиляцию файлов). Обратите внимание, что начиная с версии 3.0, пустой массив files больше не является ошибкой, если у вас хотя бы один reference в файле tsconfig.json.
Это представляет собой простой входной пункт; например, в репозитории TypeScript мы просто запускаем tsc -b src для построения всех конечных точек, так как мы перечисляем все подпроекты в src/tsconfig.json
Вы можете увидеть эти шаблоны в репозитории TypeScript — см. src/tsconfig_base.json, src/tsconfig.json, и src/tsc/tsconfig.json в качестве ключевых примеров.
Структурирование для модулей с относительными путями
В общем случае для перехода на использование модулей с относительными путями не требуется много изменений. Просто поместите файл tsconfig.json в каждую поддиректорию заданного родительского каталога и добавьте reference в эти конфигурационные файлы, чтобы соответствовать предполагаемому структурированию программы. Вам необходимо либо установить outDir в явную подпапку выходного каталога, либо установить rootDir в общий корень всех папок проектов.
Структурирование для outFiles
Макет для компиляции с использованием outFile более гибкий, потому что относительные пути не так важны. Важно помнить, что вы, как правило, не должны использовать prepend до «последнего» проекта — это улучшит время сборки и уменьшит объем ввода-вывода при каждом построении. Репозиторий TypeScript сам по себе является хорошей отправной точкой — у нас есть некоторые проекты «библиотеки» и некоторые проекты «конечных точек»; проекты «конечных точек» держатся как можно меньше и подключают только необходимые библиотеки.
© 2012-2023 Microsoft
Licensed under the Apache License, Version 2.0.
https://www.typescriptlang.org/docs/handbook/project-references.html