YellowLeds Weblog v2

Artikel über Webdesign, Webstandards und Serendipity von Matthias Mees

Asset-Verwaltung mit Bower

Schon länger hatte ich Bower als „Paket-Manager“ für meine Projektvorlage im Auge – einzelne jQuery-Plugins auf GitHub zu verfolgen und von Hand zu aktualisieren wird doch etwas umständlich. Eine Diskussion mit Jens auf Twitter gab mir neulich den nötigen „Tritt“, mir Bower genauer anzusehen und in die Projektvorlage zu integrieren.

Was ist Bower?

Bower ist ein „Paket-Manager für das Web“. Es basiert auf nodejs und git und wird – bereits installiertes nodejs, git und npm vorausgesetzt – ganz simpel über npm install -g bower installiert. Damit hat man Zugriff auf die Bower-Registry, quasi ein Verzeichnis in Bower verfügbarer Pakete.

bower help im Terminal gibt eine kurze Funktionsübersicht aus, bower install in einem entsprechend vorbereiteten Projektverzeichnis startet die Installation der eingebundenen Assets.

Beispielhafte Ausgabe des Kommandos bower install im Terminal

Bower liefert übrigens nicht nur Javascript-Bibliotheken und -Plugins, in der Registry finden sich auch z.B. CSS-Frameworks und Sass-Bibliotheken. Im Prinzip kann Bower alles einbinden, was in einem Webprojekt als Komponente denkbar ist – es muss dazu nicht einmal unbedingt in Bower registriert sein, so lange es auf GitHub verfügbar ist.

Der unschätzbare Vorteil an Bower (wie an eigentlich allen Paket-Managern) ist dabei die Auflösung von Abhängigkeiten. Benötigt eine Komponente eine weitere Komponente, um zu funktionieren, die im Projekt nicht direkt referenziert wird, holt Bower deren Archiv mit ab. Einfachstes (wenngleich sehr unrealistisches) Beispiel wäre, zu einem jQuery-Plugin auch gleich die jQuery-Bibliothek einzubinden – Bower kümmert sich jedoch nicht um das Referenzieren der Assets im Quelltext, das muss der Entwickler schon selbst erledigen.

Bower konfigurieren

Auf Dauer möchte man Bower einmalig einrichten und ausführen – dazu legt man sich eine bower.json an. Diese JSON-Datei enthält (ganz ähnlich der package.json von Grunt) quasi eine Liste der Assets, von denen ein Projekt abhängt und die Bower folglich verwalten soll. Will man z.B. jQuery und Modernizr verwenden, sieht das etwa so aus:

{
    "name":         "Meine Projektvorlage",
    "version":      "0.0.1",
    "main":         "",
    "ignore":       [],
    "dependencies": {
        "jquery":                   "~1.10.2",
        "modernizr":                "~2.6.2"
    },
    "devDependencies": {}
}

Ich habe noch nicht ausprobiert, ob die im Codebeispiel leeren Werte zwingend nötig sind, aber so sieht das Grundgerüst eine bower.json aus. Ein bower install holt nun die “dependencies” in den angegebenen Versionsnummern von GitHub ab und legt sie (standardmäßig) in Unterverzeichnissen im Verzeichnis bower_components ab.

Will man – wie ich, der bei sowas immer irgendeinen Sonderwunsch auf Lager hat – die Assets in einem anderen Verzeichnis ablegen, braucht man eine Konfigurationsdatei namens .bowerrc im Projektverzeichnis. Diese ist ebenfalls im JSON-Format und sieht bei mir (meine JS-Assets liegen im Verzeichnis scripts der Projektvorlage) so aus:

{
    "directory":    "scripts"
}

Damit landet z.B. das jQuery-Archiv in scripts/jquery/. Über die .bowerrc kann man z.B. auch einen Proxy konfigurieren oder die Ausgabe des bower-Kommandos anpassen.

4 Trackbacks

9 Kommentare

Eric Eggert

Eric Eggert

Das Grunt-Plugin bower-install übernimmt die Einbindung von allen installierten Bower-Paketen in HTML-Dateien – zumindest für das Entwickeln nützlich, Minifizieren und Zusammenfassen von diesen JS-Dateien scheint noch nicht möglich.

Matthias Mees

Matthias Mees

Danke für den Hinweis. Spannend, aber (für mich) nicht unbedingt nötig. Kombinieren und minifizieren übernimmt eh Grunt, zudem verwende ich Bower derzeit nur für JS-, nicht für (S)CSS-Assets. Das lief bei mir auf gerade mal zwei Assets hin, deren Pfad ich einmalig anpassen musste. :)

Aber wer lieber oder aus Gründen während der Entwicklung etliche Assets im HTML referenziert, könnte das Plugin mal im Auge behalten.

Jens Grochtdreis

Jens Grochtdreis

Übrigens kann man auch ausserhalb von Github Repos einbinden. Ich habe ein privates Projekt bei Bitbucket und binde es mittels Bower einfach nur mit "git@bitbucket.com:Flocke/" (und so weiter) ein. Das ist echt prima. Und da ich weder das gesamte jQuery-Projekt noch mein gesamtes Projekt benötige, lasse ich alles hübsch standardmäßig in "components" kopieren.

Und dann nutze ich Grunt, um aus diesem Bower-Ordner die benötigten Dateien und Verzeichnisse an die eigentlichen Ziele zu kopieren. Dann kann ich auch mittels Bower die Komponenten aktualisieren, ohne dass dies automatisch auf mein Projekt durchschlägt.

Wenn Du mir vor einem Jahr gesagt hättest, dass ich sowas mal machen würde, hätte ich Dich für verrückt erklärt. Und dass ich dann auch noch dafür verantwortlich bin, dass Du sowas machst, muss ich erst noch verdauen :-)

Matthias Mees

Matthias Mees

Funktioniert denn bei so hinzugefügten Repositories die Aktualisierung über das Bower-Update? Das finde ich einen guten Grund, Bower überhaupt zu verwenden (wobei ich zugeben muss, dass noch nicht wirklich ausprobiert zu haben, aber theoretisch sollte es ja Assets updaten, wenn ich das richtig verstehe).

Jens Grochtdreis

Jens Grochtdreis

Die Aktualisierung funktioniert doch auch nicht automatisch, oder habe ich da etwas übersehen? Und wenn Du dann neue Daten anforderst, dann kann das doch auch mit meinem Bitbucket-Repo klappen, oder? Aber probiert habe ich es noch nicht, muss ich zugeben.

Matthias Mees

Matthias Mees

Ich frag mich halt, woran Bower erkennen sollte, dass es bei einem „manuell“ hinzugefügten Repository eine neuere Version gibt – wobei sich dann auch die Frage stellt, woran es das eigentlich bei registrierten Repositories erkennt. Es wäre natürlich möglich, dass das über git-Tags läuft, dann ginge es wohl auch bei „manuellen“ Repos.

Es nützt wohl alles nix, ich muss damit mal ausgiebiger rumspielen. :)

Matthias Mees

Matthias Mees

Test #1: Habe ich in der bower.json für ein registriertes Paket

  • eine feste Versionsnummer, wird immer diese installiert
  • eine ungefähre Versionsnummer wie oben im Codebeispiel) wird diese installiert oder eine neuere, falls eine neuere verfügbar ist
  • erst eine feste, die bereits installiert ist, und ersetze diese durch eine höhere, so installiert bower update die neuere

Da die bower.json eines Paketes immer nur die aktuelle Version enthält, nehme ich an (weiss es aber nicht 100%ig sicher), dass git-Tags für die Auflistung aller verfügbaren Versionen mittels bower info PAKETNAME zuständig sind.

Matthias Mees

Matthias Mees

Test #2: Nicht registrierte Pakete kann man wie von Jens beschrieben über einen “git endpoint” installieren (und sogar in die bower.json übernehmen).

Man kann (wie ich am Beispiel von jQuery gMap gerade ausprobiert habe) dabei auch Versionen verwenden (was wieder auf Tags hinweist, denke ich), nicht aber bower update einsetzen.

Kommentar schreiben

Die angegebene E-Mail-Adresse wird nicht dargestellt, sondern nur für eventuelle Benachrichtigungen verwendet.
Markdown-Formatierung erlaubt