#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
поле, указывающее на источник.