Указание основного поля в package.json условно

#node.js #npm #yarnpkg #monorepo #yarn-workspaces

#node.js #npm #yarnpkg #monorepo #yarn-рабочие пространства

Вопрос:

У меня есть Monorepo под рабочими пространствами Lerna и Yarn. В репозитории есть пакеты, которые публикуются в npm и используются как за пределами monorepo, так и внутри monorepo. При разработке в monorepo мы хотели бы, чтобы main поле package.json для всех таких пакетов указывало на src каталог, в то время как при использовании пакета за пределами monorepo мы хотели бы, чтобы потребитель использовал перенесенный код в dist папке.

Я хочу, чтобы это было согласовано при всех видах использования пакетов, мое текущее решение состоит в том, чтобы main поле указывало на dist папку. Затем для каждого из инструментов в monorepo, а именно jest , tsc webpack , parcel src , dist мне пришлось придумать другое решение, специфичное для конкретного инструмента, для псевдонимирования в ,, каталоге вместо,,, каталога. Но мне не нравится тот факт, что мне приходилось выполнять эту работу для каждого из этих инструментов. Это просто не кажется масштабируемым.

Кто-нибудь предложил решение более низкого уровня, где модуль преобразуется в другую папку в зависимости от среды?

Спасибо.

Ответ №1:

Если ваша внутренняя кодовая база всегда переносит исходные тексты, почему бы просто не import { thing } from "my-package/src/main.js ?

Тогда вы можете просто оставить основное поле как dist для потребителей, которым в идеале не нужно отслеживать дополнительные пути при импорте ваших пакетов.

В вашем ответе оставлено много деталей, но предполагается, что вы используете один webpack / другой экземпляр для компиляции всех ваших пакетов.

Другой подход, поскольку вы уже подключили все свои пакеты через один и тот же этап компиляции, почему бы просто не использовать относительные пути между пакетами? Таким образом, вам никогда не придется выступать в роли потребителя, но с немного иными потребностями.

И, наконец, третий подход, который, я думаю, звучит немного запутанно, но должен делать именно то, о чем вы просите. Создайте скрипт, который использует globby или какой-либо другой пакет npm для захвата всех файлов package.json в вашем репозитории (исключая node_modules!). require() / выполните итерацию по этим файлам манифеста package.json и установите для основного поля входное значение (скажем, «dist»). Затем создайте два js-файла bin (подсказка: поле bin) с именами set-main-dist и set-main-src и, возможно, третий с именем unset-main.

Далее, независимо от того, какие скрипты вы запускаете в своих файлах package.json в корневом каталоге (или с помощью lerna run), убедитесь, что скрипт должен выглядеть следующим образом:

"prebuild": "set-main-src"

или вот так

"build": "set-main-src amp;amp; build etc"

Надеюсь, один из этих вариантов вам подойдет. Помните, что редко стоит идти против потока обычных шаблонов в tooling, а что нет. Сделайте так, чтобы это того стоило.

Ответ №2:

У меня была точно такая же дилемма, но с yarn3.

Решение, импортирующее всегда из исходного кода dint, сработало в моем случае, поскольку сам пакет также может быть опубликован в npm.

Итак, покопавшись, я, к счастью, нашел свойство package.json publishConfig.main https://yarnpkg.com/configuration/manifest#publishConfig

С его помощью я могу изменить основное поле с исходного на dist при публикации npm. В основном только для публикации мы используем модифицированный package.json.

Реализовано в моем package.json это выглядит следующим образом:

 {
   "main": "./src/index.ts",
   "publishConfig": {
     "main": "./dist/index.js"
   }
}
  

и когда я запущу yarn npm publish или yarn pack , main поле будет временно заменено на zip.
В то время как все мои инструменты (jest и ts) все еще могут полагаться на main поле, указывающее на источник.