Каков правильный подход к монорепозиторию javascript

Я пытаюсь найти правильный подход для монорепозитория javascript. Представьте монорепозиторий, содержащий пакеты/библиотеки:

root
  - node_modules
  - packages
      + lib-a
          * node_modules
      + lib-b
          * node_modules

Теперь предположим, что пакеты lib-a и lib-b используют webpack в качестве инструмента сборки.

я вижу два подхода

  1. Добавьте wepback в качестве зависимости к root. Включите скрипт "сборки" в оба пакета: "build": "webpack -p --config webpack.config.js. webpack.config.js может включать корень webpack.config.js. Затем я мог бы использовать такой инструмент, как lerna, для запуска сборки из корневого каталога (что означает, что двоичный файл webpack распознается. Однако я не смогу запустить сборку в определенных пакетах, поскольку webpack там недоступен. Я мог бы, вероятно, изменить скрипт сборки на что-то нравится "build": "../../node_modules/.bin/webpack -p --config webpack.config.js

  2. Всегда включайте webpack в каждый пакет. Это означает, что сценарий build завершится успешно. Это также означает, что каждый пакет будет иметь одинаковую зависимость, и мне, вероятно, следует следить за тем, чтобы каждый пакет использовал одну и ту же версию webpack.

По сути, я имею в виду, как должны быть структурированы пакеты внутри монорепозитория? Если какой-либо пакет опубликован, всегда должна быть возможность build этого пакета отдельно.


person user3056783    schedule 17.09.2019    source источник
comment
Наш монорепозиторий работает так, что каждый пакет имеет свои собственные модули узлов, но вы можете установить только те, которые вас интересуют и над которыми вы работаете. Затем у нас есть команда Build at root, которая в основном выполняет сборку во всех пакетах.   -  person Mederic    schedule 20.09.2019
comment
Таким образом, вы возлагаете ответственность за сборку на корневой пакет и запускаете оттуда команды сборки. Вроде бы правильный подход. Я думаю сделать это и для остальных команд (таких как тестирование, очистка и т. д.).   -  person user3056783    schedule 20.09.2019
comment
Вам следует заглянуть в lerna. В нем есть инструменты, которые помогут вам управлять монорепозиторием, а также автоматизировать определенные задачи, такие как связывание пакетов в вашем монорепозитории. Я использую lerna для своего монорепозитория, и он прекрасно работает.   -  person hwkd    schedule 26.09.2019
comment
Я думаю, было бы целесообразно изменить название этого вопроса на что-то вроде «Каков правильный подход к монорепозиторию javascript». Это поможет другим найти этот вопрос/ответ при поиске в Stackoverflow/Google.   -  person Jacek J    schedule 04.10.2019


Ответы (2)


Ваш подход №2 правильный. Вы обрабатываете каждый пакет отдельно, поскольку это был отдельный, автономный пакет.

Преимущество монорепозитория заключается не в совместном использовании файлов через структуру каталогов, а в следующем:

  1. Начальная загрузка всех зависимостей в единый node_modules с плоской структурой, эффективно их дедуплицирующая.
  2. Сделайте ваши пакеты доступными для других ваших пакетов через обычный пакет import/require(), поскольку они были внешними зависимостями. И, благодаря символическим ссылкам на node_modules, ваши пакеты "зависимостей" всегда содержат самый последний контент без публикации.
  3. Обеспечение последовательной, всегда актуальной структуры зависимостей во всех ваших пакетах. Как вы сказали: «Это также означает, что каждый пакет будет иметь одинаковую зависимость».
  4. Инструменты автоматизации для выполнения различных задач обслуживания (таких как сборка, публикация) для всех ваших пакетов с помощью одной команды.

Я знаю, что поначалу это не так просто, но когда вы копаетесь в документации Lerna, все становится более ясным. Помимо главной страницы, я рекомендую прочитать о подъем, Часто задаваемые вопросы и отдельные команды, такие как bootstrap и опубликовать.

person Jacek J    schedule 25.09.2019
comment
Я второй здесь все. Каждый пакет должен иметь возможность создавать и тестировать сам себя. Я рекомендую пряжу workspaces + lerna, но это не обязательно. Мы создали tsconfig и jest config корневого уровня, которые импортируются/расширяются отдельными пакетами. Мы также позволяем пользователю root позаботиться о линтинге для всех пакетов, husky — об хуках перед фиксацией, а commitizen — о согласованных сообщениях фиксации. - person Ryan Wheale; 07.10.2019

Наша текущая конфигурация такая же, как у вас:

root
  - node_modules
  - packages
      + lib-a
          * node_modules
      + lib-b
          * node_modules

Мы используем lerna для работы с нашим проектом: https://github.com/lerna/lerna

Вам просто нужно указать папку вашего пакета в lerna.json

{
  "lerna": "3.16.4",
  "packages": ["packages/*"],
  "version": "0.0.0",
  "npmClient": "yarn",
  "useWorkspaces": true
}

Затем в ваших сценариях package.json вы можете использовать строку:

"build": "lerna run build",

Это в основном запустит сборку во всех пакетах. Поэтому, если ваш скрипт сборки в каждом пакете имеет правильные параметры и установлен веб-пакет, он автоматически запустит сборку веб-пакета.

После этого вы можете просто работать в назначенных вам пакетах.

person Mederic    schedule 25.09.2019