RequireJS was selected from the matrix of AMD-compliant libraries.
Consider a web page using RequireJS to access square method from alpha.js
alpha object is created (if it does not exist) thanks to factory method.
Once the alpha module is available, alpha.square(10) returns 10*10 = 100.
RequireJS searches through require variable the file path associated with alpha, what it finds out is actually the path to alpha.js. Afterward, a <script> element loading alpha.js is auto generated under <head> and we are falling back to the first scenario.
For the moment, integration work is converging to:
- Ensure that RequireJS library is always loaded posterior to declaration of require variable.
Load RequireJS library
RequireJS library is configured as script of bootstrap - an IMMEDIATE resource, so it is always loaded after declaration of require
Have ON_LOAD resource enclosed in module definition block
Before transmission to client's browser, content of the resource is converted into module definition format.
The server side exploits information from resources graph while determine module id, dependencies array and arguments array of factory function.
Given that UISiteMap.js is a file bundled in PORTLET/web/SiteMapPortlet resource, its entities are now published via _module object.
As a result, methods declared in UISiteMap are visible to callback function passed to require.
This section deals with following topics
- How to configure a new AMD module
- How to use an AMD module
- How to use JQuery plugin as an AMD module
- Pre-defined AMD modules in GateIn
Take an example of math ON_LOAD resource.
Associated AMD module on client-side would be
The id passed to module definition block is SHARED/math, this value is actually the fully-qualified name of math resource.
- SHARED/ - for SHARED scope resource.
- PORTAL/ - for PORTAL scope resource.
- PORTLET/portlet_app_name/ - for PORTLET scope resource.
simple_operator.js shows a special statement _module = SimpleOperator, such assignment grants SHARED/math module with access to add/subtract methods.
RequireJS introduces <as> element, an extra configuration of ON_LOAD resource denoted as module alias. With this extended configuration, there is freedom in naming factory method 's arguments (see section JQuery Plugin for an use case where factory arguments must take predefined names).
In gatein-resources.xml, <as> appears as sibling of resource's <name> element or as child of resource's <depends> element.
Argument names of factory methods for SHARED/arithmetic and SHARED/calculus are customized as shown in below module definition blocks.
It has been mentioned earlier that while converting content of resource into module definition format, the server side extracts information from resource graph to generate array of dependency module ids. However, that array does not take into account indirect dependency resource.
Let A, B, C be three resources where A depends on B and B depends on C. Although C is a descendant of A in resource graph, definition of module SHARED/A has no reference to SHARE/C unless C is configured as direct dependency of A.
leads to incomplete module definition
For an arbitrary portal page showing MathPortlet portlet window(s), its HTML source includes a <script> element:
- Using GateIn API
Below simple portlet view shows generic coding style interacting with PORTLET/portlet_app_name/MathPortlet, SHARED/math and SHARED/jquery modules. The main idea of is to put all business code in callback passed to require block.
advance_operator.js delcares product method and publishes it to PORTLET/portlet_app_name/MathPortlet module object.
Updated portlet view.
RequireJS Integration provides a Java API that allows developers to interact with AMD modules (i.e modules constructed with declarative configuration) from Groovy template.
Expression jsManager.require("first", "firstAlias").require("second", "secondAlias").addScripts("BUSINESS CODE") in Groovy template would be interpreted by Groovy engine to a require block.
Suppose that MathPortlet was built over WebUI framework, then it could use following Groovy template to generate the same view.
- How to configure JQuery plugin as AMD module.
- How to interact with JQuery plugin in AMD coding style.
Consider a simple JQuery plugin declared in simple-plugin.js
Typical configuration to have this plugin appeared in form of AMD module definition would be:
As the core of example plugin is a self-execution block whose input is jQuery object, the argument in the factory method of SHARED/simplePlugin, mapping to SHARED/jquery module object, must be jQuery. <as>jQuery</as> saves us here!
Resource configuration of MathPortlet is amended to have simplePlugin in dependencies list.
Call to doesPluginWork method is added into portlet view
In spite of the fact that there is not direct reference to simplePlugin in callback, it is imperative to put SHARED/simplePlugin in dependencies array. With SHARED/simplePlugin in the array, it is certain that $ has been extended with plugin method prior to callback execution.
In practice, it is recommended that JQuery-plugin module ids are put at the end of dependencies array. That avoids unexpected wrong passing of input arguments to callback function.
In AMD programming paradigm, use of global variables is not recommended.