A demo with Grooscript compiled files managed by RequireJS
Warning! If you run ./gradle convert, it will overwrite all existing .js files with those which don't contain RequireJS wrappers
This repository serves as Grooscript enhancement proposal, as well as the example of how RequireJS can help in managing packages and package dependencies, if import
statements would be converted into define
or require
wrappers.
The main difference with existing Grooscript compiler is that all resulting .js files have RequireJS wrappers (see below).
Define wrapper - I used it everywhere except startup script. It declares a module and all needed dependencies for the module. It's RequireJS' responsibility to fetch these dependencies in correct order. I'll repeat here it's syntax, more details you can find in official documentation.
// myClass.js
// RequireJS beginning wrapper start
define(['path/to/module1', 'path/to/module2'], function(module1, module2){
// RequireJS beginning wrapper end
// Grooscript-compiled code start
function myClass() {
...
};
// Grooscript-compiled code end
// RequireJS ending wrapper start
return myClass;
});
// RequireJS ending wrapper end
Require wrapper - I used it only in startup script, just because it's entry point, and the startup script itself is never intended to be imported. Key difference is that, with require
, you don't need to export anything outside the script with return
statement, as shown above. So, thus you don't have to have a single class in startup script, and can do any initialization logic outside of all classes.
// main.js
// RequireJS beginning wrapper start
require(['path/to/module1', 'path/to/module2'], function(module1, module2){
// RequireJS beginning wrapper end
// Grooscript-compiled code start
...
// Grooscript-compiled code end
// RequireJS ending wrapper start
});
// RequireJS ending wrapper end
Now, below is a complete list of differencies with existing Grooscript compiler.
- all
import
statements are converted to RequireJS wrappers, as listed above - directory structure of Groovy files is kept the same for .js compiled files, i.e.
src/main/groovy/ui/BaseWidget.groovy
will go tosrc/main/webapp/js/app/ui/BaseWidget.js
(otherwise RequireJS won't work) - there's
entryPoint
setting inbuild.gradle
, which marks the script that should be startup script and wrapped byrequire
instead ofdefine
index.html
contains<script data-main="js/app/main" src="js/app/require.js"></script>
tag, which includes RequireJS and points to startup scriptrequire.js
is the only library file that is placed inapp
folder instead oflib
, it's possible to have it later inlib
and keep code layout more consistent- all paths mentioned in
require
ordefine
(and thus inimport
statements), for now are relative to the place whererequire.js
stays, that's why it's inapp
folder (see above)
- Will it be easier to have just
source = 'src/main/groovy'
inbuild.gradle
? For RequireJS, we have to preserve existing folder structure. - Grooscript and jQuery dependendcies can be also managed by RequireJS, via configuration options. This will allow us to have all JS stuff under control and be able to run optimizations, minifications and getting into a single .js file compilation scripts against all the code in the project.
Any feedback is welcome.