I use require.js in a Grails project. There are a couple of single JavaScript files containing the require.js modules defined with define
.
There is also a *.gsp file which generates the require.js config and the entry point starting with require()
as there is some dynamic configs to be generated. It looks somehow like this:
<%@ page contentType="application/javascript;charset=UTF-8" %>
require(['a', 'b'], function(a, b){
...
var a = ${controllerPropertyA};
...
some functions
...
});
In my layout I integrate require.js like this:
<script data-main='http://example.com/exampleController/dynamicGenerateMethod?domain=xyz.com' src='http://example.com/assets/require.js'></script>
All the modules a , b, and so on are asynchronously loaded by require.js. Now I would like to bundle them into a single file - I could use the require.js optimize tool but I prefer to use the assets-pipeline. This works as far as that I get all modules bundled into a single optimized-modules.js
which is available on http://example.com/assets/optimized-modules.js
.
The question: I would like to have the optimized JavaScript code in the dynamically rendered GSP file. So how can I inject the optimized-modules.js file into the GSP I'm dynamically rendering? I already thought about a tag defined in the tag library so that my *.gsp would look like
<%@ page contentType="application/javascript;charset=UTF-8" %>
<g:renderFile file="/assets/optimized-modules.js" />
require(['a', 'b'], function(a, b){
...
var a = ${controllerPropertyA};
...
some functions
...
});
and the tag definition somehow like that:
def g:renderFile = { attrs, body ->
def filePath = attrs.file
if (!filePath) {
throwTagError("'file' attribute must be provided")
}
//out << filePath
out << request.servletContext.getResource(filePath).file
//out << grailsResourceLocator.findResourceForURI(filePath).file.text
//out << grailsApplication.mainContext.getResource(filePath).file.text
//out << Holders.getServletContext().getResource(filePath).getContent()
//IOUtils.copy(request.servletContext.getResourceAsStream(filePath), out);
}
But I can't get the content of the minified optimized-modules.js which was done by the assets-pipeline plugin on startup. Any thoughts on this?
Ok, I finally found it out by myself:
Instead of using the grailsResourceLocator
I had to use the assetResourceLocator which is the way to go if you try to access assets resources.
My tag definition now looks like:
def renderFile = { attrs, body ->
def filePath = attrs.file
if (!filePath) {
throwTagError("'file' attribute must be provided")
}
ServletContextResource bar = (ServletContextResource)assetResourceLocator.findAssetForURI(filePath)
String fileAsPlainString = bar.getFile().getText("UTF-8")
out << fileAsPlainString
}
That way I can inject a compile assets javascript file into my GSP - perfect!