Best way to add a JavaScript library

I’m trying to figure out the best way to add a JavaScript library to Roots. I see there is a thread already about bxslider, which is what I’m trying to install, but it doesn’t answer my specific question and I don’t want to threadjack: How to correctly add bxslider to my theme

I used bower to install bxslider using bower install --save bxslider and it’s in the assets/vendor directory now. However, I still need to include it in the theme so it can be used. Should I add it to the Grunt.js file or the lib/scripts.php file?

Should I have even used bower to do this or just put it into the plugins directory so it can be compiled automatically with the Grunt.js file the way it’s already set up?

Essentially, what is the intended best practice to install an external JS library that will have CSS and image assets that need to be included as well?

2 Likes

Generally the best way is to use bower and then add it to Gruntfile.js to get compiled into the main scripts.js.

There’s only a few reasons you wouldn’t want to this:

  1. Package isn’t in Bower
  2. You don’t want to include that JS library in your main scripts.js (maybe to avoid loading it on every page). Or you want to conditionally include it.
  3. You need to make modifications to the library. You should always avoid this, but if it’s necessary then I’d just keep it in your regular assets/js dir since it’s now yours basically.
4 Likes

To go a little deeper on this here’s an example.

I want to add jquery UI to my project.

So I run

bower install jquery-ui

Bower adds all the appropriate assets to:

  /assets/vendor/jquery-ui

Good, now I need to get this into my theme. So I modify the Grunt.js file like so:

    'use strict';
module.exports = function(grunt) {
  // Load all tasks
  require('load-grunt-tasks')(grunt);
  // Show elapsed time
  require('time-grunt')(grunt);

  var jsFileList = [
    'assets/vendor/bootstrap/js/transition.js',
    'assets/vendor/bootstrap/js/alert.js',
    'assets/vendor/bootstrap/js/button.js',
    'assets/vendor/bootstrap/js/carousel.js',
    'assets/vendor/bootstrap/js/collapse.js',
    'assets/vendor/bootstrap/js/dropdown.js',
    'assets/vendor/bootstrap/js/modal.js',
    'assets/vendor/bootstrap/js/tooltip.js',
    'assets/vendor/bootstrap/js/popover.js',
    'assets/vendor/bootstrap/js/scrollspy.js',
    'assets/vendor/bootstrap/js/tab.js',
    'assets/vendor/bootstrap/js/affix.js',
    **'assets/vendor/jquery-ui/jquery-ui.js',**
    'assets/js/plugins/*.js',
    'assets/js/_*.js',
  ];

This adds jQuery UI to the jsFileList, which is then concat. uglified, etc below:

concat: {
  options: {
    separator: ';',
  },
  dist: {
    src: [jsFileList],
    dest: 'assets/js/scripts.js',
  },
},
uglify: {
  dist: {
    files: {
      'assets/js/scripts.min.js': [jsFileList]
    }
  }
},

That’s it right?

1 Like

Yep. Anything added to jsFileList will be included as usual.

This is super. Is there a good way to quickly add to Grunt as well? Current workflow is

bower install …
find vendor directory and file
manually add to Gruntfile

Would be cool to get something like https://www.npmjs.org/package/grunt-bower-concat working. Thanks for your thoughts!

The way things are setup on the current release will make that a bit of a chore and the Grunt workflow won’t be around much longer. You can use the gulp branch which implements this feature. Just bower install --save and gulp does the rest!

If you did want to add this functionality to Grunt though, I recommend checking out main-bower-files which is what the gulp branch uses (good place to see it in action too). It should work with Grunt despite no Grunt examples in the docs. Basically it:

This will read your bower.json, iterate through your dependencies and returns an array of files defined in the main property of the packages bower.json. You can override the behavior if you add an overrides property to your own bower.json.

So the OP wanted to install bxslider. Its bower.json has a main property that declares some non-Javascript files; you would need to override these if you plan to use main-bower files.