Монорепо Node.js TypeScript через рабочие пространства NPM

Монорепо сейчас в моде. Современные проекты используют NX для создания монорепо. Но зачем внедрять такой сложный инструмент в свой технологический стек, если зачастую достаточно чего-то простого?

И Yarn, и NPM включают в свой набор функций управление рабочими пространствами. Таким образом, вы можете управлять несколькими проектами в одном рабочем пространстве. Кроме того, один из инструментов всегда доступен в вашем проекте, так почему бы не использовать его?

Фантастический проект

Вы работаете над фантастическим проектом, который вы случайно назвали fantastic. Как креативно, не правда ли?

fantastic — это приложение командной строки, которое покажет, как настроить монорепо TypeScript с помощью рабочих пространств NPM. Проект fantastic имел огромный успех как приложение CLI, и многие пользователи хотели иметь графический интерфейс для его использования. Поэтому вы решили создать веб-интерфейс. В настоящее время ваш код находится в одном модуле, содержащем основную логику и точку входа CLI.

Поэтому вы решили разделить проект на три отдельных пакета:

Инициализация проекта

Давайте создадим пустой каталог и инициализируем пакет NPM:

mkdir fantastic
cd fantastic
npm init -y
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь создадим пакеты:

npm init -y --scope @fantastic -w packages/core
npm init -y --scope @fantastic -w packages/web
npm init -y --scope @fantastic -w packages/cli
Войти в полноэкранный режим Выйти из полноэкранного режима

Определите зависимости между пакетами:

npm install @fantastic/core -w @fantastic/web
npm install @fantastic/core -w @fantastic/cli
Войти в полноэкранный режим Выйти из полноэкранного режима

Протестируйте!

Теперь, когда у нас есть основа, давайте добавим немного кода для тестирования:

packages/core/index.js

console.log("Hello from Core!");
Войти в полноэкранный режим Выход из полноэкранного режима

packages/web/index.js

require("@fantastic/core");
console.log("Hello from Web!");
Войти в полноэкранный режим Выход из полноэкранного режима

packages/cli/index.js

require("@fantastic/core");
console.log("Hello from CLI!");
Войти в полноэкранный режим Выход из полноэкранного режима

Запуск CLI выводит следующее:

node packages/cli/index.js
Войти в полноэкранный режим Выход из полноэкранного режима
Hello from Core!
Hello from CLI!
Войти в полноэкранный режим Выход из полноэкранного режима

Это подтверждает, что установка работает нормально.

А вот и TypeScript

Пора перевести этот проект с JavaScript на TypeScript!

Прежде всего, установите typescript в качестве dev-зависимости в проект рабочей области:

npm install -D typescript
Войдите в полноэкранный режим Выйти из полноэкранного режима

Каждый пакет требует свой собственный файл tsconfig.json. Поскольку проект fantastic использует одну и ту же конфигурацию для всех трех пакетов, создайте общий файл tsconfig.base.json в корневом каталоге.

tsconfig.base.json

{
  "compilerOptions": {
    "incremental": true,
    "target": "es2020",
    "module": "commonjs",
    "declaration": true,
    "sourceMap": true,
    "strict": true,
    "moduleResolution": "node",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,

    "composite": true
  }
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Это обычный файл tsconfig.json, за исключением одной опции компилятора: composite. Эта опция позволяет TypeScript быстро определить, был ли проект уже собран.

Теперь у вас есть общий файл конфигурации TS, но вы его еще не используете. Создайте файл tsconfig.json в корневом каталоге каждого пакета:

packages/core/tsconfig.json

{
  "extends": "../../tsconfig.base.json"
}
Войдите в полноэкранный режим Выйти из полноэкранного режима

Пакеты cli и web немного отличаются. Вам нужно перечислить все ваши зависимости в свойстве references:

packages/cli/tsconfig.json и packages/web/tsconfig.json

{
  "extends": "../../tsconfig.base.json",
  "references": [{ "path": "../core" }]
}
Войдите в полноэкранный режим Выйти из полноэкранного режима

Теперь, когда независимые пакеты настроены, создайте tsconfig.json в корневом каталоге:

tsconfig.json

{
  "files": [],
  "references": [
    { "path": "packages/core" },
    { "path": "packages/cli" },
    { "path": "packages/web" }
  ]
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Пустой массив files указывает TypeScript игнорировать все файлы, кроме тех, что находятся в ссылках.

Переименуйте все файлы .js в .ts и замените require на import:

require("@fantastic/core");
Вход в полноэкранный режим Выход из полноэкранного режима

на

import "@fantastic/core";
Войти в полноэкранный режим Выйти из полноэкранного режима

Вы готовы к компиляции:

npx tsc --build
Войти в полноэкранный режим Выйти из полноэкранного режима

Флаг --build необходим, поскольку проект содержит несколько проектов.

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

$ node packages/cli/index.js
Hello from Core!
Hello from CLI!

$ node packages/web/index.js
Hello from Core!
Hello from Web!
Войти в полноэкранный режим Выйдите из полноэкранного режима

Разделение исходного кода и вывода сборки

Прежде всего, удалите все выходные данные сборки из предыдущего шага. Следующая команда удалит все файлы .js, .js.map, .d.ts и .tsbuildinfo в каталоге packages.

rm packages/**/{*.js,*.js.map,*.d.ts,*.tsbuildinfo}
Вход в полноэкранный режим Выход из полноэкранного режима

Размещение исходного кода и вывода сборки в разных каталогах является хорошей практикой. Поэтому переместите исходный код каждого пакета в каталог src, а каталог вывода сборки измените на dist.

Расширьте ваши файлы packages/*/tsconfig.json следующим фрагментом:

  "compilerOptions": {
    "rootDir": "src",
    "outDir": "dist"
  },
Войти в полноэкранный режим Выйти из полноэкранного режима

В качестве примера, вот как теперь выглядит packages/web/tsconfig.json:

{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "dist"
  },
  "references": [{ "path": "../core" }]
}
Вход в полноэкранный режим Выход из полноэкранного режима

Это сообщает TypeScript, что ваши файлы исходного кода находятся в каталоге src, а вывод сборки должен находиться в каталоге dist. Эти данные относятся к вашему файлу tsconfig.json.

Переместите файлы index.ts в соответствующий каталог src. На данном этапе у вас должно быть следующее дерево каталогов:

├── package-lock.json
├── package.json
├── packages
│   ├── cli
│   │   ├── package.json
│   │   ├── src
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── core
│   │   ├── package.json
│   │   ├── src
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   └── web
│       ├── package.json
│       ├── src
│       │   └── index.ts
│       └── tsconfig.json
├── tsconfig.base.json
└── tsconfig.json
Вход в полноэкранный режим Выход из полноэкранного режима

Перед сборкой проекта настройте свойство main в package.json каждого пакета. Измените index.js на dist/index.js, поскольку именно там он сейчас находится.

Теперь соберите свой проект и запустите CLI-приложение:

npx tsc --build
node packages/cli/dist/index.js
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Вы должны увидеть обычный результат:

Hello from Core!
Hello from CLI!
Войти в полноэкранный режим Выйти из полноэкранного режима

Вы сделали это! Отличная работа!

Теперь, когда вы заложили основу для своего проекта, продолжайте и создайте что-то необычное!

Исходный код проекта доступен на GitHub. Репозиторий содержит несколько небольших изменений. Не стесняйтесь, изучайте!

Если вы хотите узнать больше о рабочих пространствах NPM и TypeScript, посмотрите эти ссылки:

  • Документация по NPM Workspaces
  • Документация по TypeScript Project References

PS. NX — это потрясающий инструмент! Но иногда лучше использовать инструменты, которые уже есть в вашем распоряжении. Пожалуйста, не торопитесь принимать решение об использовании NX или рабочих пространств NPM / Yarn.

Оцените статью
devanswers.ru
Добавить комментарий