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


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

2 11

2 ответа:

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

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

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

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


yarn install действительно занимает много времени, в основном на этапе под названием Linking Dependencies

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

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

Он медленнее из-за

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

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

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

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

Введите описание изображения здесь

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

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

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

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

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