Utilisation de npm pour installer ou mettre à jour les packages requis, tout comme bundler pour rubygems

88

J'adore Bundler , c'est génial pour la gestion des dépendances. J'adore npm , installer des packages de nœuds est facile! J'ai une application nodejs et j'aimerais pouvoir spécifier les dépendances de mes applications et les installer / mettre à jour facilement partout où je déploie mon application. Ce n'est pas une bibliothèque que je publie, c'est une application Web à part entière.

Je connais la npm bundlecommande, mais cela semble simplement remplacer le répertoire où les packages sont installés.

J'ai l'habitude d'utiliser bundler de cette façon:

# Gemfile
gem "rails", "3.0.3"

Installe les rails v3.0.3 et toutes les autres gemmes requises sur la machine hôte uniquement si elles n'existent pas déjà

> bundle install

Comment puis-je réaliser quelque chose de similaire avec npm?

Daniel Beardsley
la source
ma réponse n'est-elle pas celle que vous vouliez savoir?
Alfred le

Réponses:

147

Depuis npm 1.0 (qui est maintenant ce que vous obtenez par défaut si vous suivez les étapes du fichier README), "bundle" n'est plus une chose séparée - c'est juste "comment ça marche".

Alors:

  1. Mettez un package.jsonfichier à la racine de votre projet
  2. Listez vos déps dans ce fichier

    { "name" : "my-project"
    , "version" : "1.0.0"
    , "dependencies" : { "express" : "1.0.0" } }
  3. npm install Puisque vous appelez cela sans argument, et pas en mode global, il installera simplement tous vos deps localement.

  4. require("express") et soyez heureux.
Isaacs
la source
2
En production, je recommande vivement de changer le your_app/node_modulesrépertoire local en un lien symbolique en dehors de votre répertoire d'application. Vous ne voulez pas avoir à télécharger, créer et installer chaque dépendance à chaque fois que vous déployez.
Daniel Beardsley
D'accord. et si j'oublie de mettre à jour mon package.json? Existe-t-il un moyen de forcer NPM à rechercher non pas package.json mais les packages que j'utilise dans mon code?
Pono
4
Ce n'est pas tout à fait correct. NPM installera toutes les dépendances pour ce qui précède my-projectdans ./node_modules/my-project/node_modules. Je ne sais pas s'il existe un moyen pratique d'installer toutes les dépendances dans ./node_modules Anyone?
Daniel Beardsley
@DanielBeardsley Je ne pense pas que ce soit comme ça que fonctionne npm. Si vous constatez ce comportement et que vous pouvez le reproduire, veuillez publier un problème sur la page github de npm.
isaacs
2
D'accord avec @DanielBeardsley. Je souffre de ce comportement même avec npm 1.1.70
graffic
10

Edit: Cela s'applique uniquement aux versions npm <1.0


C'était assez difficile à comprendre, mais NPM rend cela possible .

Vous avez besoin de trois composants

  1. Un sous-répertoire dans votre référentiel (ie deps/)
  2. Un package.jsonfichier dans le répertoire ci-dessus qui répertorie les dépendances
  3. Un index.jsfichier dans le répertoire ci-dessus qui nécessite vos dépendances

Exemple

Imaginez que l' express soit votre seule dépendance

deps / package.json

remarque: incrémentez le numéro de version à chaque fois que vous modifiez les dépendances

{
  "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
}

Vous devriez maintenant pouvoir installer vos dépendances en utilisant npm. Vous pouvez même intégrer cette partie de votre processus de déploiement

cd deps
npm install

Ensuite, dans le code de votre application, vous pouvez accéder à votre version spécifique d'express comme ceci:

var express = require('myapp_dependencies').express;
Daniel Beardsley
la source
Merci, c'est la meilleure méthode que j'ai vue jusqu'à présent. Cependant, le require('express')dans deps / index.js n'importerait-il pas simplement la dernière version express, et pas nécessairement celle que nous avons installée? Je suis un noob nodeJS alors s'il vous plaît, soyez avec moi.
adamJLev
Non, c'est la magie de npm install, il ajoute des liens symboliques dans le répertoire de votre package installé vers les versions correctes des packages dépendants. Lorsque votre package de dépendances est requis, le require('express')vérifie d'abord le répertoire local et trouve le lien symbolique vers la version correcte d'express.
Daniel Beardsley
5

Vous devriez lire ces deux articles du blog Isaacs (auteur npm). Je pense qu'ils sont vraiment bons et je crois qu'ils vous disent comment atteindre votre objectif:

  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/

Je crois que le lien n ° 1 (point n ° 11) explique ceci:

11: Regroupez toutes vos dépendances dans le package lui-même

Lorsque vous utilisez la commande npm bundle, npm placera toutes vos dépendances dans le dossier node_modules de votre package. Mais ça ne s'arrête pas là.

Si vous voulez dépendre de quelque chose qui ne figure pas dans le registre, vous pouvez le faire. Faites juste ceci:

npm bundle install http://github.com/whoever/wwhat/tarball/master Cela installera le contenu de cette archive tar dans le bundle, et vous pourrez ensuite le lister comme dépendance, et il n'essaiera pas de l'installer quand votre package est installé.

Ceci est également pratique si vous avez votre propre fourchette de quelque chose et que vous préférez ne pas changer le nom.

En fait, vous pouvez exécuter presque toutes les commandes npm sur le bundle. Pour voir ce qu'il y a à l'intérieur, vous pouvez faire npm bundle ls. Pour supprimer quelque chose, faites npm bundle rm thing. Et, bien sûr, vous pouvez installer plusieurs versions et activer celle que vous souhaitez.

Alfred
la source
C'est utile, même si ce n'était pas ce que je cherchais. J'ai peut-être besoin d'ajouter des précisions. Je recherche un moyen d'installer ou de mettre à jour automatiquement (sur la machine de destination) les packages NPM dont dépend mon application chaque fois que je la déploie. Il semble npm bundleest utilisé pour collecter toutes vos dépendances dans un répertoire spécifique autre que celui par défaut. Je vais probablement proposer ma propre solution qui fonctionne de la même manière que bundle install( bundlerpour ruby)
Daniel Beardsley
1
Juste une note, depuis la npmversion 1.0+, npm bundlea été supprimée. Au lieu de cela, utilisez simplement la npm installcommande sans nom de package, elle lira le package.json et affichera les packages requis.
Arthur Maltson
2

À partir de la version 1.1.2 de Npm, il existe une nouvelle commande npm shrinkwrapqui crée un npm-shrinkwrapped.jsonfichier, analogue à Gemfile.lock. Il est important d'en créer un, pour éviter la pourriture des logiciels (voir la justification de Bundler ). D'autant que Nodejs a une communauté aussi rapide.

Bien que bundle installcrée un Gemfile.lockautomatiquement, npm installne créera pas npm-shrinkwrapped.json(mais l'utilisera lorsqu'il existe). Par conséquent, vous devez vous rappeler d'utiliser npm shrinkwrap.

Lisez un guide complet sur http://blog.nodejs.org/2012/02/27/managing-node-js-dependencies-with-shrinkwrap/

Colonel Panic
la source
2

Il me semble que la solution la plus simple est d'utiliser un package.jsonfichier avec l' privateindicateur (ajouté à npm le mois dernier) défini sur true. De cette façon, vous pouvez exécuter npm installou npm bundlerécupérer les dépendances de votre projet, mais vous empêchez quiconque de publier accidentellement votre projet non public.

Voici un exemple package.json:

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

Running npm installs'installera expresssur le système local s'il n'existe pas déjà; l'exécution npm publishdonne une erreur à cause du"private": true .

Vous et votre équipe pouvez utiliser la balise de version en interne pour suivre les modifications de dépendance au fil du temps. Chaque fois que vous modifiez une dépendance, augmentez la version. Pour voir quelle version vous avez installée, utilisez npm ls installed.

Trevor Burnham
la source
Je pense que vous ne devriez pas citer trueet que cela ne fonctionne que parce que les chaînes sont des valeurs de vérité (c'est-à-dire !!"false" === true).
Camilo Martin
1

Publiez votre application avec npm et répertoriez ses dépendances dans votre fichier package.json.

Lorsque quelqu'un utilise npmpour installer votre package, npmse chargera de résoudre ses dépendances.

Spécifications des packages: http://wiki.commonjs.org/wiki/Packages/1.0

Dan Grossman
la source
Ouais, mais c'est une application Web non open source. Si vous avez une idée qui n'implique pas la publication de l'application, veuillez modifier votre réponse ou en créer une autre.
Daniel Beardsley
1
Publiez ensuite un package tel que "myapp-dependencies" que vos utilisateurs peuvent utiliser npmpour installer avant d'installer votre application. Je ne pense pas qu'il y ait d'autre geméquivalent pour node.js.
Dan Grossman