Grails 2.4 is now using the Asset Pipeline for managing and processing static assets in Grails applications instead of the Resources system. Th
Baxxabit's answer led me to my solution. I've been struggling with much the same thing, but wanting to make the most of the pipeline so that I can use the less-asset-pipeline plugin.
Using bootstrap as an example, I created a vendor folder as a peer of the standard assets folders and then dropped the bootstrap files under there.
application.js:
//This is a javascript file with its top level require directives
//= require jquery
//= require bootstrap-3.1.1/javascript/bootstrap
//= require_tree views
//= require_self
...
and application.css:
/*
*= require_self
*= require main
*= require mobile
*= require bootstrap-3.1.1/stylesheets/bootstrap
*= encoding UTF-8
*/
To override the boostrap customization I can simply drop a customized variables.less file into ./grails-app/assets/vendor/bootstrap-3.1.1/stylesheets/variables.less. The first folder under assets is ignored when it comes to overriding files, thereafter the path needs to match whatever you put under vendor.
This gives me this sort of hierarchy:
grails-app/assets/
├── images
...
├── javascripts
│ └── application.js
├── stylesheets
│ ├── application.css
│ ├── bootstrap-3.1.1
│ │ └── stylesheets
│ │ └── variables.less
│ ├── errors.css
│ ├── main.css
│ └── mobile.css
└── vendor
└── bootstrap-3.1.1
├── javascript
│ ├── bootstrap.js
│ └── bootstrap.min.js
└── stylesheets
├── alerts.less
...
├── variables.less
└── wells.less
I like the result. I've got the distributed package cleanly delineated and relatively easily upgradable, and I've got my changes to that package separated off into a clearly identifiable customization file.
I've put an example using the sass-asset-pipeline plugin at https://github.com/ggascoigne/grails-pipeline-scss.
To handle 3rd party libraries, you can add flipcountdown folder inside assets folder,
├── assets │ ├── flipcountdown │ │ ├── admin │ │ └── global │ ├── images │ │ ├── apple-touch-icon.png │ │ ├── apple-touch-icon-retina.png │ │ ├── favicon.ico │ │ ├── grails_logo.png │ │ ├── skin │ │ ├── spinner.gif │ │ └── springsource.png │ ├── javascripts │ │ ├── application.js │ │ └── jquery-2.1.3.js │ └── stylesheets │ ├── application.css │ ├── errors.css │ ├── main.css │ └── mobile.css
Now you can reference css and js using normal syntax,
<assets:javascript src="admin/pathToYourJSFile"/>
<assets:stylesheet src="admin/pathToYourCSSFile"/>
<assets:stylesheet src="global/pathToYourCSSFile"/>
You can create another folder like jsplugins
near standard folders (javascripts, styles, images), then you can include js library in the necessary pages, if you wouldn't use this library on all the pages.
Make something like this:
<assets:javascript src="select2/pathToYourJSFile"/>
NB: you can omit first level path under assets
path, in this example it's jsplugins
.
The best way is to use manifest.js file, where you can include necessary files via require
directive.
You should use assests
folder instead of web-app. During building war file all the files from assets will be copied to web-app folder.
Useful video from Bobby Warner: http://www.youtube.com/watch?v=VHDBlGtAHB4
Documentation: http://bertramdev.github.io/asset-pipeline/
That works fine for assets under the assets folder, but given the proliferation of web components and javascript frameworks, we often find ourselves checking out external projects, outside of a Grails project, that we want to package and distribute with our application. You also have cases where the front end of an application is worked on by front-end developers who aren't grails developers, and they use different tools to develop and test the front end in a manner that is disconnected from the grails REST services.
So, rather than copying the assets of an external project into your grails app how do you make a reference to external folders, that will insure that those assets will be included with your app whenever you run the app during development, and when you WAR the app for deployment?
Asset-pipeline seems like a backward step to me. I apparently can't use cdnjs or similar CDNs for access to external libs anymore. Am I really giving all of this away to get JS minification for my own JS code?