Javascript's Modern Web Tools – Bower

by
Tags: , , , , ,

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:

webstorm-screenshot-code-complete

When we browse the project our HTML looks like this:

single-page-app-with-angular

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:

The application with Bootstrap enabled.
The application with Bootstrap enabled.

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