2013-03-02 2 views
45

Есть ли способ указать зависимые от ОС зависимости в файле npm package.json?npm package.json Специфическая зависимость ОС

Например, я хотел бы установить «dbus» (https://npmjs.org/package/dbus) в качестве зависимости для моего модуля, если пользователь работает под управлением Linux. У меня была бы другая зависимость для Mac и Windows.

+5

Хороший вопрос. Я знаю, что есть поле 'os' в [package.json] (https://npmjs.org/doc/json.html), но это не позволяет вам менять зависимости на основе текущей платформы - это просто объявляет, какие платформы пакет включен в белый список. Например, это свойство в 'package.json': ' "ОС": [ "! Win32", "Darwin"] ' означает "этот пакет не будет работать в окнах, но будет работать на Маках".К сожалению, это не совсем то, о чем вы просите. – smithclay

+0

^Это проблема, если модуль dbus имеет собственные привязки, которые будут компилироваться только на определенной ОС ([как указано ниже в комментарии] (http://stackoverflow.com/questions/15176082/npm-package-json- os-specific-dependency # comment22801812_15670089)), его package.json должен включать это поле 'os'. –

ответ

25

В зависимости от вашей установки существует хороший способ сделать это.

НПМ package.json поддерживает os ключ,

, а также optionalDependencies

  • os может быть использован для указания ОС модуль может быть установлен.
  • optionalDependencies - это зависимости модулей, которые, если они не могут быть установлены, npm пропускает их и продолжает установку.

Таким образом, вы можете иметь ваш модуль имеет дополнительную зависимость для каждой операционной системы, и только тот, который работает будет загружен/установлен^^

EDIT:. Как @Sebastien упоминается ниже, этот подход опасен. Для любой данной ОС по крайней мере одна из ваших зависимостей «требуется», а остальная «необязательная». Предоставление всех версий зависимостей необязательно означает, что если ваша установка завершится неудачно по уважительной причине, она будет молча пропустить установку, и вам не понадобится зависимость, которая вам действительно нужна.

+2

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

+0

Я бы хотел, чтобы я мог удалить свой комментарий, так как я в конечном итоге использовал скрипты установки с этим решением>. < – TinyTimZamboni

+0

вы можете показать мне полный пример? скажем, 'fsevents' является необязательной зависимостью от OSX, которую мне неинтересно, потому что мой скрипт сборки работает на LINUX. –

6

Я думаю, что короткий ответ - нет. Я могу придумать пару обходных решений - самое простое - просто добавить все к package.json независимо от ОС, а затем require() правильный во время выполнения.

Если это не работает для вас, вы можете быть в состоянии использовать инсталляционный скрипт, чтобы получить результат, который вы собираетесь для - https://docs.npmjs.com/misc/scripts

Я не проверял это, но я думаю, что это будет работать:

Добавить что-то вроде этого, чтобы ваш package.json:

,"scripts": { 
    "install": "node install_dependencies.js" 
} 

а затем добавьте install_dependencies.js файл, который проверяет ОС и запускает соответствующие npm install ... команды.

+5

Проблема в том, что у моих зависимостей есть собственные привязки, которые компилируются только на определенной ОС, поэтому я не могу иметь их как явные зависимости. Ваше предложение для скрипта установки npm работает, я использовал os.platform(), чтобы определить, какую платформу использует пользователь; – sandeepmistry

+2

скрипты установки теперь считаются «антипаттером» [источник] (https://www.npmjs.org/doc/misc/npm-scripts.html#note-install-scripts-are-an-antipattern). Вместо этого следует использовать файл компиляции .gyp – TinyTimZamboni

+1

Просто замечание, которое мне было непонятно с приведенным выше. Если вы используете 'package.json' для управления установкой для проекта и вашей публикации, то использование .gyp не является решением. Обратите внимание на сообщение ниже TinyTimZamboni, это гораздо более подходит для этого сценария (http://stackoverflow.com/a/26069595/1125784). – Metalskin

1

Там также привязок-Шып модуль:

https://www.npmjs.com/package/bindings-shyp

Helper модуль для загрузки файла .node вашего родного модуля

Это вспомогательный модуль для авторов Узла .js. В основном это «швейцарский армейский нож», требующий() файла .node вашего собственного модуля.

В течение всей истории аддонов Node дополнения были скомпилированы в различных местах, в зависимости от того, какой инструмент сборки и какая версия узла была использована. Хуже того, теперь инструмент построения gyp может создавать либо сборку Release, либо Debug, каждый из которых встроен в разные местоположения.

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

0

Цитирование @npm_support по адресу:

https://twitter.com/npm_support/status/968195526989512705

2/2 Если вы хотите, чтобы избежать проблем при установке, связанные с зависимостями, один маршрут для вас, чтобы написать обертку, что требуется, как регулярную зависимость и убедиться, что она имеет optionalDeps (а также убедитесь, что обертка проверяет, что у вас есть все необходимое для работы).

Но ИМХО это скорее похоже на обходное решение, чем решение проблемы на самом деле.

Я могу понять, что npm хочет сохранить переносимость и избегать использования специфики платформы, но это необходимо сделать в любом случае, и IMHO, выполняющее это во время выполнения, не является оптимальным (специальность, если вы хотите оптимизировать размер кода).

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

Невозможно поддерживать «условные зависимости» в npm?

Первое, что пришло мне в голову, заключалось в том, чтобы добавить раздел «переопределить», который изменит текущие разделенные секции (+ add, -remove, = replace).

Например:

dependencies: { "common-stuff": "*" } overrides: { "os: { linux: { dependencies: { "+best-linux-module" } } } }

И другой вариант предложенный разработчиком я знаю, было бы ввести обеспечивает ключевое слово, а затем несколько модулей может обеспечить тот же семантический, чем будет удовлетворено распознаватель (a la debian), но он генерирует подобные накладные расходы.

Я ищу общий подход, ориентированный не только на поддержку ОС, но и на другие варианты упаковки (в зависимости от двигателей, например).

Вы знаете какую-либо связанную с этим проблему в трекере NPM? если не я рассматриваю файл ошибка будет отслеживаться по адресу:

https://github.com/npm/npm/issues?q=dependencies+conditional

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

Смежные вопросы