Как мне контролировать, какую версию Yarn выбирает для peerDependency зависимости при использовании рабочих пространств Yarn / nohoist?

У меня есть рабочее пространство Yarn с двумя пакетами watermelon-web и watermelon-native, в которых используется последняя версия react-redux, но разные версии react. Проблема в том, что я не могу контролировать, какую версию react Yarn выбирает для peerDependency react-redux.

Рабочее пространство package.json:

{
    "private": true,
    "workspaces": {
        "packages": [
            "watermelon-web",
            "watermelon-native"
        ],
        "nohoist": [            
            "**/watermelon-native/react-redux"
        ]
    }
}

(nohoist требуется для предотвращения ошибки времени выполнения)

watermelon-web/package.json:

{
  "name": "watermelon-web",
  "dependencies": {
    "react": "^16.12.0",
    "react-redux": "^7.1.3"
  }
}

watermelon-native/package.json:

{
  "name": "watermelon-native",
  "dependencies": {
    "react": "16.8.3",
    "react-redux": "^7.1.3"
  }
}

Между тем, react-redux имеет равноправную зависимость "react": "^16.8.3".

Что я хочу сделать: после установки Yarn watermelon-native/node_modules/react-redux/node_modules НЕ содержит react. Таким образом, когда react-redux пытается импортировать react во время выполнения, он получит [email protected] от watermelon-native/node_modules.

Что происходит на самом деле: Yarn устанавливается [email protected] в watermelon-native/node_modules/react-redux/node_modules. Когда я запускаю watermelon-native, React сообщает «Неверный вызов ловушки», потому что watermelon-native использует [email protected], но react-redux использует [email protected]. (Оба пакета должны использовать один и тот же экземпляр React для работы хуков React.)

Как заставить Yarn работать так, как я хочу?

Я пробовал использовать селективные разрешения зависимости пряжи, также известные как "разрешения "элемент в package.json, почти всеми возможными способами, но не было заметных изменений в поведении Yarn. Например, я пробовал добавить

"resolutions": {
    "**/watermelon-native/react-redux/react": "16.8.3"
}

в рабочее пространство package.json.

Двумя простыми «решениями» были бы использование одной и той же версии React во всех моих пакетах (потребуется понижение версии с watermelon-web до 16.8.3) или отказ от использования рабочих пространств Yarn. У каждого из них есть недостатки, которых я бы по возможности избегал.

(Примечание: мои примеры кода взяты из разработки React Native, но сам вопрос относится только к Yarn и не имеет ничего общего с React. react и react-redux могут быть заменены любыми другими пакетами, которые имеют достаточно похожие зависимости.)


person Sam Magura    schedule 26.11.2019    source источник


Ответы (1)


Я думаю, что ответ на вопрос: «Пряжа так не работает», по крайней мере, на данный момент.

А пока я нашел простой обходной путь. Поскольку удаление папки react из watermelon-native/node_modules/react-redux/node_modules/react решает проблему, я добавил postinstall сценарий, который удаляет эту react папку после каждой установки.

Мой сценарий PowerShell (используйте любую оболочку, которая вам нравится)

function TryRemove-Path($path) {
    if(Test-Path $path) {
        Remove-Item -Recurse -Force $path
    }
}


TryRemove-Path("$PSScriptRoot/node_modules/react-redux/node_modules/react")

Это довольно хитроумно, но даже проект Expo полагается на магию после установки., чтобы их приложения React Native могли работать с рабочими пространствами yarn. Так что, возможно, этот обходной путь не так уж и плох.

person Sam Magura    schedule 04.12.2019