Метапакеты
Часто с возрастом появляется желание иметь пакет для пакетов — положить в него всё нужное и накатывать одной командой. Чтобы он привозил и eslint, и prettier и browserslist. Вот только npm не предназначен для метапакетов. npm не гарантирует, что транзитивные зависимости будут лежать плоско на первом уровне. Вот вообще не гарантирует. А пакеты на это завязываются.
Классика — проблемы с плагинами eslint которые не могут лежать, на втором уровне. Ну ок, это кажется починили в новой системе конфигов (я ещё не попроовал).
Или вот
Предположим такую схему зависимостей:
Предположим у вас npm 6 или вы работаете в режиме
Вроде не страшно?
А теперь делаем
Всё сломалось!
Да, если у вас npm 7 и выше и вы перешли на новую работу с peerDeps то получите
Может быть. А может повезёт и оно дедупнется. Гарантий нет. В этом и проблема метапакетов. Они не дают гарантий, транзитивные зависимости нельзя магически превратить в зависимости первого уровня.
Что тут можно сделать? Ну, например, написать скрипт, который контролирует версии базовых зависимостей и сам делает пул-реквесты по их поднятию. Либо остаться на мета-пакете и очень внимательно следить за структурой.
Часто с возрастом появляется желание иметь пакет для пакетов — положить в него всё нужное и накатывать одной командой. Чтобы он привозил и eslint, и prettier и browserslist. Вот только npm не предназначен для метапакетов. npm не гарантирует, что транзитивные зависимости будут лежать плоско на первом уровне. Вот вообще не гарантирует. А пакеты на это завязываются.
Классика — проблемы с плагинами eslint которые не могут лежать, на втором уровне. Ну ок, это кажется починили в новой системе конфигов (я ещё не попроовал).
Или вот
browserslist-useragent
перенёс browserslist
в peerDependencies. Что это значит? Где тут проблемы метапакетов?Предположим такую схему зависимостей:
dependencies
<метапакет>
browserslist-useragent: 4.2.2
browserslist: 4.2.2
devDependencies
webpack
browserslist: 4.1.1
Предположим у вас npm 6 или вы работаете в режиме
--legacy-peer-deps
. Ставим зависимости и оказываемся в ситуации
node_modules
<метапакет>
node_modules
browserslist: 4.2.2
webpack
browserslist: 4.1.1
browserslist-useragent: 4.2.2
Вроде не страшно?
А теперь делаем
npm prune --production
node_modules
<метапакет>
node_modules
browserslist: 4.2.2
browserslist-useragent: 4.2.2
Всё сломалось!
browserslist-useragent
больше не видит browserslist
и падает.Да, если у вас npm 7 и выше и вы перешли на новую работу с peerDeps то получите
node_modules
<метапакет>
node_modules
browserslist: 4.2.2
browserslist-useragent: 4.2.2
node_modules
browserslist: 4.2.2
Может быть. А может повезёт и оно дедупнется. Гарантий нет. В этом и проблема метапакетов. Они не дают гарантий, транзитивные зависимости нельзя магически превратить в зависимости первого уровня.
Что тут можно сделать? Ну, например, написать скрипт, который контролирует версии базовых зависимостей и сам делает пул-реквесты по их поднятию. Либо остаться на мета-пакете и очень внимательно следить за структурой.