Verwenden von npm zum Installieren oder Aktualisieren erforderlicher Pakete, genau wie Bundler für Rubygems

88

Ich liebe Bundler , es ist großartig im Abhängigkeitsmanagement. Ich liebe npm , die Installation von Knotenpaketen ist einfach! Ich habe eine NodeJS-App und würde gerne meine Apps-Abhängigkeiten angeben und sie einfach installieren / aktualisieren können, wo immer ich meine App bereitstelle. Dies ist keine Bibliothek, die ich veröffentliche, sondern eine vollwertige Web-App.

Ich kenne den npm bundleBefehl, aber das scheint einfach das Verzeichnis zu überschreiben, in dem Pakete installiert sind.

Ich bin es gewohnt, Bundler auf diese Weise zu verwenden:

# Gemfile
gem "rails", "3.0.3"

Installiert Rails v3.0.3 und andere erforderliche Edelsteine ​​nur dann auf dem Host-Computer, wenn sie noch nicht vorhanden sind

> bundle install

Wie kann ich mit npm etwas Ähnliches erreichen?

Daniel Beardsley
quelle
Ist meine Antwort nicht das, was du wissen wolltest?
Alfred

Antworten:

147

Ab npm 1.0 (was Sie jetzt standardmäßig erhalten, wenn Sie die Schritte in der README-Datei ausführen) ist "Bundle" keine getrennte Sache mehr - es ist nur "wie es funktioniert".

So:

  1. Legen Sie eine package.jsonDatei im Stammverzeichnis Ihres Projekts ab
  2. Listen Sie Ihre Deps in dieser Datei auf

    { "name" : "my-project"
    , "version" : "1.0.0"
    , "dependencies" : { "express" : "1.0.0" } }
  3. npm install Da Sie dies ohne Argumente und nicht im globalen Modus aufrufen, werden nur alle Ihre Deps lokal installiert.

  4. require("express") und sei glücklich.
isaacs
quelle
2
In der Produktion empfehle ich dringend, das lokale your_app/node_modulesVerzeichnis in einen Symlink außerhalb Ihres App-Verzeichnisses zu ändern . Sie möchten nicht bei jeder Bereitstellung jede Abhängigkeit herunterladen, erstellen und installieren müssen.
Daniel Beardsley
OK. Was ist, wenn ich vergesse, meine package.json zu aktualisieren? Gibt es eine Möglichkeit, NPM zu zwingen, nicht nach package.json zu suchen, sondern nach Paketen, die ich in meinem Code verwende?
Pono
4
Das ist nicht ganz richtig. NPM installiert alle Abhängigkeiten für die oben genannten my-projectin ./node_modules/my-project/node_modules. Ich bin mir nicht sicher, ob es eine bequeme Möglichkeit gibt, alle Abhängigkeiten in ./node_modules Anyone zu installieren .
Daniel Beardsley
@ DanielBeardsley Ich glaube nicht, dass npm so funktioniert. Wenn Sie dieses Verhalten sehen und es reproduzieren können, veröffentlichen Sie bitte ein Problem auf der npm-Github-Seite.
Isaacs
2
Stimmen Sie mit @DanielBeardsley überein. Ich leide unter diesem Verhalten sogar mit npm 1.1.70
graffic
10

Bearbeiten: Dies gilt nur für npm-Versionen <1.0


Es war ziemlich schwierig, das herauszufinden, aber NPM macht dies möglich .

Sie benötigen drei Komponenten

  1. Ein Unterverzeichnis in Ihrem Repository (dh deps/)
  2. Eine package.jsonDatei im obigen Verzeichnis, in der Abhängigkeiten aufgelistet sind
  3. Eine index.jsDatei im obigen Verzeichnis, die Ihre Abhängigkeiten erfordert

Beispiel

Stellen Sie sich vor, Express ist Ihre einzige Abhängigkeit

deps / package.json

Hinweis: Erhöhen Sie die Versionsnummer jedes Mal, wenn Sie die Abhängigkeiten ändern

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

Jetzt sollten Sie in der Lage sein, Ihre Abhängigkeiten mit npm zu installieren. Sie können diesen Teil sogar in Ihren Bereitstellungsprozess einbeziehen

cd deps
npm install

Dann können Sie in Ihrem App-Code wie folgt auf Ihre spezifische Express-Version zugreifen:

var express = require('myapp_dependencies').express;
Daniel Beardsley
quelle
Danke, das ist die beste Methode, die ich bisher gesehen habe. require('express')Würden die in deps / index.js nicht einfach die neueste Express-Version importieren und nicht unbedingt die, die wir installiert haben? Ich bin ein NodeJS Noob, also bitte ertrage es mit mir.
AdamJLev
Nein, das ist die Magie von npm install, es fügt Symlinks im Verzeichnis Ihres installierten Pakets zu den richtigen Versionen abhängiger Pakete hinzu. Wenn Ihr Abhängigkeitspaket erforderlich ist, wird dasrequire('express') überprüft das zuerst das lokale Verzeichnis und findet den Symlink zur richtigen Version von Express.
Daniel Beardsley
5

Sie sollten diese beiden Artikel aus dem Isaacs-Blog (Autor npm) lesen. Ich denke, sie sind wirklich gut und ich glaube, sagen Sie, wie Sie Ihr Ziel erreichen können:

  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/

Ich glaube, Link Nr. 1 (Punkt Nr. 11) erklärt dies:

11: Bündeln Sie alle Ihre Abhängigkeiten im Paket selbst

Wenn Sie den Befehl npm bundle verwenden, legt npm alle Ihre Abhängigkeiten im Ordner node_modules in Ihrem Paket ab. Aber es hört hier nicht auf.

Wenn Sie sich auf etwas verlassen möchten, das nicht in der Registrierung enthalten ist, können Sie dies tun. Mach das einfach:

Installation des npm-Bundles Installation des http://github.com/whoever/whatever/tarball/master Hiermit wird der Inhalt dieses Tarballs im Bundle installiert. Anschließend können Sie ihn als Abhängigkeit auflisten und nicht versuchen, ihn zu installieren, wenn Ihr Paket wird installiert.

Dies ist auch praktisch, wenn Sie eine eigene Gabelung haben und den Namen lieber nicht ändern möchten.

Tatsächlich können Sie fast jeden npm-Befehl im Bundle ausführen. Um zu sehen, was drin ist, können Sie das npm-Bundle ls ausführen. Um etwas zu entfernen, machen Sie npm bundle rm thing. Natürlich können Sie mehrere Versionen installieren und die gewünschte aktivieren.

Alfred
quelle
Dies ist nützlich, obwohl es nicht das war, wonach ich gesucht habe. Vielleicht muss ich noch Klarheit schaffen. Ich suche nach einer Möglichkeit, die NPM-Pakete, von denen meine App abhängt, automatisch zu installieren oder zu aktualisieren (auf dem Zielcomputer), wenn ich sie bereitstelle. Es sieht so aus, als würde npm bundlees verwendet, um alle Ihre Abhängigkeiten in einem anderen Verzeichnis als dem Standardverzeichnis zu sammeln. Ich werde wahrscheinlich meine eigene Lösung finden, die ähnlich funktioniert wie bundle install( bundlerfür Ruby)
Daniel Beardsley
1
Nur ein Hinweis, seit npmVersion 1.0+, npm bundlewurde entfernt. Verwenden Sie stattdessen einfach den npm installBefehl ohne Paketnamen. Er liest die Datei package.json und ruft die erforderlichen Pakete auf.
Arthur Maltson
2

Ab Npm Version 1.1.2 gibt es einen neuen Befehl , der analog zu npm shrinkwrapeine npm-shrinkwrapped.jsonDatei erstellt Gemfile.lock. Es ist wichtig, eine zu erstellen , um Softwarefäule zu verhindern (siehe Bundlers Begründung ). Zumal Nodejs eine so schnelllebige Community hat.

Während bundle installein Gemfile.lockautomatisch erstellt wird, npm installwird nicht erstellt npm-shrinkwrapped.json(wird aber verwendet, wenn es vorhanden ist). Daher müssen Sie daran denken, zu verwenden npm shrinkwrap.

Lesen Sie eine vollständige Anleitung unter http://blog.nodejs.org/2012/02/27/managing-node-js-dependencies-with-shrinkwrap/

Oberst Panik
quelle
2

Es scheint mir, dass die einfachste Lösung darin besteht, eine package.jsonDatei zu verwenden, deren privateFlag (erst letzten Monat zu npm hinzugefügt) gesetzt ist true. Auf diese Weise können Sie die Abhängigkeiten Ihres Projekts ausführen npm installoder npm bundleabrufen, aber Sie verhindern, dass jemand versehentlich Ihr nicht öffentliches Projekt veröffentlicht.

Hier ist ein Beispiel package.json:

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

Running npm installwird expressauf dem lokalen System installiert , sofern es noch nicht vorhanden ist. Laufen npm publishgibt einen Fehler wegen der"private": true .

Sie und Ihr Team können das Versions-Tag intern verwenden, um Abhängigkeitsänderungen im Laufe der Zeit zu verfolgen. Jedes Mal, wenn Sie eine Abhängigkeit ändern, stoßen Sie die Version an. Verwenden Sie, um zu sehen, welche Version Sie installiert haben npm ls installed.

Trevor Burnham
quelle
Ich denke, Sie sollten nicht zitieren trueund dass es nur funktioniert, weil Zeichenfolgen wahrheitsgemäße Werte sind (das heißt !!"false" === true).
Camilo Martin
1

Veröffentlichen Sie Ihre App mit npm und listen Sie die Abhängigkeiten in Ihrer Datei package.json auf.

Wenn jemand npmIhr Paket installiert npm, kümmert er sich um die Auflösung seiner Abhängigkeiten.

Paketspezifikation: http://wiki.commonjs.org/wiki/Packages/1.0

Dan Grossman
quelle
Ja, aber dies ist eine Nicht-OpenSource-Web-App. Wenn Sie eine Idee haben, bei der die App nicht veröffentlicht werden muss, bearbeiten Sie Ihre Antwort oder erstellen Sie eine andere.
Daniel Beardsley
1
Veröffentlichen Sie dann ein Paket wie "myapp-Abhängigkeiten", mit dem Ihre Benutzer npmvor der Installation Ihrer App installieren können. Ich glaube nicht, dass es ein anderes gemÄquivalent für node.js gibt.
Dan Grossman