Дослідіть можливості frontend monorepos за допомогою Lerna та Nx. Вивчіть управління робочим простором, обмін кодом та ефективні збірки для масштабних проєктів.
Frontend Monorepo: Керування робочим простором за допомогою Lerna та Nx
У постійно мінливому ландшафті frontend розробки, управління великими та складними проєктами може бути значним викликом. Традиційні налаштування з кількома репозиторіями, хоча й пропонують ізоляцію, можуть призвести до дублювання коду, головного болю з управління залежностями та непослідовного інструментарію. Саме тут сяє архітектура monorepo. Monorepo — це єдиний репозиторій, що містить кілька проєктів, часто пов’язаних, які збираються та версіонуються разом. Цей підхід пропонує численні переваги, але ефективне управління monorepo вимагає спеціалізованих інструментів. У цій статті розглядаються два популярні рішення: Lerna та Nx.
Що таке Monorepo?
Monorepo — це репозиторій системи контролю версій, який містить код для багатьох проєктів. Ці проєкти можуть бути пов’язані або повністю незалежні. Ключовим моментом є те, що вони використовують той самий репозиторій. Такі компанії, як Google, Facebook, Microsoft і Uber, успішно впровадили monorepos для управління своїми масивними кодовими базами. Уявіть собі, що Google зберігає майже весь свій код, включно з Android, Chrome і Gmail, в одному репозиторії.
Переваги Monorepo
- Обмін кодом і повторне використання: Легко обмінюйтеся кодом між проєктами без складних робочих процесів пакування та публікації. Уявіть собі бібліотеку системи дизайну, яку можна безперешкодно інтегрувати в кілька програм в одному репозиторії.
- Спрощене управління залежностями: Керуйте залежностями в одному місці, забезпечуючи узгодженість у всіх проєктах. Оновлення залежності спільної бібліотеки автоматично оновлює всі проєкти, які від неї залежать.
- Атомарні зміни: Вносьте зміни, які охоплюють кілька проєктів в одному коміті, забезпечуючи узгодженість і спрощуючи тестування. Наприклад, рефакторинг, який впливає як на frontend, так і на backend, можна виконати атомарно.
- Покращена співпраця: Команди можуть легко співпрацювати над різними проєктами в одному репозиторії, сприяючи обміну знаннями та міжфункціональній розробці. Розробники можуть легко переглядати та розуміти код у різних командах.
- Послідовний інструментарій і практики: Забезпечте узгоджені стандарти кодування, правила лінтингу та процеси збірки у всіх проєктах. Це покращує якість коду та зручність обслуговування.
- Спрощений рефакторинг: Масштабні проєкти рефакторингу спрощуються, оскільки весь пов’язаний код знаходиться в одному репозиторії. Інструменти автоматизованого рефакторингу можна використовувати для всієї кодової бази.
Проблеми Monorepo
- Розмір репозиторію: Monorepos можуть стати дуже великими, потенційно сповільнюючи клонування та індексацію. Такі інструменти, як `git sparse-checkout` і `partial clone`, можуть допомогти пом’якшити цю проблему.
- Час збірки: Збірка всього monorepo може зайняти багато часу, особливо для великих проєктів. Такі інструменти, як Lerna та Nx, пропонують оптимізовані процеси збірки для вирішення цієї проблеми.
- Контроль доступу: Обмеження доступу до певних частин monorepo може бути складним. Необхідне ретельне планування та впровадження механізмів контролю доступу.
- Складність інструментарію: Налаштування та управління monorepo вимагає спеціалізованого інструментарію та знань. Крива навчання спочатку може бути крутою.
Lerna: Управління проєктами JavaScript в Monorepo
Lerna — це популярний інструмент для управління проєктами JavaScript в monorepo. Він оптимізує робочий процес навколо управління багатопакетними репозиторіями за допомогою Git і npm. Він особливо добре підходить для проєктів, які використовують npm або Yarn для управління залежностями.
Основні функції Lerna
- Управління версіями: Lerna може автоматично версіонувати та публікувати пакети на основі змін, внесених з моменту останнього випуску. Він використовує звичайні коміти, щоб визначити наступний номер версії.
- Управління залежностями: Lerna обробляє залежності між пакетами, забезпечуючи, щоб пакети в monorepo могли залежати один від одного. Він використовує символічні посилання для створення локальних залежностей.
- Виконання завдань: Lerna може паралельно виконувати команди в кількох пакетах, прискорюючи процеси збірки та тестування. Він підтримує запуск сценаріїв, визначених у `package.json`.
- Виявлення змін: Lerna може виявити, які пакети змінилися з моменту останнього випуску, дозволяючи виконувати цільові збірки та розгортання.
Приклад використання Lerna
Проілюструємо використання Lerna на спрощеному прикладі. Припустимо, у нас є monorepo з двома пакетами: `package-a` і `package-b`. `package-b` залежить від `package-a`.
monorepo/
├── lerna.json
├── package.json
├── packages/
│ ├── package-a/
│ │ ├── package.json
│ │ └── index.js
│ └── package-b/
│ ├── package.json
│ └── index.js
1. Ініціалізуйте Lerna:
lerna init
Це створює `lerna.json` і оновлює кореневий `package.json`. Файл `lerna.json` налаштовує поведінку Lerna.
2. Встановіть залежності:
npm install
# or
yarn install
Це встановлює залежності для всіх пакетів у monorepo на основі файлів `package.json` у кожному пакеті.
3. Запустіть команду в пакетах:
lerna run test
Це виконує сценарій `test`, визначений у файлах `package.json` усіх пакетів, які його визначили.
4. Опублікуйте пакети:
lerna publish
Ця команда аналізує історію комітів, визначає, які пакети змінилися, підвищує їх версії на основі звичайних комітів і публікує їх в npm (або вибраному вами реєстрі).
Конфігурація Lerna
Файл `lerna.json` є серцем конфігурації Lerna. Він дозволяє налаштувати поведінку Lerna, наприклад:
- `packages`: визначає розташування пакетів у monorepo. Часто встановлюється на `["packages/*"]`.
- `version`: визначає стратегію версіонування. Може бути `independent` (кожен пакет має власну версію) або фіксованою версією.
- `command`: дозволяє налаштувати параметри для конкретних команд Lerna, таких як `publish` і `run`.
Приклад `lerna.json`:
{
"packages": [
"packages/*"
],
"version": "independent",
"npmClient": "npm",
"useWorkspaces": true,
"command": {
"publish": {
"conventionalCommits": true,
"message": "chore(release): publish"
}
}
}
Nx: Розумна, швидка та розширювана система збірки
Nx — це потужна система збірки, яка надає розширені функції для керування monorepo. Він зосереджується на інкрементних збірках, кешуванні обчислень і оркеструванні завдань, щоб значно покращити час збірки та продуктивність розробників. У той час як Lerna в основному зосереджена на управлінні пакетами, Nx надає більш комплексний підхід до управління всім робочим процесом monorepo, включаючи генерацію коду, лінтинг, тестування та розгортання.
Основні функції Nx
- Інкрементні збірки: Nx аналізує граф залежностей ваших проєктів і перебудовує лише ті проєкти, які змінилися з моменту останньої збірки. Це значно скорочує час збірки.
- Кешування обчислень: Nx кешує результати завдань, таких як збірки та тести, щоб їх можна було повторно використовувати, якщо вхідні дані не змінилися. Це ще більше прискорює цикли розробки.
- Оркестрування завдань: Nx надає потужну систему оркестрування завдань, яка дозволяє визначати складні конвеєри збірки та ефективно їх виконувати.
- Генерація коду: Nx надає інструменти для генерації коду, які можуть допомогти вам швидко створювати нові проєкти, компоненти та модулі, дотримуючись найкращих практик і узгоджених стандартів.
- Екосистема плагінів: Nx має багату екосистему плагінів, яка підтримує різні технології та фреймворки, такі як React, Angular, Node.js, NestJS тощо.
- Візуалізація графа залежностей: Nx може візуалізувати граф залежностей вашого monorepo, допомагаючи вам зрозуміти зв’язки між проєктами та виявити потенційні проблеми.
- Зачеплені команди: Nx надає команди для запуску завдань лише для тих проєктів, на які вплинула певна зміна. Це дозволяє зосередити свої зусилля на тих областях, які потребують уваги.
Приклад використання Nx
Проілюструємо використання Nx на спрощеному прикладі. Ми створимо monorepo з програмою React і бібліотекою Node.js.
1. Встановіть Nx CLI глобально:
npm install -g create-nx-workspace
2. Створіть новий робочий простір Nx:
create-nx-workspace my-monorepo --preset=react
cd my-monorepo
Це створить новий робочий простір Nx з програмою React. Опція `--preset=react` вказує Nx ініціалізувати робочий простір із конфігураціями, специфічними для React.
3. Згенеруйте бібліотеку:
nx generate @nrwl/node:library my-library
Це створить нову бібліотеку Node.js під назвою `my-library`. Nx автоматично налаштовує бібліотеку та її залежності.
4. Зберіть програму:
nx build my-app
Це збирає програму React. Nx аналізує граф залежностей і перебудовує лише необхідні файли.
5. Запустіть тести:
nx test my-app
Це запускає модульні тести для програми React. Nx кешує результати тестування, щоб прискорити наступні запуски тестів.
6. Перегляньте граф залежностей:
nx graph
Це відкриває веб-інтерфейс, який візуалізує граф залежностей monorepo.
Конфігурація Nx
Nx налаштовується за допомогою файлу `nx.json`, який знаходиться в корені робочого простору. Цей файл визначає проєкти в робочому просторі, їх залежності та завдання, які можна виконати над ними.
Ключові параметри конфігурації в `nx.json` включають:
- `projects`: визначає проєкти в робочому просторі та їх конфігурацію, наприклад їх кореневий каталог і цілі збірки.
- `tasksRunnerOptions`: налаштовує запускач завдань, який відповідає за виконання завдань і кешування їх результатів.
- `affected`: налаштовує спосіб визначення Nx, які проєкти зазнали впливу змін.
Приклад `nx.json`:
{
"npmScope": "my-org",
"affected": {
"defaultBase": "main"
},
"implicitDependencies": {
"package.json": {
"dependencies": "*",
"devDependencies": "*"
},
".eslintrc.json": "*"
},
"tasksRunnerOptions": {
"default": {
"runner": "nx-cloud",
"options": {
"cacheableOperations": ["build", "lint", "test", "e2e"],
"accessToken": "...",
"canTrackAnalytics": false,
"showUsageWarnings": false
}
}
},
"targetDefaults": {
"build": {
"dependsOn": ["^build"],
"inputs": ["production", "default"],
"outputs": ["{projectRoot}/dist"]
}
},
"namedInputs": {
"default": ["{projectRoot}/**/*", "!{projectRoot}/dist/**/*", "!{projectRoot}/tmp/**/*"],
"production": ["!{projectRoot}/**/*.spec.ts", "!{projectRoot}/**/*.spec.tsx", "!{projectRoot}/**/*.spec.js", "!{projectRoot}/**/*.spec.jsx"]
},
"generators": {
"@nrwl/react": {
"application": {
"style": "css",
"linter": "eslint",
"unitTestRunner": "jest"
},
"library": {
"style": "css",
"linter": "eslint",
"unitTestRunner": "jest"
},
"component": {
"style": "css"
}
},
}
}
Lerna vs. Nx: Що вибрати?
І Lerna, і Nx — чудові інструменти для управління frontend monorepos, але вони задовольняють дещо різні потреби. Ось порівняння, яке допоможе вам вибрати правильний для вашого проєкту:
| Функція | Lerna | Nx |
|---|---|---|
| Фокус | Управління пакетами | Система збірки та оркестрування завдань |
| Інкрементні збірки | Обмежено (потрібні зовнішні інструменти) | Вбудовано та високо оптимізовано |
| Кешування обчислень | Ні | Так |
| Генерація коду | Ні | Так |
| Екосистема плагінів | Обмежена | Широка |
| Крива навчання | Нижча | Вища |
| Складність | Простіша | Складніша |
| Випадки використання | Проєкти, які в основному зосереджені на управлінні та публікації пакетів npm. | Великі та складні проєкти, які потребують оптимізованого часу збірки, генерації коду та комплексної системи збірки. |
Виберіть Lerna, якщо:
- Вам в основному потрібно керувати та публікувати пакети npm.
- Ваш проєкт відносно малий до середнього розміру.
- Ви віддаєте перевагу простішому інструменту з нижчою кривою навчання.
- Ви вже знайомі з npm і Yarn.
Виберіть Nx, якщо:
- Вам потрібен оптимізований час збірки та інкрементні збірки.
- Вам потрібні можливості генерації коду.
- Вам потрібна комплексна система збірки з оркеструванням завдань.
- Ваш проєкт великий і складний.
- Ви готові витратити час на вивчення потужнішого інструменту.
Чи можна використовувати Lerna з Nx?
Так, Lerna та Nx можна використовувати разом. Ця комбінація дозволяє використовувати можливості Lerna для управління пакетами, одночасно отримуючи вигоду від оптимізованої системи збірки та оркестрування завдань Nx. Nx можна налаштувати як запускач завдань для Lerna, забезпечуючи інкрементні збірки та кешування обчислень для пакетів, якими керує Lerna.
Найкращі практики для управління Frontend Monorepo
Незалежно від того, чи виберете ви Lerna чи Nx, дотримання найкращих практик має вирішальне значення для успішного управління frontend monorepo:
- Встановіть чітку структуру проєкту: Упорядковуйте свої проєкти логічно та послідовно. Використовуйте чітку угоду про іменування пакетів і бібліотек.
- Забезпечте узгоджені стандарти кодування: Використовуйте лінтери та форматери, щоб забезпечити узгоджений стиль коду в усіх проєктах. Такі інструменти, як ESLint і Prettier, можна інтегрувати у ваш робочий процес.
- Автоматизуйте процеси збірки та тестування: Використовуйте конвеєри CI/CD для автоматизації процесів збірки, тестування та розгортання. Можна використовувати такі інструменти, як Jenkins, CircleCI та GitHub Actions.
- Впроваджуйте перевірку коду: Проводьте ретельні перевірки коду, щоб забезпечити якість коду та зручність обслуговування. Використовуйте запити на отримання та інструменти для перевірки коду.
- Відстежуйте час збірки та продуктивність: Відстежуйте час збірки та показники продуктивності, щоб визначити вузькі місця та сфери для покращення. Nx надає інструменти для аналізу продуктивності збірки.
- Документуйте структуру та процеси свого Monorepo: Створіть чітку документацію, яка пояснює структуру вашого monorepo, інструменти та технології, які використовуються, і робочі процеси розробки.
- Прийміть звичайні коміти: Використовуйте звичайні коміти для автоматизації процесів версіонування та випуску. Lerna підтримує звичайні коміти з коробки.
Висновок
Frontend monorepos пропонують значні переваги для управління великими та складними проєктами, включно з обміном кодом, спрощеним управлінням залежностями та покращеною співпрацею. Lerna та Nx — це потужні інструменти, які можуть допомогти вам ефективно керувати frontend monorepo. Lerna — чудовий вибір для управління пакетами npm, тоді як Nx надає більш комплексну систему збірки з розширеними функціями, такими як інкрементні збірки та генерація коду. Ретельно зваживши потреби вашого проєкту та дотримуючись найкращих практик, ви можете успішно впровадити frontend monorepo та скористатися його перевагами.
Не забудьте врахувати такі фактори, як досвід вашої команди, складність проєкту та вимоги до продуктивності, вибираючи між Lerna та Nx. Поекспериментуйте з обома інструментами та знайдіть той, який найкраще відповідає вашим конкретним потребам.
Успіхів у вашій monorepo подорожі!