Lesson Monday

Today we're going to learn about a new development tool called Bower. It is a package manager like npm, but it is optimized for frontend packages like Bootstrap and jQuery.

Why do we need a separate frontend package manager? Isn't npm enough? There is debate in the community about this, but the main benefits of using a different package manager for the front-end are:

  • Separation of Power: Front-end developers have one file for their dependencies, and the back-end team has a different file for theirs. This can prevent version conflicts and disorganization.

  • Optimization: Some packages depend on specific versions of other packages. Sometimes two packages require different versions of the same dependency. npm installs each package's dependencies separately. If each of our backend modules has its own version of a package, they are independent and there is no conflict. Each package can have its own node_modules folder, and this is convenient but it can lead to complex paths and lots of files. Bower makes sure that each package is installed only once, even if it is used by multiple packages. This makes sense since we can't use jQuery-1.12.0 at the same time as jQuery-2.2.0 in the browser.

  • Language Independence: Bower does not have to be used with Node. For example, Bower can also be used as a package manager in Ruby on Rails or AngularJS.

Installing Bower

Let's get started. Bower is itself a Node module so we can install it easily with npm. It is recommended that we install it globally.

$ npm install bower -g

Note: On your machine you must have Admin permissions to run this. On Mac, you may have to use sudo npm install bower -g and on Windows you may have to run it using your Admin account.

Initializing Bower

We can begin using Bower the same way that we begin a project with npm. Bower also uses a manifest file in the top level of the project directory, but this time it must be named bower.json. We can create it using the following command:

$ bower init

The terminal will prompt us for information about the project. Feel free to add a name and description, but we can just press Enter to just use the default values.

Now, we should have a bower.json file that looks like this:

{
    "name": "pingpong",
    "description": "",
    "main": "index.js",
    "license": "ISC",
    "moduleType": [],
    "homepage": "",
    "ignore": [
    "*/.",
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ]
}

Installing Front-End Dependencies via Bower

Adding Front-End Dependencies to .gitignore

When we install packages with Bower, a folder called bower_components will be made. We should add this folder to our .gitignore file, just as we did with our node_modules folder holding npm dependencies:

.gitignore
bower_components/
node_modules/
.DS_Store

jQuery

Let's install our first front-end dependency, jQuery. We’ll switch to using the package for our pingpong app instead of relying on the Google CDN in our script tag. We can add jQuery to our project with a simple Bower install command. It has the same structure as an npm install command, but we are using the --save flag instead of our usual --save-dev flag because we want to use jQuery in the final production build.

$ bower install jquery --save

The syntax similarities don't stop there. When we clone a project that uses npm to manage its dependencies, we run npm install to put the packages on our local machine. We do the same thing to get our Bower dependencies:

$ bower install

Notice that Bower has created the directory to hold our dependencies called bower_components. We can load jQuery into our pingpong app from this folder by simply changing the path in our <script> tag. Instead of this:

index.html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>

We want this:

index.html
<script src="bower_components/jquery/dist/jquery.min.js"></script>

If we reload our html page in the browser, it should still work.

Bootstrap

Next, let's add Bootstrap the same way:

$ bower install bootstrap --save

Then we can then add it to our app the same way we would load it if we had downloaded it manually, except that again we'll find the files we need in the bower_components directory. Also, we need to make sure we're loading jQuery before the Bootstrap JavaScript, since jQuery is a dependency of Bootstrap.

index.html
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>

Now, let's test it out by adding some Bootstrap classes to our pingpong app. Here is what the final index.html should look like.

index.html
<!DOCTYPE html>
<html>
  <head>
    <script src="bower_components/jquery/dist/jquery.min.js"></script>
    <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
    <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="build/js/app.js"></script>
    <title>Ping Pong</title>
  </head>
  <body>
    <div class="container">
      <h1>Ping Pong!</h1>
      <form id="ping-pong-form">
        <div class="form-group">
          <label for="goal">Enter a number:</label>
          <input id="goal" type="number">
          <button class="btn-success" type="submit">Submit</button>
        </div>
      </form>
      <form id="signup">
        <div class="form-group">
          <label for="email">Enter your email:</label>
          <input id="email" type="text">
          <button class="btn-success" type="submit">Submit</button>
        </div>
      </form>
      <ul id="solution"></ul>
    </div>
  </body>
</html>

We can search for other Bower packages and compare them on the Bower website.

Moment.js

Let's add another JavaScript dependency. We're going to add Moment.js so that we can easily work with dates and times in various formats in our apps. First, we'll install it with Bower:

$ bower install moment --save

Since we will be using this in production, we want to use --save not --save-dev.

Now, we'll load its minified source into the browser with this <script> tag, making sure that it is loaded above our app.js file.

index.html
<script src="bower_components/moment/min/moment.min.js"></script>

This allows us to use Moment.js functions in our frontend JavaScript files. Let's make a new one and follow our naming convention so that it gets concatenated automatically, we'll call it time-interface.js and put it in our development js folder. Now, we can display the current time like this:

js/time-interface.js
$(document).ready(function(){
  $('#time').text(moment());
});

All we need to do is add an HTML tag with the id time to our index.html file.

index.html
<h3>Well look at the time! </h3>
<h3 id="time"></h3>

If we rebuild we will be able to see the current time displayed in the browser when we reload our page.

Terminology


  • Bower: A package manager (much like npm) specifically meant for front-end packages like Bootstrap and jQuery.

Tips


  • Use the --save flag instead ol --save-dev if the Bower package will be necessary in a project's production build.

Additional Resources