2

I am using bower for asset management. The Bootstrap bower repo is coming with a Gruntfile.js.

Is there a way to exclude this from the linker?

I have tried:

var jsFilesToInject = [
     '!**Gruntfile.js',
//     ...
]

But it's not working - am I putting this string in the wrong spot?

Generated HTML and Error

enter image description here

File Structure

enter image description here

P.S. I followed this guide to get here: StackOverFlow Question and ran bower install bootstrap and bower install angular.

Community
  • 1
  • 1
Tyler Wall
  • 3,747
  • 7
  • 37
  • 52
  • can you post your whole `jsFilesToInject` it seems like you have a problem of path, we can see that you load both `angular.js` and `angular.min.js` – Jérémie Parker Jan 31 '14 at 11:10
  • @Wallter, it seems that there is a problem with Sails regarding excludes, see https://github.com/balderdashy/sails/issues/2375. – ryanm Sep 15 '15 at 15:52

2 Answers2

5

A working configuration for me has been the following :

  • put the bower_components folder one level up, directly in the assets folder.
  • put all your app related files in the linker folder

    | .bowerrc
    | assets/
    |-- bower_components/
    |---- bootstrap/
    |------ dist/
    |-------- bootstrap.js
    |---- angular/
    |-- linker/
    |---- js/
    |------ sails.io.js
    |------ socket.io.js
    |---- styles/
    |---- templates/
    

In your Gruntfile.js have a jsFileToInject setup like so

    var jsFilesToInject = [
        // Below, as a demonstration, you'll see the built-in dependencies
        // linked in the proper order order
        // Bring in the socket.io client
        'linker/js/socket.io.js',

        // then beef it up with some convenience logic for talking to Sails.js
        'linker/js/sails.io.js',

        // jQuery and plugins
        'bower_components/jquery/jquery.js',

        // Bootstrap
        'bower_components/bootstrap/dist/bootstrap.js',

        // Angular
        'bower_components/angular/angular.js',

        // App file that needs to load first
        'linker/js/app.js',

        // All of the rest of your app scripts imported here
        'linker/**/*.js'
    ];

And in the .bowerrc at the root of your project, you put

    {
        "directory": "assets/bower_components"
    }
Jérémie Parker
  • 3,184
  • 2
  • 20
  • 33
  • this is a good answer, probably one of the best i've seen so far.. Only thing that sucks is you have to manually specify all of your `JSFilesToInject`. One tip is if you're using requireJs you can use the `grunt-contrib-requirejs` to do some of this for you. – NDBoost Jan 31 '14 at 15:15
  • I know this solution exists. But I think it is much nicer to just have the bower_components in the linker folder because when you run bower install, it will automatically add this to your project (seems to keep with the node/sails theme of making life easier) – Tyler Wall Feb 01 '14 at 18:36
  • You can add a .bowerrc file at the root of your project with this: `{ "directory": "assets/bower_components" }` this will tell bower where to put your dependencies. – Jérémie Parker Feb 01 '14 at 22:51
  • I've added the `.bowerrc` part to the answer. – Jérémie Parker Feb 02 '14 at 19:00
4

This is a bug in the current sails frontend generator. I have submitted a PR, but existing applications will have to be fixed manually, since the generator is only executed once.

The issue is in the end of the current pipeline.js file, in the section that actually exports the settings. At the moment it goes like this:

// pipeline.js

//... Defined rules ...

module.exports.cssFilesToInject = cssFilesToInject.map(function(path) {
  return '.tmp/public/' + path;
});
module.exports.jsFilesToInject = jsFilesToInject.map(function(path) {
  return '.tmp/public/' + path;
});
module.exports.templateFilesToInject = templateFilesToInject.map(function(path) {
  return 'assets/' + path;
});

As you can see it prepends the relative path to the tmp folder or the assets folder for templates. This results in the rule !js/foo.js in .tmp/public/!js/foo.js, which will probably not match anything.

The solution is to replace the block above in pipeline.js with the following:

module.exports.cssFilesToInject = cssFilesToInject.map(function(path) {
  var tmpPath = '.tmp/public/';
  if (path.substring(0,1) == '!')
    return '!' + tmpPath + path.substring(1);
  return tmpPath + path;
});
module.exports.jsFilesToInject = jsFilesToInject.map(function(path) {
  var tmpPath = '.tmp/public/';
  if (path.substring(0,1) == '!')
    return '!' + tmpPath + path.substring(1);
  return tmpPath + path;
});
module.exports.templateFilesToInject = templateFilesToInject.map(function(path) {
  var tmpPath = 'assets/';
  if (path.substring(0,1) == '!')
    return '!' + tmpPath + path.substring(1);
  return tmpPath + path;
});

This will check if the given rule starts with an ! and prepend it correctly, so !js/foo.js will result in !.tmp/public/js/foo.js that will correctly match.

The exclusions have to be set AFTER the result set was created. This is according to grunt's documentation. So for your case it would be:

var jsFilesToInject = [
     //...
     '!**Gruntfile.js',
]
mitom
  • 66
  • 3