Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I connect bower components with sails.js?

I'd like to be able to install Javascript dependencies through bower and use them in a sails.js app, but I can't figure out a way to do this with out just copying an pasting files from the bower_components folder to the Sails assets folder.

Ideally I think I'd like to use requirejs and point to the bower components in the main.js file. I may be trying to pound a square peg in a round hole, please let me know if so. Any thoughts on managing components/libraries with Sails are welcome.

like image 337
Cole Reed Avatar asked Aug 09 '13 02:08

Cole Reed


2 Answers

In Sails 0.10 the 'assets/linker' directory no longer exists, however I found a lead on simple solution that gives some automation to the bower -> asset linker workflow while also allowing some granular control over what exactly ends up getting linked.

The solution is adding grunt-bower to your Sails.js compileAssets task

grunt.registerTask('compileAssets', [     'clean:dev',     'bower:dev',     'jst:dev',     'less:dev',     'copy:dev',     'coffee:dev' ]); 

Then configure your grunt-bower task like so (as tasks/config/bower.js):

module.exports = function(grunt) {   grunt.config.set('bower', {     dev: {         dest: '.tmp/public',         js_dest: '.tmp/public/js',         css_dest: '.tmp/public/styles'     }   });    grunt.loadNpmTasks('grunt-bower');  }; 

This will automatically copy your bower js and css files to the proper place for Sail's asset linker to find and automatically add to your project's layout template. Any other js or css files will still automatically be added after your bower files.

However this is still no silver bullet as this setup has 2 big caveats to it:

1 - The files that are added through bower-grunt have to be listed in bower.json's main array. If you see a file isn't being loaded you would expect to be, you must either edit that packages bower.json file OR add the dependency manually through grunt-bower's packageSpecific options.

2 - The order of bower files in the asset linker is currently alphabetical. My only recourse to adjust this order so far is tinkering around with an additional grunt task to manually re-order files prior to the rest of Sail's compileAssets task. However this one I'm confident there is something grunt-bower could do by supporting package copy ordering.

like image 133
user3429154 Avatar answered Sep 21 '22 15:09

user3429154


Note: the following answer is no longer completely relevant to the current version of SailsJS because there is no support for the linker folder as of SailsJS 0.10.

See: Sails not generating linker

Original answer:

I was able to figure out a solution for this, which is actually pretty simple. I had not realized you could configure where bower places it's files.

Create a .bowerrc file and change the directory where bower components are installed, in the case of Sailjs they should be put into the assets folder.

/*  * Create a file called .bowerrc and put the following in it.  * This file should be in the root directory of the sails app.  */   {    "directory": "assets/linker/bower_components"  } 

Sails will then use grunt to copy them to the .tmp/public/assets folder whenever a file is change. If you don't wish to have sails continually deleting and then recopying those files you can exclude them in the grunt file.

/*   * This is not necessary, but if you have a lot of components and don't want  * them constantly being deleted and copied at every file change you can update  * your Gruntfile.js with the below.  */   clean: {    dev: ['.tmp/public/**',          '!.tmp/public',          '!.tmp/public/bower_components/**'],    build: ['www']  }, 

One tip on using requirejs with sails. By default you will get an error from the socket.io file since sails will load it without using requirejs. This will throw an error since socket.io supports amd style loading, more details here http://requirejs.org/docs/errors.html#mismatch.

The simplest way to fix this is to just comment out the lines near the end of the socket.io.js.

/*  * Comment the below out in the file assets/js/socket.io.js, if using requirejs  * and you don't want to modify the default sails setup or socket.io.  */   if (typeof define === "function" && define.amd) {    define([], function () { return io; });  } 

The other way would be to recode the sails files in assets/js named "socket.io.js", "sails.io.js" and app.js to be amd modules.

like image 43
Cole Reed Avatar answered Sep 22 '22 15:09

Cole Reed