Использование npm для установки или обновления необходимых пакетов точно так же, как сборщик для rubygems

88

Я люблю Bundler , он отлично справляется с управлением зависимостями. Я люблю npm , устанавливать пакеты узлов очень просто! У меня есть приложение nodejs, и я хотел бы иметь возможность указывать зависимости моих приложений и легко устанавливать / обновлять их везде, где я развертываю свое приложение. Это не библиотека, которую я выпускаю, это полноценное веб-приложение.

Я знаю эту npm bundleкоманду, но она просто переопределяет каталог, в котором установлены пакеты.

Я привык использовать бандлер таким образом:

# Gemfile
gem "rails", "3.0.3"

Устанавливает rails v3.0.3 и любые другие необходимые драгоценные камни на хост-машину, только если они еще не существуют

> bundle install

Как я могу добиться чего-то подобного с помощью npm?

Дэниел Бердсли
источник
мой ответ не то, что вы хотели знать?
Альфред

Ответы:

147

Начиная с npm 1.0 (который теперь вы получаете по умолчанию, если следуете инструкциям в файле README), «пакет» больше не является изолированной вещью - это просто «как это работает».

Так:

  1. Поместите package.jsonфайл в корень вашего проекта
  2. Перечислите свои данные в этом файле

    { "name" : "my-project"
    , "version" : "1.0.0"
    , "dependencies" : { "express" : "1.0.0" } }
    
  3. npm install Поскольку вы вызываете это без аргументов и не в глобальном режиме, он просто установит все ваши депы локально.

  4. require("express") и будь счастлив.
Айзекс
источник
2
При производстве я настоятельно рекомендую изменить локальный your_app/node_modulesкаталог на символическую ссылку вне каталога вашего приложения. Вам не нужно загружать, собирать и устанавливать каждую зависимость при каждом развертывании.
Дэниел Бердсли
ОК. что, если я забуду обновить свой package.json? Есть ли способ заставить NPM искать не package.json, а пакеты, которые я использую в своем коде?
Поно
4
Это не совсем так. NPM установит все зависимости для вышеуказанного my-projectв ./node_modules/my-project/node_modules. Я не уверен, есть ли удобный способ установить все зависимости в ./node_modules Anyone?
Дэниел Бердсли
@DanielBeardsley: Я не думаю, что так работает npm. Если вы наблюдаете такое поведение и можете воспроизвести его, опубликуйте сообщение о проблеме на странице npm github.
isaacs
2
Согласитесь с @DanielBeardsley. Я страдаю от такого поведения даже с npm 1.1.70
graffic
10

Изменить: это относится только к версиям npm <1.0


Разобраться в этом было довольно сложно, но NPM делает это возможным .

Вам нужно три компонента

  1. Подкаталог в вашем репозитории (т.е. deps/)
  2. package.jsonФайл в каталоге выше , что списки зависимости
  3. index.jsФайл в каталоге выше , что требует вашего зависимостей

пример

Представьте, что экспресс - ваша единственная зависимость

deps / package.json

примечание: увеличивайте номер версии каждый раз, когда вы изменяете зависимости

{
  "name": "myapp_dependencies",
  "version": "0.0.1",
  "engines": {
    "node": "0.4.1"
  },
  "dependencies":{
    "express": "2.0.0beta2"
  }
}

deps / index.js

export.modules = {
  express: require('express')
  //add more
}

Теперь вы сможете устанавливать свои зависимости с помощью npm. Вы даже можете сделать эту часть процесса развертывания

cd deps
npm install

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

var express = require('myapp_dependencies').express;
Дэниел Бердсли
источник
Спасибо, это лучший метод, который я когда-либо видел. Однако не будет ли require('express')в deps / index.js просто импортировать последнюю экспресс-версию, и не обязательно ту, которую мы установили? Я новичок в NodeJS, так что терпите меня.
adamJLev
Нет, это волшебство npm install, это добавляет символические ссылки в каталог вашего установленного пакета на правильные версии зависимых пакетов. Когда требуется пакет зависимостей, require('express')сначала проверяется локальный каталог и обнаруживается символическая ссылка на правильную версию express.
Дэниел Бердсли
5

Вам следует прочитать эти две статьи из блога Isaacs (автор npm). Я считаю, что они действительно хороши, и я считаю, что они расскажут вам, как достичь своей цели:

  1. http://blog.izs.me/post/1675072029/10-cool-things-you-probably-didnt-realize-npm-could-do
  2. http://foohack.com/2010/08/intro-to-npm/

Я считаю, что ссылка №1 (пункт №11) объясняет это:

11: объедините все свои зависимости в сам пакет

Когда вы используете команду npm bundle, npm помещает все ваши зависимости в папку node_modules вашего пакета. Но это еще не все.

Если вы хотите зависеть от чего-то, чего нет в реестре, вы можете это сделать. Просто сделай это:

npm bundle install http://github.com/whoever/whatever/tarball/master Это установит содержимое этого архива в пакет, а затем вы можете указать его как зависимость, и он не будет пытаться установить его, когда ваш пакет будет установлен.

Это также удобно, если у вас есть собственный форк чего-либо, и вы предпочитаете не менять имя.

Фактически, вы можете запустить практически любую команду npm в пакете. Чтобы посмотреть, что внутри, вы можете выполнить команду npm bundle ls. Чтобы что-то удалить, выполните npm bundle rm thing. И, конечно же, вы можете установить несколько версий и активировать ту, которую хотите.

Альфред
источник
Это полезно, хотя я не искал этого. Возможно, мне нужно добавить пояснение. Я ищу способ автоматической установки или обновления (на конечном компьютере) пакетов NPM, от которых зависит мое приложение при его развертывании. Похоже, npm bundleон используется для сбора всех ваших зависимостей в определенный каталог, отличный от каталога по умолчанию. Я, вероятно, предложу свое собственное решение, которое работает аналогично bundle install( bundlerдля рубина)
Дэниел Бердсли,
1
Просто примечание, начиная с npmверсии 1.0+, npm bundleбыло удалено. Вместо этого просто используйте npm installкоманду без имени пакета, она прочитает package.json и загрузит необходимые пакеты.
Артур Мальтсон
2

Начиная с версии Npm 1.1.2, есть новая команда, npm shrinkwrapкоторая создает npm-shrinkwrapped.jsonфайл, аналогичный Gemfile.lock. Его важно сделать, чтобы предотвратить гниение программного обеспечения (см. Обоснование Bundler ). Тем более, что у Nodejs очень быстро развивающееся сообщество.

Хотя bundle installсоздает Gemfile.lockавтоматически, npm installне будет создавать npm-shrinkwrapped.json(но будет использовать его, если он существует). Следовательно, вам нужно помнить об использовании npm shrinkwrap.

Прочтите полное руководство на http://blog.nodejs.org/2012/02/27/managing-node-js-dependencies-with-shrinkwrap/

Полковник Паник
источник
2

Мне кажется, что самое простое решение - использовать package.jsonфайл с установленным privateфлагом (добавленным в npm только в прошлом месяце) true. Таким образом, вы можете запустить npm installили npm bundleполучить зависимости вашего проекта, но вы предотвратите случайную публикацию вашего непубличного проекта кем-либо.

Вот пример package.json:

{
"name": "yourProject"
,"version": "1.0.0"
,"dependencies": { "express" : ">=2.1.0" }
,"private": true
}

Запуск npm installбудет установлен expressв локальной системе, если она еще не существует; running npm publishвыдает ошибку из-за "private": true.

Вы и ваша команда можете использовать тег версии для внутреннего использования, чтобы отслеживать изменения зависимостей с течением времени - каждый раз, когда вы меняете зависимость, повышайте версию. Чтобы узнать, какую версию вы установили, используйте npm ls installed.

Тревор Бернхэм
источник
Я думаю, вам не следует цитировать, trueи что это работает только потому, что строки являются истинными значениями (то есть !!"false" === true).
Камило Мартин
1

Также опубликуйте приложение npmи укажите его зависимости в файле package.json.

Когда кто-то использует npmдля установки вашего пакета, npmон позаботится о разрешении его зависимостей.

Спецификация пакетов: http://wiki.commonjs.org/wiki/Packages/1.0

Дэн Гроссман
источник
Да, но это веб-приложение без открытого исходного кода. Если у вас есть идея, которая не связана с публикацией приложения, отредактируйте свой ответ или создайте другой.
Дэниел Бердсли
1
Затем опубликуйте такой пакет, как "myapp-dependencies", который ваши пользователи могут использовать npmдля установки перед установкой вашего приложения. Я не думаю, что есть другой gemэквивалент для node.js.
Дэн Гроссман