Все задавались вопросом, почему ваша папка node_modules занимает все больше и больше места по мере того, как вы включаете все больше и больше зависимостей в свой проект? Заглянем внутрь.

Зависимость часто включает другую, которая тоже может иметь зависимости. Некоторые распространенные зависимости, такие как lodash или isarray, могут быть включены более 10 раз в ваш собственный файл package.json.

NPM поставляется с новой системой выравнивания, которая пытается поместить все зависимости, независимо от того, на каком уровне дерева они обычно находятся, в папку node_modules верхнего уровня. Основная проблема в том, что в настоящее время NPM не может обрабатывать модули с другой версией. Таким образом, у нас должен быть полный дубликат модуля только для каждой другой версии, которая у нас есть. Правильно? НЕПРАВИЛЬНО.

Сумасшедшая правда заключается в том, что то, где вы размещаете свои зависимости в файле package.json, имеет значение.

Давайте попробуем, создадим простой файл package.json:

{
  "name": "simple",
  "version": "1.0.0",
  "dependencies": {
      "elasticsearch" : "^11.0.1"
  },
  "devDependencies":
  {
      "copy-webpack-plugin" : "^3.0.1",
      "gulp-merge-json" : "^0.6.0"
  }
}

Кажется достаточно простым, не так ли? Установите его с помощью npm install и посмотрите на размер node_modules. 21 месяц. Почему нет.

Давайте подробнее рассмотрим зависимости, используя небольшой bash-скрипт (dup.sh):

for i in $(find -name 'package.json')
do
    NAME=$(jq -r ".name" $i)
    VERSION=$(jq -r ".version" $i)
echo $NAME@$VERSION
done

Это просто найти каждый package.json, который он может, и вывести синтаксис name@version. Это не то же самое, что команда npm list, поскольку она покажет только существующие и полные модули, отбрасывая все дедуплицированные модули.

Запустим, посчитаем повторение строк и посмотрим на результат:

$ ./dup.sh | sort | uniq -c | sort -n
      1 [email protected]
      1 [email protected]
      1 [email protected]
      ....
      2 [email protected]

Какой сюрприз. lodash 4.16.2 включен дважды. Каждый добавляет 5 мес.

Это более 20% от общего размера папки.

Но это не остановится здесь. Если вы добавите больше зависимостей, требующих той же версии lodash, она будет дублироваться все больше и больше.

Это связано с тем, что пакету elasticsearch требуется [email protected], и он имеет приоритет без веской причины.

Это проблема с npm или с elasticsearch?

Конечно, elasticsearch не обновил свой пакет до последней версии, но мы не можем винить в этом тех, кто сопровождает пакет: npm не выполняет свою работу по дедупликации.

Что NPM может сделать для этого?

Много вещей.

Самый простой — построить полное дерево перед дедупликацией, подсчитав, какая версия используется чаще, и дедуплицировать ее. Это простое решение, но оно не мешает вам получать дубликаты: если у вас есть пять lodash@3 и два lodash@4, он будет дедуплицировать lodash @3, оставив две копии lodash@4.

Лучше всего правильно обрабатывать версию пакета, например, переименовывая папки в node_modules, используя соглашение @: [email protected]. Таким образом, у вас может быть столько версий, сколько вы хотите, и все они будут дедуплицированы и размещены в одном месте.

Помогите нам перестать тратить дисковое пространство и производительность ввода-вывода, распространяйте информацию.