Как правильно включить React как в приложение, так и в частную библиотеку? (Предупреждение React Invalid Hook Call от дублированного React) - PullRequest
0 голосов
/ 30 мая 2020

У меня есть своего рода «монорепозиторий», один большой проект, состоящий из нескольких небольших проектов, использующих React.

Я пытаюсь разбить их на три отдельных репозитория, давайте назовем их Core, Application1 и Application2

Core является зависимостью обоих приложений, а Core зависит от React, поскольку он определяет некоторые классы компонентов React. Оба приложения также используют React.

Когда я попытался собрать все это вместе (используя пакет Parcel), я получил последний пакет, который во время выполнения выдает предупреждение Invalid Hook Call в одном (но не оба) приложений.

На этой странице (или в сообщении об ошибке) говорится, что ошибка могла быть вызвана одной из следующих причин:

  1. Возможно, у вас несовпадающие версии React и React DOM.
  2. Возможно, вы нарушаете правила хуков.
  3. У вас может быть несколько копий React в одном приложении.

Я проверил, что # 1 неверно, и я даже не использую хуки каким-либо образом, о котором мне известно, поэтому проблема, похоже, заключается в нескольких версиях React.

Прочитав об этом, я понял, что моя Core библиотека ошибочно объявила React как зависимость и вместо этого должна объявить ее в peerDependencies. Это заставило приложение перестать выдавать ошибку, но также привело к тому, что моя основная библиотека начала иметь кучу ошибок Typescript и не могла запускать модульные тесты (которые полагаются на React, используя Jest / Enzyme для визуализации и проверки DOM).

Поскольку указание React в peerDependencies привело к тому, что он не был установлен в node_modules из Core, я решил, что мне, вероятно, следует включить React как в peerDependencies, так и в devDependencies из Core. Это снова исправляет базовую библиотеку, но ломает приложение.

Я не совсем уверен в следующем:

  • Почему одно из моих приложений не работает из-за дублирования копий React, а другое нет, так как они кажутся довольно симметричными друг другу.
  • Почему, хотя я указываю React только в peerDependencies и devDepenencies в Core, я все равно получу дублирующую копию React в зависимом приложении
  • Используется ли метод для внесение Core в приложение не имеет к этому никакого отношения. (Один из методов, который я пробую, - это package. json Я указываю core как стиль URL-адреса "file: ../". Другой альтернативой является использование "пряжи" или, возможно, и то, и другое, и я Я не уверен, влияет ли это на то, что попадает в node_modules под папкой приложения или на то, что входит в комплект)

Как правильно включить React как в приложение, так и в библиотеку таким образом, чтобы в обоих этих проектах был доступен React, но в приложении не возникало дубликатов, вызывающих эту ошибку перехвата (или просто занимая лишнее место).

1 Ответ

0 голосов
/ 01 июня 2020

Отвечая на свой вопрос.

Я нашел следующую проблему полезной: https://github.com/facebook/react/issues/14257

В комментариях к способам решения этой проблемы были внесены различные предложения. , либо npm link, либо yarn link передавая библиотеку реакции из библиотеки в приложение, или наоборот. Все они казались многообещающими, поскольку идея состоит в том, чтобы убедиться, что все различные ссылки на React действительно указывают на одно и то же место. К сожалению, ни один из них не помог мне. (например, ответы JerryGreen и Kas в этом выпуске)

Другой пользователь, dcecile, предложил использовать функцию alias webpack, но я не использую webpack.

resolve: {
    alias: { react: require.resolve("react") }
},

Parcel имеет аналогичную функцию alias, но не может использоваться точно так же, потому что он используется в пакете. json файл, поэтому такие вещи, как require.resolve, не могут быть вызваны как будто они находятся в конфигурационном файле webpack js.

В итоге я нашел способ использовать функцию Parcel alias, чтобы делать то, что я хотел, на основе другого примера из https://github.com/jaredpalmer/tsdx/issues/64 от пользователя jaredpalmer. В моей ситуации я добавляю это в пакет приложения. json, и это, похоже, избавляет от проблемы дублирования и ошибки «Недопустимый вызов Hook Call»:

 "alias": {
    "react": "../my-core-library/node_modules/react",
  },
...