Bower – a dependency manager for HTML projects
Dubbed 'a package manager for the web', you can also think of it as an URL shortcut service for downloading distributions from Git endpoints like GitHub.
Although not as feature-rich as npm
, and not requiring or providing any security or auditing of individual packages, Bower serves a simple downloading tool. You can use Bower as a mechanism to provide development-time versions of dependencies such as jQuery, a Javascript MVC framework, Bootstrap, etc.
Coupled with our next tool on the list, Grunt
, you can set up a develop-in-place web application that then gets minified and compressed down to several CSS and Javascript files when you're ready to package it within a web application or as the code for a mobile, PhoneGap app on iOS or Android.
Getting started with Bower
But we're getting ahead of ourselves. We need to start by thinking about the disparate requirements of browser application developers -vs- end users. For example, browser developers want:
- no-deploy turnaround of changes to files
- instant response from unit testing and scenario testing tools (go from red-to-green in 1 second)
- easy addition of Javascript, CSS, HTML frameworks with their uncompressed source code for easy debugging
- ability to package the final project for deployment in a minified way
End users need:
- Compressed, minified files for Javascript, CSS, etc…
- A small number of files
- Speed of execution
What we need to do to support both camps is put together a flexible project structure. Here is one model:
/ app bower-components component-1 component-2 images scripts controllers services directives app.js styles views index.html dist images app-minified.js frameworks-minified.js styles-minified.css index.html Gruntfile.js
In the model above, we provide a series of components, using Bower, for development-time use. These components can be HTML/CSS frameworks, LESS and SASS scripts, Javascript libraries, and anything you'd use by downloading them from the internet. Our developer HTML file, /app/index.html
, will directly mount the uncompressed source-level versions of all of the projects. We'll put the project through a grunt
script (in our next tutorial) to minify it and prepare it for deployment to a web server or mobile application.
But for now, let's work with this structure and get Bower involved. So we'll create the app structure (I'm using Linux/Mac shell scripts but you can build them in your own file explorer if on Windows):
mkdir -p app/images app/scripts/controllers \ app/scripts/services \ app/scripts/directives \ styles views
Now, we'll use Bower to define our components. We'll start with bower init
:
> bower init (output) [?] name: jstools-bower-project [?] version: 0.0.0 [?] description: [?] main file: [?] keywords: [?] authors: Ken Rimple <krimple@chariotsolutions.com> [?] license: MIT [?] homepage: index.html [?] set currently installed components as dependencies? No [?] add commonly ignored files to ignore list? Yes [?] would you like to mark this package as private which prevents it from being accidentally published to the registry? YesN) y { name: 'jstools-bower-project', version: '0.0.0', authors: [ 'Ken Rimple <krimple@chariotsolutions.com>' ], license: 'MIT', homepage: 'index.html', private: true, ignore: [ '**/.*', 'node_modules', 'bower_components', 'test', 'tests' ] } [?] Looks good? Yes
Working with components
As you can see, after answering a few questions, Bower outputs a project file, bower.json
, which will contain the settings for all of your files. This file will contain all of the project and version information for libraries you'll be using to develop your browser-based application.
Let's add the AngularJS MVC framework to our project, and install it in HTML. First, we'll tell Bower to download AngularJS and a few related libraries:
bower install angular --save-dev bower install angular-route --save-dev bower install angular-resource --save-dev
Bower downloads the components into the bower_components
directory:
bower_components angular README.md angular-csp.css angular.js angular.min.js angular.min.js.gzip angular.min.js.map bower.json angular-resource README.md angular-resource.js angular-resource.min.js angular-resource.min.js.map bower.json angular-route README.md angular-route.js angular-route.min.js angular-route.min.js.map bower.json
Think of this like a source code library, but one that includes distributable versions. the AngularJS projects are downloaded into their own subdirectories of bower_components
, and contain both minified and un-minified versions of themselves.
Note that this is a convention, and that Bower does not impose one on Bower component developers. However, most follow it.
Versioning
Bower is a dependency manager, so built into the tool are version numbers for your libraries. When you used the --save-dev
command-line flag, you told Bower to store the downloaded version from that component's bower.json
descriptor in your own bower.json
project. Here is your current bower.json
file in the root of the application:
{ "name": "jstools-bower-project", "version": "0.0.0", "authors": [ "Ken Rimple <krimple@chariotsolutions.com>" ], ... "devDependencies": { "angular": "~1.2.6", "angular-resource": "~1.2.6", "angular-route": "~1.2.6" } }
(We skipped the crud in the middle). The devDependencies
section defines what libraries you're using. We asked for angular
, angular-route
and angular-resource
and at the time of publication the versions available were 1.2.6
. The syntax that includes the tilde (~
) comes from the Node semvar project. It means any version that starts with 1.2.6, so any bugfixes to 1.2.6 should be included. (More information here).
Setting up our application
Now let's set up our application to use AngularJS. We'll create our content in /app/index.html and reference our bower project:
<!DOCTYPE html> <html ng-app> <head> <title>Our single page app</title> </head> <body> 12 + 3 = {{ 12 + 3 }}! <script src="bower_components/angular/angular.js"></script> <script src="bower_components/angular-resource/angular-resource.js"></script> <script src="bower_components/angular-route/angular-route.js"></script> </body> </html>
It should be mentioned at this point that I use IntelliJ WebStorm to edit my Javascript projects. It has code-completion for things like Javascript file names, browser-based debugging, and a lot of other features. Plus I can just use wstorm .
to open WebStorm in my current project directory and start editing. Here's a screenshot:
When we browse the project our HTML looks like this:
Not overly exciting, but then this isn't an AngularJS tutorial.
Adding a CSS Framework
Let's sauce up our web application by adding Bootstrap to it. We'll search Bower for appropriate packages:
> bower search bootstrap Search results: bootstrap git://github.com/twbs/bootstrap.git angular-bootstrap git://github.com/angular-ui/bootstrap-bower.git sass-bootstrap git://github.com/jlong/sass-bootstrap.git bootstrap-sass git://github.com/jlong/sass-twitter-bootstrap bootstrap-datepicker git://github.com/eternicode/bootstrap-datepicker.git bootstrap-select git://github.com/silviomoreto/bootstrap-select.git bootstrap-timepicker git://github.com/jdewit/bootstrap-timepicker bootstrap.css git://github.com/bowerjs/bootstrap.git angular-ui-bootstrap git://github.com/angular-ui/bootstrap.git angular-ui-bootstrap-bower git://github.com/angular-ui/bootstrap-bower ... (208 results in total!)
Sheesh, that's a lot of bootstrap libraries. Factoid #1 on Bower – it's not policed. Anyone can submit a package with bower register
– which is why they ask up front whether you want to allow your package to be deployed.
I happen to know that the angular-ui-bootstrap
project installs special Angular components called 'directives' that can supply us some special widgets in an Angular-friendly way. Also, a few weeks ago they just updated to Bootstrap 3.0. So let's install that one:
bower install angular-ui-bootstrap --save-dev
Next, we'll install Bootstrap itself:
bower install bootstrap --save-dev
Now we have what we need to transform our project into something cooler. Let's update our HTML:
<!DOCTYPE html> <html> <head> <title>The Great Angular Calculator</title> <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.css"> </head> <body> <h1>Angular Demo App</h1> <section ng-app="myApp" class="container"> <div class="jumbotron"> The great number adder! All watch the amazing application!!! </div> <alert>Let's add numbers!</alert> <form role="form-inline"> <input type="number" class="form-control" ng-model="a"> + <input type="number" class="form-control" ng-model="b"> = {{ a + b || 0 }}! </form> </section> <script src="/bower_components/angular/angular.js"></script> <script src="/bower_components/angular-resource/angular-resource.js"></script> <script src="/bower_components/angular-route/angular-route.js"></script> <script src="/bower_components/angular-ui-bootstrap/ui-bootstrap-tpls-0.10.0.js"></script> <script> angular.module('myApp', ['ui.bootstrap']); </script> </body> </html>
This application boots Twitter Bootstrap's style engine by adding the stylesheet, and sets up the Angular JS engine to include an adapter to provide custom tags (via directives) such as the alert
tag above. It boots Angular's framework to create a named application, myApp
, and attach it to the section
that contains a simple adding machine.
Here it is, in full glory:
AngularJS contains some really cool form validation code, such as only allowing numbers and providing spinners for form fields with the type of number
. We use Angular's model elements, providing two model variables, a
and b
, which automatically data-bind and provide instant updates to our formula, {{ a + b || 0 }}
, which displays the result of adding model variables a
and b
or the value 0
if both are not defined.
We could have used any supported JS or HTML framework in our demo application, so feel free to try this on your own and search for your favorite Bower repository.
Final thoughts on Bower
Bower is not a panacea – it doesn't contain a vetted, safe repository for every element and so may not be the best bet for safety when you're putting together your enterprise project – you have to audit the packages you use and make sure they come from valid sources.
Although Bower allows you to treat it like a dependency downloader and distribute the dependencies at build time, the Bower team suggests you actually check in those dependencies. This is because the projects provided can be distributed in any git-based repository, unlike a permanent, vetted repository like the Maven central repo.
Bower is a useful tool for client-side dependency management. It provides search, lookup, registration and download services and a way to distribute your code to the outside world. However, it does not handle server-side dependencies, such as providing code for NodeJS, and it doesn't deal with build processes.
For the former, see our prior tutorial on the Node Package Manager. We'll deal with build processing in our next tutorial, 'Grunt'.
Resources
- Bower – A package manager for the web
- Angular JS – The superheroic web framework
- Angular UI – A wrapper around the Twitter Bootstrap framework
- Twitter Bootstrap – The popular CSS and Javascript style framework