# Bower and Grunt: match made in heaven

Bower is great, but it only does one thing: manage packages. We’ll need a bit of
help from Grunt to reach perfection. Here’s how to install and use Bower, and
how to automate the copying of files from bower_components to lib.

> **Note:** I have a follow up article on how to do all this with Gulp:
> [Bower and Gulp: match made in heaven (also)](/bower-and-gulp-match-made-in-heaven-also)

[Bower](http://bower.io/), "a package manager for the web", a tool that makes
installing packages a breeze (such as Zepto, Scut, or any desired library or
plugin). This means you can download packages from the comfort of your command
line. The days of '_right-click on a link, choose Save As_' are over. Bower can
also update packages with the `bower update` command.

## Install Bower

Start by installing Bower globally ([Node/npm is needed](http://nodejs.org/)):

```shell
$ npm install -g bower
```

`cd` into your project and run:

```shell
$ bower init
```

The `init` is not mandatory if Bower is only used to pull in packages, it just
creates a `bower.json` file that we need later.

It'll prompt you with various questions, most of which are self-explanatory.
Skip any of them with enter. See the comments below for explanations.

```
[?] name: (test)                   # This defaults to the directory name
[?] version: (0.0.0)               # In which version is your project
[?] description:                   # Short description of your project
[?] main file:                     # The main file of your project, in jQuery that would be the `jquery.js`
[?] what types of modules does this package expose? (Press <space> to select)
❯⬡ amd                             # More: http://requirejs.org/docs/whyamd.html
    ⬡ es6                             # More: http://wiki.ecmascript.org/doku.php?id=harmony%3amodules
    ⬡ globals                         #
    ⬡ node                            # More: http://nodejs.org/api/modules.html
    ⬡ yui                             # Or just press enter to skip this
[?] keywords:                      # Like tags, if you publish your project
[?] authors: (bob <bob@exmpl.com>) # I suppose Bower pulls these from you Git configuration
[?] license: (MIT)                 # MIT is the default and sufficient in most cases
[?] homepage:                      # Project home
[?] set currently installed components as dependencies? (Y/n) # You most likely want to say Y to this
[?] add commonly ignored files to ignore list? (Y/n)          # Solid Y also
[?] would you like to mark this package as private which prevents it from being accidentally published to the registry? (y/N)
```

The `bower.json` file is created in the project root. Check it out. It can be
edited in normal fashion if needed.

## `bower.json` file

This is the heart of your Bower project. It contains information about the
project (name, homepage etc.), along with list of dependencies.

It's needed only when:

- Publishing packages
- Using the `grunt-bower-task` (more on that later)

Example Bower manifest file could look something like this:

```json
{
  "name": "Test Project",
  "version": "2.0",
  "homepage": "https://github.com/bob/test-project",
  "authors": ["bob <bob@example.com>"],
  "description": "This is a test project",
  "license": "MIT",
  "ignore": ["**/.*", "node_modules", "bower_components", "test", "tests"],
  "dependencies": {
    "jquery": "~2.1.0",
    "scut": "~0.10.2",
    "unveil": "~1.3.0",
    "zeptojs": "~1.1.3",
    "yepnope": "~1.5.4"
  }
}
```

The only really interesting bit is the dependencies: the packages a project
needs to function.

## Installing packages with Bower

The syntax for installing is:

```shell
$ bower install <endpoint> [<endpoint> ..] [<options>]
```

If jQuery is desired, it can be first searched:

```shell
$ bower search jquery
```

Choose suitable jQuery package and issue:

```shell
$ bower install jquery --save
```

The `--save` flag saves it as a dependency in the project. Here are all the
options it takes.

- `-F`, `--force-latest`: Force latest version on conflict
- `-p`, `--production`: Do not install project devDependencies
- `-S`, `--save`: Save installed packages into the project’s bower.json
  dependencies
- `-D`, `--save-dev`: Save installed packages into the project’s bower.json
  devDependencies

Now, a `bower_components` directory is created in the project root, and jQuery
is pulled in from its Git repo.

```
bower_components/
 └── jquery
```

By the way, a `bower.json` file is not needed to install packages.

### Install all the project dependencies

It's easy to pull in packages with Bower, but its real strength lies in its
ability to pull in all the needed dependencies for a given project. Say, clone a
project from GitHub, none of the dependencies are included into it, they're in
their respective repositories. Just run:

```shell
$ bower install
```

And Bower will look into the `bower.json` file and pull in all the listed
dependencies.

## Using the packages

Bower is only a package manager, not a module loader. Reference packages in
normal fashion:

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

This is where the trouble starts.

### The package dilemma

**"Bower package" equals exactly to: "its git repository"**

Which is how it should be, but, we have problem now. For example, jQuery that
was pulled in, created a directory tree like this:

```
jquery/
    ├── MIT-LICENSE.txt
    ├── bower.json
    ├── dist
    │   ├── jquery.js
    │   ├── jquery.min.js
    │   └── jquery.min.map
    └── src
        ├── ajax
        │   ├── jsonp.js
        │   ├── load.js
        │   ├── parseJSON.js
        │   ├── parseXML.js
        │   ├── script.js
        │   ├── var
        │   │   ├── nonce.js
        │   │   └── rquery.js
        │   └── xhr.js
        ├── ajax.js
        ├── attributes
        │   ├── attr.js
        │   ├── classes.js
        │   ├── prop.js
        │   ├── support.js
        │   └── val.js
        ├── attributes.js
        ├── callbacks.js
        ├── core
        │   ├── access.js
        │   ├── init.js
        │   ├── parseHTML.js
        │   ├── ready.js
        │   └── var
        │       └── rsingleTag.js
        ├── core.js
        ├── css
        │   ├── addGetHookIf.js
        │   ├── curCSS.js
        │   ├── defaultDisplay.js
        │   ├── hiddenVisibleSelectors.js
        │   ├── support.js
        │   ├── swap.js
        │   └── var
        │       ├── cssExpand.js
        │       ├── getStyles.js
        │       ├── isHidden.js
        │       ├── rmargin.js
        │       └── rnumnonpx.js
        ├── css.js
        ├── data
        │   ├── Data.js
        │   ├── accepts.js
        │   └── var
        │       ├── data_priv.js
        │       └── data_user.js
        ├── data.js
        ├── deferred.js
        ├── deprecated.js
        ├── dimensions.js
        ├── effects
        │   ├── Tween.js
        │   └── animatedSelector.js
        ├── effects.js
        ├── event
        │   ├── alias.js
        │   └── support.js
        ├── event.js
        ├── exports
        │   ├── amd.js
        │   └── global.js
        ├── intro.js
        ├── jquery.js
        ├── manipulation
        │   ├── _evalUrl.js
        │   ├── support.js
        │   └── var
        │       └── rcheckableType.js
        ├── manipulation.js
        ├── offset.js
        ├── outro.js
        ├── queue
        │   └── delay.js
        ├── queue.js
        ├── selector-native.js
        ├── selector-sizzle.js
        ├── selector.js
        ├── serialize.js
        ├── sizzle
        │   └── dist
        │       ├── sizzle.js
        │       ├── sizzle.min.js
        │       └── sizzle.min.map
        ├── traversing
        │   ├── findFilter.js
        │   └── var
        │       └── rneedsContext.js
        ├── traversing.js
        ├── var
        │   ├── arr.js
        │   ├── class2type.js
        │   ├── concat.js
        │   ├── hasOwn.js
        │   ├── indexOf.js
        │   ├── pnum.js
        │   ├── push.js
        │   ├── rnotwhite.js
        │   ├── slice.js
        │   ├── strundefined.js
        │   ├── support.js
        │   └── toString.js
        └── wrap.js
```

Sure I don’t need all of that?

Bower does one thing, and it does it well. It's not trying to be anything else
than a tool that pulls in packages.

From jQuery repo, only one file is really needed:

```
jquery/
    └── dist
        └── jquery.js
```

## grunt-bower-task to rescue

What it does:

- `grunt-bower-task` copies the **main** file to `/lib`
  - **Main** file is the file that is specified in `bower.json`:
    `"main": "dist/jquery.js",`
- `bower_components` dir can be now excluded in `.gitignore`
- Link to files in `lib` instead
  - `<script src="lib/jquery/jquery.js"></script>`

### `grunt-bower-task` usage

Configuring is easy:

```js
grunt.initConfig({
  bower: {
    install: {
      //just run $ grunt bower:install and you'll see files from your Bower packages in lib directory
    },
  },
})
```

See more usage and installation instruction
[here](https://github.com/yatskevich/grunt-bower-task).

After setting it up, try it out:

```shell
$ grunt bower
```

Now the task copies the `main` files from each package to `/lib`. The dir
structure could looks something like this:

```
lib
├── jquery
├── zepto
└── yepnope
```

When `grunt-bower-task` is set up, install Bower packages like so:

```shell
$ bower install jquery && grunt bower
```

And off you go, happy pappy.

### What if no `main` file

If there is no **main** file, here's what `grunt-bower-task` does:

> - If `"main"` files are empty then the whole package directory will be copied
>   to `./lib`.
> - When you define `"exportsOverride"` only asset types and files specified by
>   you will be copied to `./lib`.

This happens. For example with Zepto, cause it assumes that every user builds
their own version of it, therefore no main file exists, and the whole tree is
copied. Bummer. But as alway, there's a way.

### Copying specified files only

After Zepto is custom built,
([heres how to do that](http://clubmate.dev/how-to-build-a-custom-zepto/)), only
`zeptojs/dist/zepto.js` is desired. Pop open the `bower.json` from the project
root and define `exportsOverride` there, like this:

```json
{
  "name": "Test Project",
  "version": "2.0",
  "homepage": "https://github.com/bob/test-project",
  "authors": ["bob <bob@example.com>"],
  "dependencies": {
    "jquery": "~2.1.0",
    "scut": "~0.10.2",
    "unveil": "~1.3.0",
    "zeptojs": "~1.1.3",
    "yepnope": "~1.5.4"
  },
  "exportsOverride": {
    "zeptojs": {
      "js": "dist/zepto.js"
    },
    "yepnope": {
      "js": "yepnope.js"
    }
  }
}
```

It breaks down to:

- `"zeptojs"` the package dir in `bower_components`
- `"js"` target dir in `./lib`
- `"dist/zepto.js"` is path to the wanted file in `bower_components`

Now if `$ grunt bower` is issued, it'll create the following directory
structure:

```
lib
    ├── jquery
    │   └── jquery.js
    ├── js
    │   ├── yepnope
    │   │   └── yepnope.js
    │   └── zeptojs
    │       └── zepto.js
    ├── scut
    │   └── _scut.scss
    └── unveil
        └── jquery.unveil.js
```

Nice! We got that problem solved.

Or [grunt-contrib-copy](https://github.com/gruntjs/grunt-contrib-copy) would
also do the job, it's a task that copies specified files.

## Other useful Bower commands

Uninstall:

```shell
$ bower uninstall <packagename>
```

[Publish](https://github.com/bower/bower#registering-packages) packages:

> To register a new package:
>
> - There **must** be a valid manifest JSON in the current working directory.
> - Your package should use
>   [semver](https://github.com/bower/bower#registering-packages) Git tags.
> - Your package **must** be available at a Git endpoint (e.g., GitHub);
>   remember to push your Git tags!
> - Then use the following command:
>   `$ bower register <my-package-name> <git-endpoint>`

## Conclusion

Bower is pretty amazing, and couple in with grunt it reaches new heights.
