Skip to main content

Using Bower, npm and updates to AngularJS

3 min read

Older Article

This article was published 13 years ago. Some information may be outdated or no longer applicable.

I finally caved and started using bower after my friend nudged me one too many times. Laziness had been winning, but here we are.

I’ve updated the GitHub repository for the Contact Manager. Clone the repo, run npm install to grab the npm packages, then call bower install to pull in the components.

Here are a few thoughts on bower, npm/node.js, and the breaking changes between AngularJS 1.1.5 and 1.2.0rc1.

Bower

As I’ve mentioned roughly 100 times, I run a Ubuntu Virtual Machine on VirtualBox for development, and I auto-login as the ‘root’ user. This made every bower command spit out: “Bower is a user command, there is no need to execute it with superuser permissions”. So I set up an alias using the --allow-root flag (no, I’m not creating a new user. I am the superuser):

root@ubuntu:/# vi ~/.bashrc
alias bower="bower --allow-root"

Sorted.

Bower creates a bower_components folder by default. To change that, I dropped a .bowerrc file into my project:

{
  "directory": "components"
}

This tells bower to install everything into the components folder.

If you’re running Express JS (like I do), you’ll also need a static path for /components, otherwise Express will rightly throw a 404. I added this to my app.js:

app.use('/components', express.static(__dirname + '/components'));

npm and node.js

How many times have you run node app.js, hit a bug, fixed the source, ctrl-c’d the process, and typed the start command again? I did it far too many times. Now I’m using an npm package called nodemon that watches for file changes and automatically restarts the application. No more manual restarts.

This also means I can type npm start instead of node app.js. How? The npm start command reads its arguments from package.json in the project root (the same file that lists your npm dependencies). Here’s the full file for the contact manager:

{
  "name": "contact-manager",
  "description": "",
  "version": "0.0.1",
  "author": {
    "name": "Tamas Piros",
    "email": "tamas@tamaspiros.co.uk",
    "web": "http://tamaspiros.co.uk"
  },
  "scripts": {
    "start": "NODE_PATH=./app/controllers NODE_ENV=development ./node_modules/.bin/nodemon app.js"
  },
  "dependencies": {
    "express": "latest",
    "mongoose": "latest",
    "ejs": "latest",
    "nodemon": "latest"
  }
}

Notice the highlighted line telling nodemon to watch app.js.

Updating AngularJS

Updating from AngularJS 1.1.5 to 1.2.0rc1 broke a few things. I went with the release candidate because I wanted ng-if, which wasn’t in the latest stable release at the time.

Here’s what tripped me up:

  1. urlSanitizationWhitelist failed

This function got removed in 1.2.0. The replacement is aHrefSanitizationWhitelist:

$compileProvider.aHrefSanitizationWhitelist(/^\s*(https|skype|mailto):/);
  1. Uncaught Error: [$injector:modulerr] Failed to instantiate module contacts due to: Error: [$injector:unpr] Unknown provider: $routeProvider

The fix: open the AngularJS app.js file (not the backend one) and add the ngRoute directive:

angular.module('contacts', ['ngRoute','contacts.filters', 'ui.bootstrap']).

That alone won’t do it. You also need to include the actual script:

<script src="/components/angular-route/angular-route.js"></script>

Watch out for these changes. They can eat hours if you don’t know what’s shifted.

Next up, I’ll be looking at grunt. Until then.