Все задавались вопросом, почему ваша папка 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]. Таким образом, у вас может быть столько версий, сколько вы хотите, и все они будут дедуплицированы и размещены в одном месте.