clubmate.fi

A good[ish] website

Web development blog, loads of UI and JavaScript topics

Bower and Gulp: match made in heaven (also)

Filed under: Tooling— Tagged with: bower, gulp, RequireJS

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

If you’re unsure what’s Bower and how to use it, the first post of the series explains that.

Problem with Bower

You’ve got directory bower_components full of packages downloaded from npm, and there’s a lot of fluff, tests and examples, those serve an important purpose to the development of the project, but has 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 all about, moving packages main files out or bower_components.

Gulp plugin to rescue

main-bower-files plugin does few things:

  1. Checks projects bower.json for dependencies.
  2. Then finds those dependencies from bower_components/, and copies their sources.

That’s all it does, then it’s up to you to make a stream from that source and pipe it to wanted location.

Note worthy thing: The main file is defined in each project’s bower.json file.

Install via trusty NPM:

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

Then define a task:

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:

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

Note: There are other plugins 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:

{
  "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:

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

{
  "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"
  }
}

Comments would go here, but the commenting system isn’t ready yet, sorry. Tweet me @hiljaa if you want to make a correction etc.

  • © 2021 Antti Hiljá
  • About
  • Follow me in Twatter → @hiljaa
  • All rights reserved yadda yadda.
  • I can put just about anything here, no one reads the footer anyways.
  • console.log('Smash the patriarchy!')
  • I love u!