Share via



October 2015

Volume 30 Number 10

Visual Studio - Bower: Modern Tools for Web Development

By Adam Tuliper | October 2015

For a long, long time, we lived in a beautiful walled garden. In this protected ecosystem of Web development, we used sophisticated technology like ASP.NET and Visual Studio. The rest of the world’s tools were considered rather inferior. We were part of an empire, if you will, and it was a pretty good place to be for a long time.

However, as time has passed, development cultures, tools, resources, and more have become fragmented and even chaotic. But some pretty solid tech has cropped up during this period, including Bootstrap, AngularJS, Git, jQuery, Grunt, Gulp, and Bower, and Web developers accustomed to the Microsoft ecosystem are able to take advantage of these tools.

In this first part of a two-article series, I’ll provide an overview of Bower, a package manager primarily for (but not limited to) front-end Web development. In the second article, I’ll cover Grunt and Gulp, two JavaScript-based task runners that can be used to perform all sorts of tasks, like copying files, minification, concatenation, and even compilation.

Grunt, Gulp and Bower are additional tools in your Web development arsenal. Tooling to integrate with them is built into Visual Studio 2015 and available via add-ins for Visual Studio 2012 and 2013. You still need to install them.

Some of you might be wondering if Microsoft is making you learn and use even more tools. Doesn’t NuGet work just fine for packages, and isn’t msbuild sufficient as a build tool? The answer to both questions is yes—in many but not all scenarios. And for those cases where conventional tools don’t suffice, Grunt, Gulp and Bower can help. In a Web project, you might want to compile your Sass whenever a CSS file changes. Or you may want to get the latest Bootstrap or Angular release without waiting for someone at Microsoft to create a NuGet package from it. You can’t accomplish either task with NuGet or msbuild.

NuGet is an awesome technology and continues to be developed, supported and tightly integrated into Visual Studio. Continue using it for your projects, especially for binaries and projects that need to make changes to your Visual Studio solutions. Each time a new version of jQuery or Bootstrap comes out, though, someone must create and release a NuGet package for it. But because Bower can use semantic versioning, as soon as a tool is released and tagged on GitHub, Bower can use it; no need to wait for someone else to package it up in a NuGet package.

I’ll be using the Node Package Manager (npm) for the Bower installation and for several items in the next article. Because npm isn’t provided as a standalone download, simply install Node.js from nodejs.org. For more information on installing and using npm, visit the Microsoft Virtual Academy “Package Management and Workflow Automation” page at bit.ly/1EjRWMx.

Bower is a major package manager typically used for front-end Web development and, arguably, it’s the only front-end-only package manager solution. Most packages used in front-end Web development, such as Bootstrap, jQuery, and AngularJS, can be installed using either npm or Bower, but in many cases the dependency management may be a bit easier with Bower (although some may disagree).

Bower packages, unlike NuGet packages, aren’t limited to a single source type. A Bower package can be a Git endpoint, a folder on a file system, a URL for content files or zipped files, and more. Bower integrates with a package registry that lists published packages, but packages don’t have to be listed in Bower to be installed.

Installing and Using Bower

Bower typically pulls from a Git repository, so you’ll need to install msysgit (msysgit.github.io) and select the option to run from the command prompt, as shown in Figure 1.

Install msysgit with Command-Line Support
Figure 1 Install msysgit with Command-Line Support

You use npm to install Bower globally so you can use it from anywhere on your system.  You only need to install Bower once, not per project.

npm install -g bower

Now you’re all set to use Bower. Open a command line to your project folder root and use the following format to install a package into your project:

bower install <package name/url/zip/etc.> --save

For example, to install jquery, simply enter:

bower install jquery --save

The first three words probably make sense, but the --save might need some explanation. This parameter causes an entry to be written to the bower.json file to note you’ve installed this package. (Bower doesn’t create this file by default; you need to tell it to do so, as I’ll discuss shortly.) By default, the Bower install command creates a bower_components folder in the folder where you run the install command; the bower_components folder name can be customized using a Bower configuration file, .bowerrc.

You’ll notice in Figure 2 the jQuery package install results in many more files and folders than you might expect. All I really want in my project is jQuery.js, but in this case I get the entire jQuery source code tree. Many package installs do indeed give you the entire source code tree, often significantly more than you want. This leaves new Bower users wondering which file to use.

Bower Installs the Entire jQuery Source Tree
Figure 2 Bower Installs the Entire jQuery Source Tree

Some projects will release a packaged version of the app minus all the extra files you don’t want. For example, the Bower package for AngularJS is a repository off of the Angular root on GitHub at github.com/angular/bower-angular. When you install this package (bower install angular --save), you get only the .js and .css you need to reference in your HTML pages.

To find packages, you can go to bower.io, use Visual Studio IntelliSense (covered later), or search the Bower package repository via the command line:

bower search jquery

You can also install several packages at once, which is great when you want to script your installs:

bower install jquery bootstrap-css angular
#or install a specific version of jquery ui
bower install jquery-ui#1.10.4
#install a github repository as a package
bower install https://github.com/SomeRepository/project.git

Bower creates a local cache of the packages you install. On my Windows 8 and Windows 10 systems, the default cache folder is C:\Users\<MyName>\AppData\Local\bower\cache\packages (you can override this default in your .bowerrc file). As you can see in Figure 3, you can manage cached packages via the list and clean commands. Note that Bower will pull from the local cache if it can any time you run bower install.

Figure 3 Using the Local Bower Cache

#install jquery package for the first time
bower install jquery
#uninstall jquery package
bower uninstall jquery
#install from cache (ie works disconnected)
bower install jquery --offline
#show me the cache
bower cache list
#clean local cache
bower cache clean
#will fail, package no longer cached
bower install jquery --offline

For packages that depend on other packages, Bower attempts to install the required dependencies on your file system. Bower has a flat dependency tree, meaning any required dependencies are installed right under /bower_components, not under the package that requires it. For example, the bower.json file for jQuery UI lists a dependency of “jquery”: “>=1.6,” meaning if jQuery isn’t installed yet, the latest version of the jQuery package will be installed to /bower_components, as long as it’s at least version 1.6.

Updating or uninstalling packages is pretty straightforward and includes version and dependency checks:

#will update based on version rules in bower.json, ex. "jquery": "~2.1.3"
#specifies any patch like 2.1.4 is acceptable to update, but 2.2.0 is not
bower update jquery
#will remove folder and reference in bower.json, but will prompt first
#if other packages have a dependency on jquery
bower uninstall jquery

The bower.json File

At this point if I deleted the /bower_components folder, I’d have no idea what packages were installed or required by my application. If I gave the source code (with no packages) to another developer or brought it to another environment, such as a build server without the bower_components folder, that developer and I would be out of luck. If you’re familiar with NuGet, this is similar to missing the packages.config file. Ideally, you want a bower.json file in your application so Bower can track your package dependencies and versions, but it’s optional.

To create the bower.json file, run the bower init command in your project root and follow the prompts as shown in Figure 4.

Figure 4 Creating a bower.json File

C:\Users\Adam\Documents\WebApp> bower init
? name: MyWebApp
? version: 1.0.0
? description:
? main file:
? what types of modules does this package expose?
? keywords:
? authors: Adam Tuliper <adam.tuliper@gmail.com>
? license: MIT
? homepage:
? set currently installed components as dependencies? (Y/n) Y
? 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? (y/N)

If you forget to create a bower.json file and install a bunch of packages without it or forget to add those packages using the –save option, don’t worry. When you run the bower init command, it asks “set currently installed components as dependencies?” Answering affirmatively means Bower will look at the packages in /bower_components and add what it determines to be the root packages into the dependencies section. Note, however, that if jQuery UI depends on jQuery, jQuery isn’t added as a dependency in your file using this method as it’s installed when you install jQuery UI. It’s always a good idea to review this generated dependencies section to ensure you agree with what dependencies should be listed.

Now you can initialize Bower for your project at the command line, typically in the root folder of your Web project. Then you install your dependencies. A sample bower.json file is shown in Figure 5.

Figure 5 A Sample bower.json File

{
  "name": "MyWebApp",
  "version": "0.0.0",
  "authors": [
    "Adam Tuliper <adam.tuliper@anonymous>"
  ],
  "license": "MIT",
  "ignore": [
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ],
  "dependencies": {
    "angular": "~1.4.3",
    "bootstrap-css": "~3.3.4",
    "jquery-ui": "~1.11.4"
  },
   "devDependencies": {
    "angular-mocks": "~1.4.3"
  }
}
}

The top section contains overall project and package information. Other sections worth mentioning are ignore, dependencies and devDependencies. The ignore section excludes the indicated files if you happen to be creating a Bower package from this app. Because I’m working with a Web app and not creating my own Bower package, this doesn’t apply. The dependencies and devDependencies sections contain all of the packages I’ve installed that will be used by my application; they’re covered in the next section in more detail.

Managing Dependencies

You’ve seen that you can specify two different types of dependencies in a bower.json file: dependencies and devDependencies. Items in the dependencies section are added when you call, for example, bower install jquery --save. These are packages (such as jQuery) that will run in production for your app. The devDependencies entries, on the other hand, are packages that typically won’t make it to production, such as mock frameworks like angular-mocks or less/sass compilers. These entries are added when you use, for example, the bower install angular-mocks --save-dev option. These two dependency types are only noted in your bower.json file and don’t affect how you use these files on the file system in your application. If you’re performing a restore of the packages in, for example, a QA environment, theoretically you wouldn’t need to install the devDependencies.

To install all dependencies only in the dependencies section and ignore anything in devDependencies, such as when creating a production build, simply use bower install –production.

If you want to see all of the dependencies your application uses, you can run bower list, which produces output like the following:

bower check-new     Checking for new versions of the project dependencies..
MyWebApp#0.0.0 C:\Users\Adam\Documents\MyWebApp
├── angular#1.4.3 (1.4.4-build.4147+sha.bb281f8 available)
├─┬ angular-mocks#1.4.3 (1.4.4-build.4147+sha.bb281f8 available)
│ └── angular#1.4.3 (latest is 1.4.4-build.4147+sha.bb281f8)
├── bootstrap-css#3.3.4
├─┬ jquery-ui#1.11.4
│ └── jquery#2.1.4 (3.0.0-alpha1+compat available)
└── jquery1#2.1.4 (3.0.0-alpha1+compat available)

Too Many Files

Newcomers to Bower quickly realize some packages contain many files while they might need only one file. Some Bower packages list one or more files in the main configuration section that are required for using the package. For example, jQuery has around 90 files in the package when you install it. But to use jQuery, you only need jQuery.js, so the solution is to look at main and note that for jQuery it lists just a single file in the /dist folder:

{
  "name": "jquery",
  "version": "2.1.4",
  "main": "dist/jquery.js",
...
}

If you look in the /dist folder for jQuery, you’ll also find the jQuery.min.js and its corresponding .map file for debugging, although it wouldn’t make sense to list these in the main element because the intention is either jQuery.js or jQuery.min.js is used in production, not both.

Running bower list --paths returns all of the main files for every installed package, like so:

C:\Users\Adam\Documents\MyWeb> bower list --paths
  angular: 'bower_components/angular/angular.js',
  'bootstrap-css': [
    'bower_components/bootstrap-css/css/bootstrap.min.css',
    'bower_components/bootstrap-css/js/bootstrap.min.js'
  ],
  jquery: 'bower_components/jquery/dist/jquery.js'

The onus is on package creators to ensure they list the proper files in the main section.

Because, by default, all package files are under the /bower_components subfolder, you might think my HTML files would reference the files right off this folder as follows:

<link rel="stylesheet" type="text/css"
  href="/bower_components/bootstrap-css/css/bootstrap.min.css">
<script src="/bower_components/bootstrap-css/js/bootstrap.min.js" />
<script src="/bower_components/angular/angular.js" />
<script src="/bower_components/jquery/dist/jquery.js" />

You can find many examples on the Inter­net that do this and reference files inside the /bower_components folder. This is not a clean practice. I don’t recommend it, and I, for one, don’t want to deploy such a folder and potentially hundreds or thousands of files to production when I need only a handful of files that should be minified and concatenated into even fewer files. I’ll cover the latter techniques in the next article on Grunt and Gulp, but for now, I’ll examine one of several available techniques to pull out these main files in a better way using the bower-­installer module.

The bower-installer module will copy all of the main files into your specified folder structure. First, install this module globally on your machine via npm install -g bower-installer.

Next, add a section to your bower.json file to specify where these main files should be copied:

"install": {
  "path": "lib"
},

Your main files for each package will end up in a subfolder under \lib in this case, for example, lib\jquery­\jQuery.js, lib\angular\angular.js.

You can customize this process quite a bit. Be sure to check out that package’s documentation at bit.ly/1gwKBmZ.

Last, run bower-installer every time you want your files copied to the output folders. Again, there are other ways, such as using Grunt or Gulp to copy these files using a task—you can even watch the folders for changes—but this is a quick, minimal-dependency way of doing it when you start out that doesn’t require other workflows.

Build Servers and Source Control

What about when you want to install your required packages on a build server? This is useful in the scenarios where you know only your code is in source control and all other packages (Bower/NuGet, and so forth) are installed and/or built (Sass, Less, CoffeeScript and the like) on a build server. Some shops will source control everything, including all binaries and third-party dependencies. Others rely on the package manager to restore the packages in a build environment. When I give a Visual Studio project to someone, I generally expect the packages to be restored on their machine. The typical recommendation for Bower as it relates to source control, however, is to source control all third-­party code if you can live with potentially large repositories or if you don’t want to rely on the package manager, otherwise don’t source control /bower_components.

To install all dependencies and copy main files using just a bower.json file, simply run the following commands:

#Will read bower.json and install referenced packages and their dependencies
bower install
#Optional - copy each packages main{} files into your predefined path
bower-installer

Why Not Just npm?

Some developers just use the npm, others choose Bower and some use a mix. You’ll find many packages that are in both the Bower and npm package repositories, which makes your workflow easier in any case. The npm works well not only for Node.js apps, but also for managing both client-side and server-side packages. The npm has a nested dependency tree, meaning that for every package you install, all of its dependencies are installed in that package’s node_components subfolder. For example, if you use three packages and each one uses jQuery, the entire jQuery package is installed three separate times. Nested dependencies can create quite a long dependency chain. Windows users of the npm are almost guaranteed at some point to run across the dreaded path length error because of this, for example: The directory name  C:\Users\Adam\.......\node_modules\somePackageA \node_modules\somePackageB\node_modules\insight\node_modules\inquirer\node_modules\readline2\node_modules\strip-ansi\node_modules\ansi-rege ... is too long.

This is a byproduct of the npm nested dependency structure, though the beta of npm 3 does have a flatten feature. My aim isn’t to convince you of one or another as you can happily use both.

Bower, ASP.NET 5 and Visual Studio

Visual Studio 2015 has built-in support for Bower and npm, including installing packages and IntelliSense. Prior versions of Visual Studio can get this same functionality by downloading and installing the free Package IntelliSense Extension for Visual Studio. Figure 6 shows some of the options that are available to manage your packages inside a bower.json file.

Package Options in Visual Studio
Figure 6 Package Options in Visual Studio

As you can see in Figure 7, when you type a package name IntelliSense gives you matching packages and versions, saving you a command-line or Web lookup. Once you make changes to the bower.json file and save it, the package will be installed locally without having to go to the command line. There’s nothing here that’s Visual Studio-specific from a file standpoint. In other words, a default bower.json from any Web project just works.

Bower IntelliSense in Visual Studio
Figure 7 Bower IntelliSense in Visual Studio

Figure 8 shows dependencies from bower.json in Solution Explorer, indicating how Bower is fully integrated into your Web projects and Visual Studio.

Bower Dependencies in Solution Explorer
Figure 8 Bower Dependencies in Solution Explorer

With ASP.NET 5, there’s a new project structure in which all files in your project folder are included in your project by default, but only items in the /wwwroot folder of your Web project are addressable as static content, such as HTML, CSS, images and JavaScript files. Knowing this, you could set your bower.json config so that bower-installer copies your dependencies to this folder (though the out-of-the-box ASP.NET 5 templates use Gulp to copy pre-set files to their destinations, as I’ll cover in the next article).

NuGet packages are still awesome, used heavily and supported, of course, in ASP.NET 5 projects. As a side note, NuGet settings go in the project.json’s dependencies section, but show up under references in Visual Studio. NuGet packages are used out-of-the-box for server-side packages, such as logging and MVC support.

Wrapping Up

Bower is a great tool that can easily be integrated into your front-end workflow. Its API is simple to use and with integrated support in Visual Studio, you can use it right along with npm and NuGet to manage both front-end and back-end packages. Take an hour or two to learn Bower; you’ll be happy you did.


Adam Tuliper is a senior technical evangelist with Microsoft living in sunny SoCal. He is a Web dev, game dev, Pluralsight author and all-around tech lover. Find him on Twitter @AdamTuliper or adamt@microsoft.com.

Thanks to the following Microsoft technical expert for reviewing this article: Michael Palermo