# Bower and Gulp: match made in heaven (also)

This is a sequel to "Bower and Grunt: match made in heaven." With Gulp things
are even better.

If you’re unsure what Bower is or how to use it, the
[first post of the series](/bower-and-grunt-match-made-in-heaven) explains that.

## Problem with Bower

You’ve got a `bower_components` directory full of packages downloaded from npm,
**and there’s a lot of fluff**, tests and examples, those serve an important
purpose during development, but have little value to the end user. Most of those
files don't belong to the end product **and should not be included to the
project repo**. That's what this post is about: moving packages' **main** files
out of `bower_components`.

## Gulp plugin to rescue

[main-bower-files](https://www.npmjs.com/package/main-bower-files) plugin does a
few things:

1. Checks the project's `bower.json` for dependencies.
2. Then finds those dependencies from `bower_components/`, and copies their
   sources.

That’s all it does. It’s up to you to make a stream from that source and pipe it
to the desired location.

**Note:** The main file is defined in each project’s `bower.json` file.

Install via trusty NPM:

```shell
$ npm install --save-dev main-bower-files
```

Then define a task:

```js
var gulp = require('gulp')
var mainBowerFiles = require('main-bower-files')

gulp.task('bower', function () {
  // mainBowerFiles is used as a src for the task,
  // usually you pipe stuff through a task
  return (
    gulp
      .src(mainBowerFiles())
      // Then pipe it to wanted directory, I use
      // dist/lib but it could be anything really
      .pipe(gulp.dest('dist/lib'))
  )
})
```

Now you’d install a package normally, and then run the bower task:

```shell
$ bower install --save some-package
$ gulp bower
```

**Note:** There are [other plugins](https://www.npmjs.com/search?q=gulp-bower)
also.

## What if no main file?

Then an override needs to be defined in `bower.json`. For instance, the
`echo.js` doesn’t have a main file defined, **but it does have a main file**.
Make an override, here’s a sample bower.json:

```json
{
  "name": "some-project",
  "devDependencies": {
    "normalize-scss": "~3.0.2"
  },
  "dependencies": {
    "echojs": "~1.7.0"
  },
  "overrides": {
    "echojs": {
      // Dir in bower-components
      "main": "dist/echo.js" // The location of the main file
    }
  }
}
```

## Automate it fully

You can watch the `bower_components/` and run bower-main-files automatically
when a change occurs. Here's a sample task:

```js
var gulp = require('gulp')

gulp.task('watch', function () {
  // All files in bower_components
  gulp.watch('bower_components/**', ['bower'])
})
```

## Common pitfalls

If nothing happens or only some packages get copied, it might be that the
packages were accidentally installed without the `--save` flag. Hence, are
present in `bower_components` but not listed in the `bower.json` file.
`devDependencies` are also not copied. Just reinstall the packages:
`$ npm install --save some-package`.

Here's an example `bower.json`

```json
{
  "name": "some-project",
  // Not copied
  "devDependencies": {
    "scut": "~1.0.1",
    "normalize-scss": "~3.0.2"
  },
  // Only deps are copied
  "dependencies": {
    "jquery": "~2.1.1",
    "zepto": "~1.1.6",
    "requirejs": "~2.1.16"
  }
}
```
