Хорошо, я должен быть честным. Я не фанат монорепозиториев в целом. Я особенно не фанат организационных монорепозиций (если только у вас нет разветвленной версии github и команды разработчиков из 100 инженеров для управления ею, как в Facebook или Google).

Но есть кейсы для монорепозитория для проекта. Допустим, у вас есть многокомпонентная библиотека с внутренними зависимостями. Это тот случай. Еще одно практическое правило - в этом участвует не более 5 человек. Более того, дерьмо становится глупым. Также при использовании одновременно вы можете построить небольшую экосистему микросервисов и прочего в одном проекте (вот пример, который я сделал).

Эта статья проведет вас через создание бессмысленного маленького многокомпонентного проекта с Lerna. Это будет просто, и прикрыть начало работы. В нем будет отсутствовать куча вещей, но они будут самоуверенными. Вы можете исследовать это дерьмо самостоятельно. Вот так…

Давайте начнем с чистого листа и последуем разделу «Начало работы» из прочитанного мной Лерны.

Сделай это…

$ mkdir simple-monorepo && cd $_
$ npx lerna init

Люблю npx! Он позволяет запускать последнюю версию удаленного пакета npm без установки глобальной версии экземпляра, которая устареет примерно через месяц.

При этом будет настроен каталог packages, и вы получите разумный файл lerna.config и файл package.json. Он также инициализирует каталог с помощью git.

Давайте создадим правильный файл .gitignore с:

$ curl https://raw.githubusercontent.com/github/gitignore/master/Node.gitignore > .gitignore

Хорошо, давайте установим…

$ npm i

А теперь давайте добавим несколько пакетов! Добавьте свои каталоги с помощью:

$ mkdir packages/component-one && mkdir packages/component-two && mkdir packages/component-three

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

$ npm init -y

Поскольку в lerna.config по умолчанию указано, что все наши пакеты находятся в «packages / *», все каталоги, которые мы создали выше, теперь фактически являются пакетами в этом проекте lerna.

Lerna поставляется с утилитой exec, которая позволит вам запускать команду во всех ваших пакетах, поэтому давайте скопируем наш .gitignore в каждый проект с помощью:

$ npx lerna exec "cp ../../.gitignore ."

Довольно аккуратно!

Теперь давайте добавим некоторые зависимости разработчиков, которые понадобятся нам во всех наших проектах. Сначала отличный тестовый фреймворк tape:

$ npx lerna add tape --dev

Далее замечательный линтер стандарт:

$ npx leran add standard --dev

Теперь каждый из наших файлов package.json должен выглядеть так:

{
  "name": "component-[one|two|three]",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "standard": "^14.3.1",
    "tape": "^4.11.0"
  }
}

Ура! Мы в пути! Но хорошо, допустим, компонент-один зависит от компонента-два, который зависит от компонента три, ЧТО?!?!

Довольно просто:

$ npx lerna add component-two packages/component-one/
$ npx lerna add component-three packages/component-two/

Теперь в package.json первого компонента есть…

"dependencies": {
  "component-two": "^1.0.0"
}

… И в файле package.json компонента-два есть…

"dependencies": {
  "component-three": "^1.0.0"
}

…А ТАКЖЕ! Лерна загрузила все вещи так, чтобы все они были правильно связаны. НЕАТО !! Это также можно использовать для установки внешних зависимостей в конкретный пакет, например:

$ npx lerna add debug packages/component-one/

Но давайте это докажем. В третьем компоненте и файле index.js есть следующее:

module.exports = (text) => `UPPER-CASED BY COMPONENT THREE >> "${text}"`.toLocaleUpperCase()

Довольно просто. Теперь во втором компоненте добавьте файл index.js со следующим:

const componentThree = require('component-three')
module.exports = (text) => `*** decorated by component-two: "${componentThree(text)}" ***`

Видеть, что! Никакой ерунды "../../../ чего-то". Просто настоящая живая библиотека компонентов. А теперь давайте начнем с приложения в первом компоненте. Создайте файл index.js с:

const componentTwo = require('component-two')
console.log(componentTwo('This is component one!'))

О, мальчик, это становится ХОРОШО !!!

теперь давайте запустим!

$ node packages/component-one/index.js

Мы должны увидеть…

*** decorated by component-two: "UPPER-CASED BY COMPONENT THREE >> "THIS IS COMPONENT ONE!"" ***

Ура!

Но ждать?!? Что происходит, когда я вставляю это в свое репо, и кому-то приходится его загружать. После того, как они клонируют ваше репо, они могут просто:

$ npm i && npx lerna bootstrap

Это установит Lerna в корневом репозитории, а затем использует загрузочную программу lerna для установки всех зависимостей (внутренних и внешних) в каждом из пакетов !! Ой!

А если нужно убрать…

$ npx lerna clean

Удалит каталоги node_moudule, если вы хотите повторно запустить bootstrap для переустановки материалов.

Ссылки на примеры репозиториев