Подтвердить что ты не робот

Как избежать "загрузки двух копий ошибки React" при разработке внешнего компонента?

Я разрабатываю внешний компонент (скажем, my-component, который я связываю с проектом с npm link (как он находится в процессе, и мне нужен пакет для отражения изменений).

В папке my-component есть node_modules/react и node_modules/react-dom, поскольку они являются его зависимостями. Однако они являются peerDependences, поэтому я не предполагал привести их в проект, связывающий этот пакет.

Однако при использовании npm link он связывает весь каталог, включая node_modules. Итак, когда проект строится, он включает пакеты 2 раза: от node_modules/* и от node_modules/my-component/node_modules/*.

Это начинает влиять, когда компонент использует ReactDOM.findDOMNode, он вызывает эту ошибку:

Warning: React can't find the root component node for data-reactid value `.0.2.0`. If you're seeing this message, it probably means that you've loaded two copies of React on the page. At this time, only a single copy of React can be loaded at a time.

Кроме того, это может помочь понять, что происходит: проблема возникает только в том случае, если есть как node_modules/my-component/node_modules/react, так и node_modules/my-component/node_modules/react-dom. Если есть только один из них, сообщение об ошибке отсутствует.

Обычная установка пакета не приводит к такой ошибке, поскольку там нет node_modules/react-dom.

Как предполагается создание внешнего компонента и проекта в одно и то же время?

4b9b3361

Ответ 1

Я считаю, что ответ заключается в том, чтобы указать react и react-dom как peerDependencies в вашем внешнем компоненте package.json. Насколько я могу следовать здесь и здесь, npm link должен (начиная с [email protected]) больше не устанавливать peerDependencies (или `devDependencies).

Aaaand Я просто внимательно прочитал ваш пост и понял, что вы уже указываете их как peerDependencies. Поэтому я думаю, что ответ сводится к следующему:

Обновить до [email protected]:

npm install -g [email protected]

Ответ 2

Кто-то умнее меня (@mojodna) придумал это решение: удалите дубликаты зависимостей от внешнего компонента и разрешите их с вашими проектными копиями этих депок.

Шаг 1: Удалите зависимости от вашего внешнего компонента node_modules

Как @cleong отметил, вы не можете просто удалить отпечатки из внешнего компонента node_modules, потому что ваш шаг построения проекта не удастся, когда он ударит -изменение зависимостей во внешней компоненте.

Шаг 2. Добавьте проект node_modules в NODE_PATH

Чтобы исправить это, вы можете добавить проект node_modules к переменной среды NODE_PATH при запуске шага сборки. Что-то вроде, например, это:

NODE_PATH=$(pwd)/node_modules/ npm start

(где npm start - ваш script, который связывает ваш внешний компонент, например, с помощью браузера, Webpack и т.д.)

На самом деле вы всегда можете добавить дополнение NODE_PATH к вашим скриптам сборки, и оно будет работать независимо от того, есть ли у вас npm link что-нибудь. (Заставляет меня задаться вопросом, не должно ли это быть поведение по умолчанию npm...)

Примечание. Я оставил свой существующий ответ, потому что там какой-то разговор, и это другое (и лучшее) решение.

Ответ 3

Исправлено, добавив react-dom в качестве псевдонима в мою конфигурацию webpack

alias: {

    react$: require.resolve(path.join(constants.NODE_MODULES_DIR, 'react')),
    'react-dom': require.resolve(path.join(constants.NODE_MODULES_DIR, 'react-dom'))

}

Ответ 4

Проблема двоякая:

  • У вас не может быть загружено 2 копии реакции.
  • npm link создает символическую ссылку, однако "require" не уважает symlink, и когда он пытается перейти по каталогу, он никогда находит реакцию родительского проекта.

Решение:

Все, что вам нужно сделать, это связать реакцию и реакцию с вашим компонентом с компонентом родительского проекта node_modules.

Перейдите к проекту компонента и удалите реакцию и реакцию, затем выполните

npm link ../myproject/node_modules/react
npm link ../myproject/node_modules/react-dom

Ответ 5

Проблема заключается в связи с npm. https://github.com/npm/npm/issues/5875

npm не обрабатывает связанный каталог как дочерний элемент родительского проекта.

Попробуйте альтернативы npm-ссылке:

1) Используйте относительные зависимости пути в package.json

2) Вручную укажите свои зависимости в своих проектах node_modules

3) Используйте URL-адрес пути

В принципе ничего, кроме ссылки npm

Ответ 6

Добавление следующего в мой webpack.config.js сработало для меня:

resolve: {
    alias: {
        react: path.resolve(__dirname, 'node_modules', 'react')
    }
}

Я также экспериментировал с DedupePlugin (упоминался как возможное средство здесь), но я не мог заставить его работать.

Интересно также, что я столкнулся с различными (и, возможно, более коварными) проявлениями одной и той же проблемы, когда модуль найден в нескольких местах в графике зависимостей.

Один из таких случаев заключался в том, что мои ограничения React.PropTypes.instanceOf(SomeType) выдавали бы предупреждения, даже если тип, который я прошел, был правильным. Это связано с тем, что модуль присутствует в нескольких местах в дереве каталогов node_modules. Из-за утка-ввода код все равно будет работать, но моя консоль была загромождена этими предупреждениями. Переход к resolve.alias тоже заставил их замолчать.

YMMV

Ответ 7

Если вы используете Webpack в основном проекте, это решение может работать. В моем случае project-a требуется project-b. Оба требуют React и ReactDOM 0.14.x

У меня это в project-a/webpack.config.js:

resolve: {
  modulesDirectories: ['node_modules'],
  fallback: path.join(__dirname, 'node_modules')
},
resolveLoader: {
  fallback: path.join(__dirname, 'node_modules')
},
  • project-b требует React и ReactDOM как peerDependencies в project-b/package.json
  • project-a требует project-b как devDependency (также должен работать как dependency) в project-a/package.json
  • local project-b связан с project-a следующим образом: cd project-a; npm link ../project-b

Теперь, когда я запускаю npm run build внутри project-b, изменения отображаются сразу же в project-a

Ответ 8

Я использую ReactJS.net и настраиваю webpack из учебника и начинаю использовать react-bootstrap, когда я начал получать эту ошибку. Я обнаружил, что добавление 'react-dom': 'ReactDOM' в список externals в webpack.config.js устраняет проблему, тогда список внешних выглядит следующим образом:

  externals: {
    // Use external version of React (from CDN for client-side, or
    // bundled with ReactJS.NET for server-side)
      react: 'React',
      'react-dom': 'ReactDOM'

Это, похоже, первая ссылка в google для этой ошибки, поэтому я подумал, что этот ответ может помочь кому-то здесь.

Ответ 9

Я получал это, потому что уже включил react и react-dom в качестве внешних скриптов в моей разметке HTML.

Ошибка вызвана добавлением import ReactDOM from 'react-dom' к компонентному модулю. Ошибка исчезла, как только я удалил импорт, и модуль работал нормально, поскольку компоненты уже были доступны.