Как развернуть приложение Node.js с глубокой структурой node_modules в Windows?

91

Я столкнулся с любопытной проблемой - очевидно, у некоторых модулей Node.js настолько глубокая иерархия папок, что команда копирования Windows (или PowerShell, Copy-Itemчто мы на самом деле используем) выдает печально известную ошибку «путь слишком длинный», когда путь превышает 250 символы длинные.

Например, это иерархия папок, которую может создать один модуль Node:

node_modules\nodemailer\node_modules\simplesmtp\node_modules\
xoauth2\node_modules\request\node_modules\form-data\node_modules\
combined-stream\node_modules\delayed-stream\...

Это кажется безумием, но это реальность с модулями Node.

Нам нужно использовать копирование и вставку во время развертывания (мы не используем «умную» целевую платформу, такую ​​как Heroku, где развертывание Git было бы вариантом), и это серьезное ограничение для Windows.

Нет ли команды npm или чего-то, что могло бы сжать node_modulesпапку или, возможно, включить только то, что действительно необходимо во время выполнения? (Модули узла обычно содержат testпапки и т. Д., Которые нам не нужно развертывать.) Есть другие идеи, как это обойти? Не использовать Windows, к сожалению, не вариант :)

Борек Бернар
источник
1
Есть ли в вашем проекте package.jsonс dependenciesнабором? Если да, не могли бы вы скопировать node_modulesи использовать npm в installили updateзависимости?
Джонатан Лоновски
4
@JonathanLonowski Наша среда развертывания не поддерживает выполнение npm installв целевой среде, она работает, создавая «пакет развертывания» локально (в основном ZIP плюс некоторые метаданные), который затем загружается на целевую машину, извлекается там и все. Так что мне нужно включить node_modulesнапрямую.
Borek Bernard

Ответы:

24

npm v3 (выпущенный недавно) решает эту проблему, выравнивая зависимости. Ознакомьтесь с примечаниями к выпуску здесь, в https://github.com/npm/npm/releases/tag/v3.0.0 в flat flatразделе.

И последний комментарий по этому поводу https://github.com/npm/npm/issues/3697

РамешВел
источник
5
Примечания к выпуску для flat flatтеперь похоронены на другой странице. Вот прямая ссылка: github.com/npm/npm/releases/tag/v3.0.0
Джон-Филип
Спасибо @ John-Philip, обновил ответ новой ссылкой
RameshVel
62

просто чтобы добавить к этому ... еще одна вещь, которая мне помогла, - это список всех установленных модулей npm ls.

который даст вам дерево модулей и версий ... оттуда довольно легко определить, какие из них являются дубликатами ... npm dedupeничего для меня не сделало. Я не уверен, ошибка это или что-то в этом роде (Node v 10.16)

Поэтому, как только вы обнаружите дублирующийся модуль, установите его в корневой каталог node_module, используя npm install dupemodule@1.2.3 --save-dev. Версия важна.

после этого я стер свой каталог node_modules и сделал новый npm install.

Укороченная версия

  1. npm ls чтобы получить список всех установленных модулей.
  2. просмотрите эти модули и определите повторяющиеся модули ( важна версия )
  3. npm install module@version --save-dev чтобы установить эти модули в корневой каталог node_modules и обновить package.json.
  4. rmdir node_modules для удаления каталога node_modules.
  5. npm install чтобы загрузить новую копию ваших зависимостей.

Как только я это сделал, все стало намного чище.

Я также рекомендую прокомментировать ваш файл package.json, чтобы показать, какие из них были сброшены, чтобы сгладить дерево node_modules.

Бен Леш
источник
Это отлично сработало для меня. Спасибо! Простите мое незнание, но почему модули не всегда устанавливаются на верхнем уровне?
Caleb
2
@Caleb, вероятно, потому, что разные модули полагаются на разные версии одного и того же модуля, или, может быть, просто потому, что проще просто получить все, что нужно, а затем уменьшить его ... Я не знаю.
Бен Леш
7
Тем не менее, спасибо за подсказку. Я только что удалил из нашего проекта около 1700 файлов-дубликатов. Удаление вещей - моя любимая часть работы разработчика! Кроме того, для тех, кто интересуется, как добавлять комментарии в package.json, вот ваш ответ: stackoverflow.com/questions/14221579/…
Калеб
github.com/joyent/node/issues/6960, специалист по узлам говорит, что Windows - это первоклассный гражданин. Они сказали. Но они закрыли вопрос и ничего не исправили. Удачливые пользователи Windows.
vee
38

Я не думаю, что есть какое-либо отличное решение с учетом ваших ограничений, но вот некоторые вещи, которые могут помочь.

  • Попробуйте использовать npm dedupeдля оптимизации иерархии каталогов, что может сократить некоторые пути
  • Использовать npm install --productionдля установки без инструментов разработки
  • Возьмите некоторые из этих глубоко вложенных зависимостей (я предлагаю ровно столько, чтобы избежать проблемы) и переместите их в каталог node_modules верхнего уровня. Просто следите за ними, чтобы знать, каковы ваши истинные зависимости и какие обходные пути для этой проблемы.
  • ИЛИ переместите некоторые из этих глубоких зависимостей в node_modulesкаталог самого высокого уровня, your_project/node_modules/pkg_with_deep_depsчто позволит им иметь достаточно короткие пути, но при этом работать. Так бы и было your_project/node_modules/pkg_with_deep_deps/node_modules.
    • Я думаю, requireдолжен быть в состоянии найти их правильно во время выполнения. Вам просто нужно четко задокументировать, что вы изменили вручную, почему вы это сделали, и сохранить ваши собственные истинные зависимости, точно представленные вpackage.json

Вот обсуждение проблемы на github , в которой подробно рассматривается эта проблема.

Питер Лайонс
источник
Спасибо, что указали dedupe(вообще не знал об этом) и --production( npm install -hне отображал эту опцию)! К сожалению, использование ZIP-архива невозможно, см. Комментарий выше.
Borek Bernard
9
npm dedupe сведет только «общие» модули к самому низкому общему месту в иерархии. Не достаточно хорошо. Правильное решение позволило бы «выровнять» всю иерархию и, возможно, позволить игнорировать каталоги test / doc. Альтернативой будет поддержка node для чтения модулей непосредственно из tar-файла.
MMind
3
Согласны, что-то вроде «двоичного» распространения пакетов (ZIP, tarball, что угодно) было бы очень полезно.
Borek Bernard
11

Я написал модуль узла под названием "npm-flatten", который сглаживает ваши зависимости для вас здесь: https://www.npmjs.org/package/npm-flatten

Если вы ищете дистрибутив, я также написал пакет NuGet, который интегрирует полную среду node.js с вашим проектом .NET здесь: http://www.nuget.org/packages/NodeEnv/

Обратная связь будет приветствоваться.

user3602171
источник
У нас это сработало. У нас были еще лучшие результаты, когда мы сначала запустили nmp dedup.
Шон Роуэн,
1

Мне помогло сопоставление локального диска с моей папкой Node.js:

чистое использование n: \ computername \ c $ \ users \ myname \ documents \ node.js / persistent: да

До: c: \ users \ myname \ documents \ node.js \ projectname (45 символов) После: n: \ projectname (14 символов, что на 31 символ меньше)

Во многих случаях это позволяло установить некоторые модули.

Я скажу, что я заново обнаружил эту проблему сегодня, когда пытался сделать резервную копию всего моего кода на USB-накопитель.

"C: \ Users \ myname \ Documents \ Node.js \ angular-phonecat \ node_modules \ karma \ node_modules \ chokidar \ node_modules \ anymatch \ node_modules \ micromatch \ node_modules \ regex-cache \ node_modules \ benchmarked \ node_modules \ file-reader \ node_modules \ extend-shallow \ benchmark \ fixtures слишком длинный. "

Даже когда я пытался создать их резервную копию, используя букву диска N:, в некоторых случаях это все равно не удавалось из-за длины пути, но этого было достаточно, чтобы исправить тот, который указан выше.

Майкл Бланкеншип
источник
1

1) Во время сборки выпуска вы можете предотвратить сканирование этих файлов / папок Visual Studio, установив свойства папки как скрытую папку (ПРОСТО установите для нее значение node_modules). Ссылка: http://issues.umbraco.org/issue/U4-6219#comment=67-19103

2) Вы можете исключить файлы или папки, опубликованные во время упаковки, включив следующий узел XML в файл CsProject.

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  ...
  <OutputPath>bin\</OutputPath>
   <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
  <ExcludeFilesFromDeployment>File1.aspx;File2.aspx</ExcludeFilesFromDeployment>
  <ExcludeFoldersFromDeployment>Folder1;Folder2</ExcludeFoldersFromDeployment>
</PropertyGroup>
Дэвид Челлия
источник
1

Я нашел одно решение из Руководства Microsoft Node.js .

  • Начните с короткого пути (например, c: \ src)
  • > npm install -g rimraf удалить файлы, превышающие max_path
  • > npm dedupe перемещает повторяющиеся пакеты на верхний уровень
  • > npm install -g flatten-packages перемещает все пакеты на верхний уровень, но может вызвать проблемы с управлением версиями
  • Обновление до npm@3которого пытается сделать node_modulesиерархию папок максимально плоской.
    • Поставляется с Node v5
    • Или… > npm install –g npm-windows-upgrade
Zangw
источник
0

Это не подходящее решение, скорее, это обходной путь, когда вы торопитесь, но вы можете использовать 7-Zip, чтобы заархивировать свою папку, переместить заархивированный файл и разархивировать его без каких-либо проблем.

Мы использовали это решение для развертывания приложения Node.js там, где было невозможно выполнить чистую установку npm.

Джейсон
источник
Ага. Это то, что я делаю каждый раз, когда мне нужно установить mongoose. В нем есть собственный код, и у меня есть несколько / более новых версий Visual Studio = fail. Я мог просто открыть VS, добавить каждый неудачный файл .sln и восстановить его. Но проще просто выполнить XCOPY по всему моему набору папок node_modules \ mongoose по мере необходимости (просматривая версии, конечно).
Майкл Бланкеншип,