Подтвердить что ты не робот

Как заставить Grunt Deploy использовать глобальные модули NPM вместо локальных

Во-первых, я очень новичок в npm и хрюкаю. У нас есть проект, в котором мы используем Grunt для компиляции и создания выходных файлов. Я пытаюсь настроить наш сервер сборки на использование Grunt для создания выходных файлов. Мы используем Windows с контролем источника TFS, и из-за этого 260-символьного ограничения пути мы не можем проверить модуль командной строки grunt-bower-task в исходное управление (поскольку он один использует 230 символов в установленном пути).

Когда я запускаю npm install из каталога моего проекта, он отлично работает и устанавливает следующие необходимые модули в папку node_modules в моем каталоге проектов:

  • хрюкать
  • пехотинец-становой-задачи
  • пехотинец-вно-компас
  • пехотинец-вно-подключения
  • пехотинец-вно-jshint
  • пехотинец-CONTRIB-requirejs
  • пехотинец-вно-часы

И затем, когда я запускаю развертывание grunt из моего каталога проектов, все работает так, как ожидалось.

В то время как я мог просто запустить npm install часть процесса сборки, я предпочитаю не делать этого, так как для загрузки всех файлов требуется несколько минут, и я не хочу, чтобы наши сборки зависели от внешнего веб-сервиса доступны.

Я видел, что вы можете устанавливать модули как локально, так и глобально, поэтому я надеюсь только, что смогу установить модули по всему миру на сервере сборки что они не должны находиться в папке node_modules непосредственно внутри каталога проекта, прежде чем запускать развертывание grunt. Я запускал npm install -g, а также npm install -g [module] для каждого из перечисленных выше модулей, а также npm install -g grunt-cli.

Если я делаю npm prefix -g, он показывает мне, что глобальный каталог модуля - C:\Users [Мой пользователь]\AppData\Роуминг\npm, и когда я смотрю в эту папку node_modules, я вижу все модулей. Однако, когда я запускаю развертывание grunt, он жалуется:

Неустранимая ошибка: не удается найти локальный хрюканье

Если я включаю только каталог * node_modules\grunt *, то я все равно получаю следующие ошибки:

Локальный модуль Npm "grunt-contrib-watch" не найден. Установлен ли он?

Локальный модуль Npm "grunt-contrib-jshint" не найден. Установлен ли он?

...

Я также попытался использовать * grunt deploy --base "C:\Users [My User]\AppData\Roaming\npm", но он жалуется, что он не может найти другие файлы, такие как .jshintrc.

Итак, есть способ, которым я могу запустить развертывание grunt, и проверить ли он общий путь префикса npm для модулей, а не искать в каталоге проекта?

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

Для справки, это мой файл package.json выглядит следующим образом:

{
  "name": "MyProject",
  "version": "0.0.1",
  "scripts": {
    "preinstall": "npm i -g grunt-cli bower"
  },
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-contrib-compass": "~0.2.0",
    "grunt-contrib-watch": "~0.4.4",
    "grunt-contrib-jshint": "~0.6.0",
    "grunt-contrib-requirejs": "~0.4.1",
    "grunt-contrib-connect": "~0.3.0",
    "grunt-bower-task": "~0.2.3"
  }
}

Спасибо.

4b9b3361

Ответ 1

Вместо того, чтобы использовать глобальную опцию для npm, вы должны использовать символические ссылки на своих модулях для достижения аналогичных результатов.

Глобальные установки npm предназначены только для удобства утилит командной строки, таких как jshint или grunt-cli.

Ответ 2

Обходной путь: явно укажите все временные зависимости в вашем собственном пакете. json.

Скажем, например, что вы зависите от module_a, а module_a зависит от модуля_b. После npm install у вас будет node_modules/module_a/node_modules/module_b/, потому что npm будет устанавливать module_b local в module_a. Однако, если вы добавите module_b как прямую зависимость в свой пакет package.json(и точно укажите спецификаторы версии), то npm будет устанавливать только module_b только один раз: на верхнем уровне.

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

Итак, пересмотренный пример. Вы зависите от [email protected], который зависит от модуля[email protected] Если вы также зависеть от [email protected], вы получите в два раза модуль module_b. (Версия 0.1.0 будет установлена ​​на верхнем уровне, а 0.2.0 будет установлена ​​в модуле_a.) Однако, если вы зависеть от v0.2.0 (используя точную строку версии в вашем пакете .json как для использования module_a), тогда npm заметит, что он может использовать ту же версию module_b. Поэтому он будет устанавливать модуль module_b только на верхнем уровне, а не на module_a.

Короче говоря: добавьте какие-либо временные зависимости, которые у вас есть, которые имеют глубокие деревья модулей непосредственно к вашему собственному package.json, и вы получите более мелкое дерево node_modules.

Ответ 3

Я использую fenestrate для решения подобных проблем в Windows. Даже если он работает с Git, если вы используете интеграцию Git из Visual Studio в Team Explorer, она по-прежнему будет терпеть крах, если длинные пути к файлу находятся в вашей папке node_modules - даже если вы не добавляете эту папку в исходный элемент управления.

Обычно структура зависимостей Grunt и Bower вызывает это.

  • В первую очередь я бы рекомендовал запустить npm dedupe на ваших пакетах. Это делается для сканирования уже установленных пакетов и проверки дублирования некоторых зависимостей. Если он найден на более высоком уровне, он удалит глубоко протестированные.

  • Во-вторых, если dedupe не решит проблему, если вы можете найти зависимость, которая так глубоко вложена, что вызывает эту проблему, попробуйте установить ее прямо в ваше решение и снова запустите debupe.

    /li >
  • Если для этого больше зависимостей пакетов, fenestrate, это решит проблему. Плюс это действительно здорово, потому что вы можете подключить его к вам на npm install, и он будет запускаться после установки нового пакета. Кроме того, он полностью обратим.

Надеюсь, это поможет.

Ответ 4

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

чтобы следить за ответом bevacqua:

Вместо того, чтобы использовать глобальную опцию для npm, вы должны использовать символические ссылки на своих модулях для достижения аналогичных результатов.

Глобальные установки npm предназначены только для удобства утилит командной строки, таких как jshint или grunt-cli.

Я немного копал и мог бы дать немного больше разъяснений:

В итоге я создал глобальную папку в корне каталога пользователя. Внутри этого каталога я добавил все пакеты, которые мне нужны, используя npm install. Например, я запускал npm install grunt, npm install grunt-contrib-watch, npm install grunt-contrib-less и т.д. Вы также можете добавить файл package.json в ту же папку и просто запустить npm install, чтобы добавить их все сразу. Теперь мой глобальный каталог имел следующую структуру:

.global_grunt_modules
    node_modules
        grunt
        grunt-contrib-watch
        grunt-contrib-less

Затем я перешел в любой рабочий каталог проекта, где мне нужно было запустить grunt, а в корневой папке этой папки вышла команда:

ln -s ~/.global_grunt_modules/node_modules .

ln с флагом -s (символическая ссылка) принимает два аргумента:

[source_file] [target_dir]

Итак, команда в основном говорит: "Создайте символическую ссылку из моей глобальной папки node_modules и привяжите ее к моей текущей директории". . указывает текущий рабочий каталог.

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

Ответ 5

Когда ссылка npm недостаточно хороша (сетевые файловые системы,...), вы можете использовать пакет 'requireg'. Это единственное чистое решение, которое каким-то образом делает его "встроенным". Пакет 'requireg' имеет функцию globalize, которая делает последующие вызовы, также смотрящие в глобальном.