Для больших веб-приложений npm install
resp. yarn install
занимает много времени, главным образом на этапе " Linking Dependencies
. Что здесь происходит? Получает ли он зависимости зависимостей? Или что-то совсем другое? Какие файлы создаются на этом этапе?
Что действительно делает "Linking Dependencies" во время установки npm/yarn?
Ответ 1
Когда вы вызываете yarn install
, происходит следующее:
-
Разрешение: пряжа начинает разрешать зависимости, делая запросы в реестр и рекурсивно просматривая каждую зависимость.
-
Загрузка/выборка. Затем, пряжа ищет в глобальном каталоге кеша, чтобы узнать, загружен ли пакет. Если этого не произошло, пряжа извлекает tarball для пакета и помещает его в глобальный кеш, поэтому он может работать в автономном режиме и не требует загрузки зависимостей более одного раза. Зависимости также могут быть помещены в исходное управление как tarball для полной автономной установки.
-
Связывание. Наконец, пряжа связывает все вместе, копируя все файлы, необходимые из глобального кеша, в локальный каталог 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
. Обратите внимание на наличие разных версий одного и того же пакета для использования в разных проектах.
Но имейте в виду, что это уменьшит переносимость проекта. Это компромисс, который должен сделать любой менеджер (будь то rubygems или узловые модули). Я могу просто скопировать папку проекта узла (что на самом деле может занять несколько часов, потому что вы будете копировать (локальную) папку node_modules
, но я могу ожидать, что она будет работать, если у меня есть только эта папка проекта, в отличие от копирования рубина проект будет занимать от нескольких секунд до нескольких минут, так как нет локальных пакетов (или камней, как они их называют), но запуск проекта в другой системе потребует, чтобы эти пакеты присутствовали в глобальной папке камней.
Ответ 2
Фаза связывания работает по существу в 3 больших шага:
- Найти каждый файл, который должен быть в node_modules
- Проверьте этот список по сравнению с тем, что уже существует, и найдите, что нужно копировать из кеша в node_modules
- Сделайте копию
Возможно, эта проблема на Github поможет вам.