The following is a guest post by Dan Sundy from Helios Design Labs. Dan is both going to explain how to use Bower and make a case for doing so, from the perspective of someone who resisted the idea at first.
When I first started working with Bower I didn’t quite get the appeal. “Seriously?” I thought. “Now it’s too much work to download and unzip a file?” I also wasn’t super excited about cramming a bunch of new commands into a brain that was already bulging at the seams with Git, Grunt, Gulp, Jekyll, Node, etc.
There are two things I would tell that half-a-year ago version of myself. First, Bower can do a little bit more than download a file or two. Second, spending an hour learning a tool that will eliminate a repetitive task is worth it.
First Things First: What the Heck is Bower?
For the uninitiated, Bower is a package manager. It’s good at, well, managing packages—anything that you depend on an external author for. Good examples are CSS frameworks like Bootstrap, libraries like jQuery, jQuery plugins, or JavaScript frameworks like Angular. The official Bower website, Bower.io, probably says it best:
Web sites are made of lots of things — frameworks, libraries, assets, utilities, and rainbows. Bower manages all these things for you.
Bower works by fetching and installing packages from all over, taking care of hunting, finding, downloading, and saving the stuff you’re looking for.
Prerequisites
There are some things you’ll need before you can start working with Bower:
- The command line. Yup, it’s a command line tool (c’mon it’s not that scary).
- Node and NPM. Bower is a Node module so to get it you need NPM.
- Git. Bower packages are Git repos. Bower uses Git to understand where the package is, what version it’s on—that sort of thing.
- Global Installation. Technically you could install it in every project but you’ll probably want to have it everywhere.
To install Bower globally:
$ npm install -g bower
Note: Depending on your setup you may have to use `sudo npm install -g bower` to install it globally.
The Basics
To start, picture the directory structure for a new site. Mine usually look something like this:
|-.git/
|-dist/
|-node_modules/
|-src/
| |-assets/
| |-css/
| |-fonts/
| |-js/
| | |-lib/
| | |-main.js
| |
| |-sass/
| | |-style.sass
| |
| |-index.html
|
|-.gitignore
|-gulpfile.js
|-package.json
|-README.md
There’s a `src` folder where the bulk of the development work is done. A Gulp build task will eventually prep everything and compile our optimized code into a production-ready `dist` folder.
Let’s say you want to include jQuery in this project. Usually you would go to jquery.com, find and click on the correct download link, then unzip and put the files in the right directory.
With Bower, just run the following command:
$ bower install jquery
Now a `bower_components` directory with a `jquery` folder has appeared.
|-.git/
|-bower_components/
| |-jquery/
|
|-dist/
|-node_modules/
|-src/
| |-assets/
| |-css/
| |-fonts/
| |-js/
| | |-lib/
| | |-main.js
| |
| |-sass/
| | |-style.sass
| |
| |-index.html
|
|-.gitignore
|-gulpfile.js
|-package.json
|-README.md
jQuery has made it easy to get their code by creating and registering a package for Bower. Most popular libraries and frameworks have done the same. If you want to check that the asset you want is a Bower package you can do a search:
$ bower search <package-name>
If it isn’t registered, it is still possible to grab repos with git endpoints like this:
$ bower install git://github.com/example-user/example-package.git
Advanced: If you want to get fancy, you can even install private repos that you have access to. Check out this video tutorial by Rob Dodson.
Here are some other basic commands you can use to view and manage assets that you have installed.
List all your packages:
$ bower list
Get information about any package that you have installed:
$ bower info <package-name>
Check for updates with:
$ bower check-new
Then, if there are updates, update a package:
$ bower update <package-name>
But maybe updating to the latest version broke something.
Install any specific version—old or new—with:
$ bower install <package-name>#<version>
This is definitely not an exhaustive list. If you’re interested in getting started I recommend you make a test project and work through one of the many tutorials that can be found online. This one by Treehouse is great: Getting Started with Bower. Then you can dig into all the commands by checking out Bower’s API.
Hey, But Wait, There’s More!
The small dev team I work with has been using Bower for the past year or so. While package management via the command line was great, I wasn’t sold until we started using the `bower.json` and `.bowerrc` files.
.bowerrc
The `.bowerrc` file can do a number of things, but I’ve mostly seen it used to change the name and location of the `bower_components` directory. (This made me happy because I hated having that random `bower_components` folder floating around in the project root).
Here’s what a `.bowerrc` file can look like:
{
"directory": "src/components"
}
The directory option sends packages to a location that makes the most sense—in this case, the `src/` directory. Have a look at the new project structure:
|-.git/
|-dist/
|-node_modules/
|-src/
| |-assets/
| |-components/
| | |-jquery/
| |
| |-css/
| |-fonts/
| |-js/
| | |-lib/
| | |-main.js
| |
| |-sass/
| | |-style.sass
| |
| |-index.html
|
|-.gitignore
|-.bowerrc
|-gulpfile.js
|-package.json
|-README.md
Notice that the `bower_components/` folder is gone and there is a `components/` folder in the `src/` directory.
Advanced: It’s a good idea to use something like gulp-usemin or grunt-usemin to take care of concatenation and minification for all of the extra styles and scripts.
So how can the `bower.json` file help us out?
bower.json
The `bower.json` file looks a lot like Node’s `package.json`. It is a manifest file that allows you to specify options. Let’s have a look at an example (which can be generated by running bower init
):
{
"name": "bower-example",
"version": "0.0.0",
"authors": [
"author <[email protected]>"
],
"description": "An example project using bower.",
"main": "index.html",
"license": "MIT",
"private": true,
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"devDependencies": {
"jquery": "~2.1.1"
}
}
A lot of these options are there in case you are registering this repo as a Bower package. But see the devDependencies
object at the very bottom? That object will be updated automatically if you append --save-dev
to a Bower command, like this:
$ bower install jquery --save-dev
Now if fellow coder runs `bower install`, the computer will install everything from the devDependencies
list in the folder specified in `.bowerrc`. Similarly, if one developer adds a package or updates a package version using --save-dev
, the whole team can sync up their assets using bower install
(after pulling down the latest version of the `bower.json` file).
Since all the hunting and gathering work has been eliminated with the `bower.json` file, there is no longer a need to version any of those assets. The `components/` folder can be added to the `.gitignore` file to keep your repository lean and mean.
*.DS_Store
.sass-cache
node_modules/
dist/
src/components/
Parting Shot
I was listening to an episode of my favorite web dev podcast (wink, wink) and the hosts were chatting about whether Bower was actually useful, or just a passing fad. They were wondering if its point is to make downloading easier or whether it is used for updating versions of your libraries, like ruby gems do. They talked about it being a “front-endy NPM” (I’m paraphrasing).
The beauty is, it does all of those things. You can use it for downloading and keeping code updated, but you can take it further. Bower can help you keep project libraries and frameworks in sync, or integrate it with other tools like Yeoman to trim even more time off your dev setup. Plus, you can create and register Bower packages of your own so that you can install and update them in all your projects quickly (and safely).
Oh, and regarding the question that got the discussion started: You wouldn’t use Bower to install WordPress, and WordPress shouldn’t be in your `bower_components` folder. But you could use Bower within your WordPress theme to manage external assets (just don’t load libraries like jQuery that are already included in the WordPress core).
I know there’s a bunch of you Sublime Text lovers out there (me included). My friend Ben Schwarz made a Sublime Text package for Bower, so you search for a bower package and install it right from Sublime, like you would a Sublime package itself through Package Control.
Having used Bower in one or two projects, now more than often I link my
script
tags to CDN-hosted libraries — Google’s for CDN, BootstrapCDN for Bootstrap, and CDNJS for almost everything else. How is this approach versus Bower?I think the original appeal to CDNs came from three things mostly: 1. Ease of bringing in third party resources. 2. The user is likely to have [that version of jquery of whatever] cached since they probably visited another site that used the same CDN. 3. Distributed CDN’s for fast downloads.
There are a few reasons why CDN’s aren’t so great though; namely stories of ISPs occasionally blocking popular CDN IPs on accident, wanting to work offline, etc. The benefit of #2 above is often negated by the fact that jQuery can be found on so many different CDNs with it’s so many versions that it reduces the likelihood of benefiting from the cache. Also with so many third party tools now in CSS/JS. It’s likely that that your project’s combination of tools will require a few HTTP requests which cancels out the benefits too in my opinion.
Bower is awesome because [for those who like command-line] it’s just as easy as bringing in a CDN, I can work offline, I don’t have to worry about ISPs. My favorite reason: Since the files are local, I can concatenate and minify JS into one file – just in case that’s not clear, my jQuery, Handlebars, Backbone, Underscore, and my App specific JS are all in one file so it’s never more than 1 HTTP request. It’s obviously cached on the user’s computer after. Gulp/Grunt allows that process to be trivial once it’s setup. And last, I can take that file and host it on my own distributed CDN for speed.
The primary appeal of storing all your assets locally vs using a CDN is that you can concatenate and pre/postprocess them. Concatenation results in fewer HTTP requests, which is generally a good thing, performance-wise. As for pre/postprocessing, if you don’t need the entirety of a framework like Bootstrap, you can grab the Less source for it, comment out the partials you don’t need, and compile it on your end, resulting in a smaller codebase. Additionally you can use things like Autoprefixer ensuring you only prefix the properties that need to be prefixed for the browsers you’re supporting.
Of course, CDNs are generally more fault tolerant and stable, and you’ll also get your assets served quicker across the globe, but there’s nothing stopping you from using a CDN yourself on your own assets if you’re serious about your site’s performance.
Brad & Alex, while I’m totally aware of the fact that jQuery is hosted on more than one CDN’s, I’d argue someone would use anything other than Google’s. Heck, where was the last time we see a Microsoft-hosted jQuery again?
Now I’m not really a fan of concatenating all scripts into one big file. While it saves several HTTP requests, users have to download the libraries (jQuery, Backbone, Handlebars and whatnot) over and over again from site to site. IMHO that’s not really good for the internet’s health. Biggest guys out there are not providing free CDN’s without a good reason.
Also, it’s not only about the number of HTTP requests. It’s the speed (Brad’s #3) as well. Since a CDN serves files from the server nearest to a user, and their servers tend to have better connection than ours, I’d say CDN wins hands down in a speed test. Not to mention about bandwidth, and I’ve seen for myself how saving several KB’s each page load helps the bill.
That said, there are certain cases when using a CDN is not a wise move. For example, some ISP’s in China block(ed) CDNJS. I learned this the hard way.
@Alex jsDelivr OSS CDN can concatenate JS & CSS. I think you’re right about Bootstrap & the like; better to build site-specific CSS.
@Phan: I agree that not concatenating larger & popular libs (like jQuery, D3) is a good idea, I think it is wise to concatenate smaller libs with their dependencies to be wise. In addition to one fewer HTTP request, remember that a GZip for a single file can be slightly smaller than several separate files added together.
It seems to me the “Case for Bower” then comes down to:
And then the case against those points come down to:
bower install
every time you pulled to be sure you’re good.I’m not totallllly convinced yet, for me personally and my projects, but I do have a greater understanding and definitely can imagine teams/workflows where Bower is beloved. Thanks Dan!
At the end of the day, workflow all comes down to personal preference. Some people like PCs some people like Macs; some people like Sublime Text, others Coda; some sit and some stand.
I think the bottom line is: use the tools that feel comfortable (those are the ones that will make projects faster anyway).
But it would be cool if there is something that notified you of changes to the
bower.json
file ongit pull
and prompted you tobower install
(without having to read the file change output). Hmmm… anyone?Thank you, Chris!
My biggest issue is that Bower downloads whole repo and some libraries put their code in root, some in src, some have compressed/uncompressed folders etc. So before I’m able to run minfy task I have to configure it with individual paths for every script I intend to use (I do it again if I add new dependencies later on).
But it’s definetly useful for projects with multiple vendor scripts and just feels natural to use it if going with whole npm/grunt/gulp/yeoman/automate-all-things setup.
Dan,
Just do
every time. It shouldn’t take long :)
The author seems to have made an error in using
devDependencies
instead ofdependencies
(and--save-dev
instead of--save
). The first is for unit tests and other build tools, whereas the latter is for dependencies used in production (which should be used in this article). Read more on the difference in this StackOverflow!Thanks for pointing that out, wooorm. You’re right, things like jQuery and Bootstrap should go in dependencies which assumes they are needed for dev as well.
Sure thing :)
I work with a small team, some of which are more “back-endy” than frontend. The command line is a scary place for some, so to simplify things a bit I’ve added a scripts section to our
package.json
file that will update ruby sass, node_modules and our bower components.Their workflow is now pretty simple:
npm run update
I use CodeKit for Bower. I guess it’s not as powerful as with the the command line but for me it’s totally sufficient. At the moment I have so much to learn that I don’t have time for new command line instructions.
And CodeKit works as a task manager, too and it’s very easy to use. So I am all happy with it.
I’m a Bower fan and have ran into some issues when working with a team.. mainly the ‘out of sync’ issue.
Scenario: (/bower_components is not checked into repo,.. but bower.json is)
Developer A adds mustache.js via Bower
In build process Developer A’s mustache.js file is minified and concatenated into main scripts file.
Developer A pushes changes to repo
Developer B pulls and gets latest files and upon build process grunt/gulp freaks out about missing dependency. (the /bower_components/mustache.js in #1)
Developer B must stop the press and manually run bower install, then build.
Like /node_modules I like to keep those puppies out of the repo and so team communication is the workaround here: “Hey Developer B,.. I just added mustache.js via Bower,.. be sure to run bower install” (feels soo analog but works)
Git Hook Workaround
Another option is to run a Git Hook after you pull. I’ve had luck with this awesome post-merge git hook written by Sindre Sorhus, from the command line.
You take that post-merge file and stick it into
.git/hooks
and then after you pull it runsbower install
ornpm install
automatically if it needs to. Really cool!Git Tower Users
I personally use Git Tower for my .git action and have not found a solid workaround for this. The hook mentioned above does not trigger after pulling/merging. I was even lucky to work directly with the Git Tower team to try and come up with a working hook and didn’t have any luck. (Massive props to Git Tower for taking the time to help!!)
It boiled down to the need of setting up the shell environment correctly in the hook and my bash scripting skills = 0. Git Tower Hooks
Another Issue – Modified Bower Component Files
Another tiny issue I’ve ran into is when files need to be modified inside the /bower_components folder. For example.. Sass Bootstrap (which is rad and allows you to prune the entire framework down to only what you need per component in a handy import .scss file) could get modified and because /bower_components is not in repo other team members are not in sync.
For these situations when you think the component is going to be modified I like get them out of /bower_components and into the project folder.
More times then not the files in /bower_components do not get modified so it’s generally not a problem.
NPM vs. Bower
Some would argue you can do everything Bower in NPM but I kind of enjoy keeping my ‘front-endy’ type stuff in bower and my ‘node-ish’ stuff in NPM.
your “Modified Bower Component Files” problem is also a problem for. In my case I can live with bootstrap’s default files and add everything to project but my problem is I use Sass and I include everything in main.css and many bower components comes with .css files only, which AFAIK can’t be included as it is in main.css.
Well I don’t wanna be hater, but you could done all of that with command line. I use powershell(or bash), to write templates for sites, npm and git. Just don’t see the point of bower, or I’m mistaken?
I started using Bower about a year ago, primarily because many open-source projects I was interested in did. Like everything else, there was a learning curve.
Frustrating as it was, what I like about Bower (and Yeoman, Grunt, NPM) is that it is very well documented and there is timely content (generally blog posts) that explains almost everything in plain English.
Fuzzy dependency matching is awfully groovy too.
Being able to specify
common-library.js ~3.2
(yes, this is really a trait ofNPM
) and have Bower install a version that works without being overly specific is great.Updating/upgrading caused me lots of headaches at first (“if it ain’t broke don’t update it”), but the ease of installing different tools/libraries combined with its widespread adoption and support convinced me.
I’m not super comfortable with the command line and I don’t generally try to ‘debug’ things so having a robust community using, writing about and supporting Bower made all the difference in the world to me.
If you use Bower, you may want to use “wiredep” as well: a useful feature is that it can aggregate files from bower modules, so you could have a gulp task that concats all js files into a dependencies bundle (or all css, etc).
And if a Bower module doesn’t point to the right files in its “main” property,
you can override it per-module in bower.json.
Example: https://medium.com/@mattdesl/gulp-and-browserify-shim-f1c587cb56b9#038f
Cecile, love your Icon… awesome
I’ll echo one of the other commenters here and say that I really dislike all the files Bower grabs. As a test, I used Bower to get jQuery. It downloaded 111 items/1.1 megs. I then fetched jQuery Mobile. It was 3.3 megs and 380 items. I know jQM and I can’t even figure out how to actually point to the assets so I can use it in my project. I assume this is something I could figure out, but I do not understand why all of these additional assets are grabbed. Maybe if I was planning on building JQM by hand, but I’d argue thats a rare use case (most folks use library X, only a few actually work on library X).
At least for me, Bower actually adds time to my development if I have to hunt out where in the heck the actual library files are versus just grabbing a slimmer zip file.
As an example, and disclaimer, I wrote this (grin), I wrote an extension for Brackets that fetches libraries and only grabs the minimum you need to actually use the library: https://github.com/cfjedimaster/brackets-jsdownloader
There is a ‘files’ area in package.json. Maybe that could be useful?
https://docs.npmjs.com/files/package.json#files
I use bower in collaboration with Gulp. I run bower install to get the bower packages I need and then I have a task which will move the actual files – perhaps just the .js files or the .scss files – out of bower_components/ to where I actually need them.
Now I’ve written that task once, I don’t have to do it again other than to update the task with any additional packages I need.
I’ve used Bower for a few personal projects (admittedly, it’s been awhile), and I’m not yet convinced. Unless I’m missing something, Bower just downloads git repositories. It doesn’t eliminate the actual pain point in using third-party frontend libraries, which is digging through those repositories and finding the one or two files you care about.
Compare this with npm+Browserify. With npm, it doesn’t matter what the structure of the third-party project is. You just
npm install
andrequire()
, and you’re good to go. Plus, Browserify encourages you to keep your code organized with CommonJS modules, which eliminates the need for IIFEs.Now that npm is gonna try to be more front-end package-friendly, the case for bower might look slightly different.
I’d say for me the case for using npm for front-end packages would be for using them with browserify (for JS assets) – similar to what Michael said above.
It’d be interesting to have an in-depth follow up on this article explaining the difference between bower and npm when it comes to front-end packages. I think the biggest difference comes down to the flatter structure of bower.
I’ve used Bower very little. The problem with my work flow is that I sometimes would end up wanting/needing to alter files within a bower component, due to personal preference or necessity. Sometimes you need to customize different components so that they play nicely together for your project. If a component is altered, then I can’t automatically update it at a later time with Bower. Plus, when starting a new site project, I’m more likely to re-use an altered component again, instead of installing the unaltered latest version. That could depend on the importance of the project. Is it worthy of an update to the latest code base available.
I also agree that some components install too many files. I personally have a “vendors” folder, which I manually install components (zips from github) in their own folder along with other files that I deem beneficial (licenses, documentation, examples). But overall, I usually delete a lot of the included files.
Excellent article. Some people like exploring Grunt (the JS task runner), which plays very nicely with Bower.
Nice writeup but why can’t you just use npm to get the dependancies you need? Why download a second javascript package manager with npm when you already have npm?
There is ongoing work to make NPM more front-end friendly.
http://blog.npmjs.org/post/101775448305/npm-and-front-end-packaging
And lots of people are turning to NPM to mitigate other needs.
http://blog.kewah.com/2014/npm-as-a-front-end-package-manager/
I do love that the Bower and NPM teams are working so closely together (seemingly) on this.
https://github.com/bower/bower/issues/1520
If you wanted to check for bower package updates after every pull, you could use a git hook. Read more about them at http://www.git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
Great intro to Bower. However, I don’t agree with the directory structure you’ve chosen. I wouldn’t place third-party scripts installed through Bower in
src/components
since these scripts technically aren’t part of your application source code. They’re vendor-scripts and I’d much rather see them place at the same place in the hierarchy as thenode_modules
directory. Of course, changing the name frombower_components
to anything else is totally acceptable.Sorry for being that guy.