Что действительно делает "Linking Dependencies" во время установки npm/yarn?

Для больших веб-приложений npm install resp. yarn install занимает много времени, главным образом на этапе " Linking Dependencies. Что здесь происходит? Получает ли он зависимости зависимостей? Или что-то совсем другое? Какие файлы создаются на этом этапе?

Ответ 1

Когда вы вызываете yarn install, происходит следующее:

  1. Разрешение: пряжа начинает разрешать зависимости, делая запросы в реестр и рекурсивно просматривая каждую зависимость.

  2. Загрузка/выборка. Затем, пряжа ищет в глобальном каталоге кеша, чтобы узнать, загружен ли пакет. Если этого не произошло, пряжа извлекает tarball для пакета и помещает его в глобальный кеш, поэтому он может работать в автономном режиме и не требует загрузки зависимостей более одного раза. Зависимости также могут быть помещены в исходное управление как tarball для полной автономной установки.

  3. Связывание. Наконец, пряжа связывает все вместе, копируя все файлы, необходимые из глобального кеша, в локальный каталог node_modules после определения того, что уже есть, и того, что там нет.


yarn install занимает много времени, главным образом на этапе под названием " Linking Dependencies

Вы должны заметить, что Step 3: Linking занимает больше времени, чем Step 1: Resolution и Step 2: Fetching где происходит фактическая загрузка. Во время этого шага у нас уже есть вещи, которые нам нужны готовые и загружаемые, то почему это занимает много времени, мы что-то пропустили?

Да, COPY для локального проекта в папку node_modules...! Причиной этого является то, что эта копия не эквивалентна копированию одного большого ISO файла 4,7 ГБ. Вместо этого это несколько супер маленьких файлов (Не принимайте это, когда я говорю несколько, это могут быть файлы 15k+: P), поэтому требуется много времени для копирования. (Также важно отметить, что при загрузке пакетов вы загружаете один большой файл tar на пакет, содержимое которого затем следует извлекать в кеш, который также требует времени)

Это медленнее из-за

  • Антивирус: ваш антивирус сидит посередине и делает быструю проверку (в дополнение к нашей проверке пряжи, если она уже существует) на каждой отдельной нити файла пытается скопировать резкость своей скорости на столько. Если вы находитесь в Windows, попробуйте добавить родительскую папку проекта в качестве исключения для Защитника Windows.
  • Скорость передачи носителей: SSD могут значительно увеличить эту скорость (извините, SSHD и FireCudas тоже не помогут, это будет один раз).

Но эффективно ли это? Могу ли я взять его из глобального узла node_modules (после его создания)?

Нет вопросов для обоих вопросов. Из-за того, как узел работает, каждый пакет находит свои зависимости только по отношению к его собственному местоположению. Также потому, что каждый проект может захотеть использовать разные версии одного и того же пакета, чтобы обеспечить его правильную работу и не нарушать обновления пакетов.

В идеале папка проекта должна быть тощей. Эффективным способом сделать это будет создание глобальной папки node_modules. Любые и все запрошенные пакеты загружаются, если они еще не присутствуют и используются из этого местоположения. На самом деле Ruby делает это так. Здесь мой глобальный Ruby эквивалент папки node_modules. Обратите внимание на наличие разных версий одного и того же пакета для использования в разных проектах.

enter image description here

Но имейте в виду, что это уменьшит переносимость проекта. Это компромисс, который должен сделать любой менеджер (будь то rubygems или узловые модули). Я могу просто скопировать папку проекта узла (что на самом деле может занять несколько часов, потому что вы будете копировать (локальную) папку node_modules, но я могу ожидать, что она будет работать, если у меня есть только эта папка проекта, в отличие от копирования рубина проект будет занимать от нескольких секунд до нескольких минут, так как нет локальных пакетов (или камней, как они их называют), но запуск проекта в другой системе потребует, чтобы эти пакеты присутствовали в глобальной папке камней.

Ответ 2

Фаза связывания работает по существу в 3 больших шага:

  1. Найти каждый файл, который должен быть в node_modules
  2. Проверьте этот список по сравнению с тем, что уже существует, и найдите, что нужно копировать из кеша в node_modules
  3. Сделайте копию

Возможно, эта проблема на Github поможет вам.

https://github.com/yarnpkg/yarn/issues/1496