This feature is experimental.
The support for native AMD modules was added in GateIn Portal 3.8. Native AMD modules exhibit three main differences against GateIn Modules (GMD):
Motivation
Despite the great flexibility of GateIn Modules (GMD), there are a few situations where they cannot provide an appropriate solution. One such is a requirement to use a large 3rd party JavaScript framework such as Dojo. Dojo complies with the AMD specification and therefore it should in theory be possible to declare its modules as GMD Modules, but there is a couple of reasons why that is not a way to go:
-
Large. Dojo 1.9.2 contains as many as 4899 JavaScript files. Can you imagine that you declare them in gatein-resources.xml? Well, it is perhaps possible, if you write a tool that does that for you. But such a tool would have to provide also the dependency tree which is by no means trivial.
-
Extreme AMD. Although still AMD compliant, there are constructs, that GMD cannot handle at all:
-
Relative module names. Let us have a dependeny graph as simple as: dojo/sniff depends on dojo/has. Given that both dojo/sniff and dojo/has live in the same directory named dojo, the dojo/sniff.js file can start with define(["./has"], function(has){ , but relative module path names like "./has" will not be handled by GMD.
-
Cyclic dependencies. However questionable their purpose, this happens in the AMD world but GateIn Portal capitulates with an error when seeing them.
-
Inline require. Calls like the following are legal in AMD but cannot be declared in any way in means of GMD: require([id == 'platform' ? platformId : defId], function(provider){...});. There are two problems with that: first, you do not know at development time what (and at which position) should be declared as a dependency in gatein-resources.xml and second, the GMD implementation does server-side wrapping of all modules which causes that these inline require() calls result in a request for a non-existent resource.
-
Loader Plugins. Some specific loader plugins are supported in GateIn Portal (see GMD Module Resources), but their diversity in the AMD world is much broader than GMD is able to cover. In AMD, the string following the ! separator (i.e. the resource ID) is to be interpreted by the loader plugin, so effectively, they can mean just anything: be it an URL, name of another module, some magic string... But the present GMD implementation is able to interpret them as resource paths only.
How to Use Native AMD Modules
To solve all the above, the native AMD modules were introduced. Let us look how to use them.
To ease the declaration of AMD modules in gatein-resources.xml esp. in situations when there are lots of modules, the <amd> element was introduced. It offers Maven assembly-plugin like <includes> and <excludes> subelements so that a large amount of resources can be declared in a concise way.
gatein-resources.xml
<gatein-resources xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.gatein.org/xml/ns/gatein_resources_1_4 http://www.gatein.org/xml/ns/gatein_resources_1_4"
xmlns="http://www.gatein.org/xml/ns/gatein_resources_1_4">
<amd>
<fileset>
<directory>/dojo-release-1.9.2-src</directory>
<excludes>
<exclude>**/tests/**</exclude>
<exclude>**/test/**</exclude>
<exclude>**/.*/**</exclude>
<exclude>**/*.php</exclude>
<exclude>**/.*</exclude>
<exclude>**/README</exclude>
<exclude>**/LICENSE</exclude>
</excludes>
</fileset>
</amd>
The above example includes everything important from an unchanged dojo source distribution present in src/main/webapp/dojo-release-1.9.2-src directory of the project. The path configured in <directory> element has to be relative to the root directory of your WAR. Declaring external paths such as http://mycdn.example.com/js/ is not supported in <directory>.
Both JavaScript files and non-JavaScript resources distributed with Dojo, such as images, HTML templates, CSS files, etc. are bulk-registered here. Note that the implicit and unchangeable scope of all resources imported in this way is SHARED.
Further, there is <native-amd> element which just marks a GMD style module as "being native AMD" to the effect that
gatein-resources.xml cont.
<module>
<name>dojoPortlet</name>
<native-amd>true</native-amd>
<script>
<path>/js/dojo-portlet.js</path>
</script>
</module>
<module>
<name>dojoPortletWithButton</name>
<native-amd>true</native-amd>
<script>
<path>/js/dojo-portlet-with-button.js</path>
</script>
</module>
In /js/dojo-portlet.js and /js/dojo-portlet-with-button.js we use modules from Dojo as dependencies in the usual AMD way:
/js/dojo-portlet.js
require(['dojo/fx', 'dojo/_base/fx', 'dojo/domReady!'], function (fx, coreFx) {
fx.chain([
coreFx.fadeIn({ node: "dojoWorks", duration: 3000 }),
coreFx.fadeIn({ node: "inJBossPortal", duration: 3000 })
]).play();
});
/js/dojo-portlet-with-button.js
require(['dijit/form/Button','dojo/dom','dojo/domReady!'], function (Button, dom) {
var myButton = new Button({
label: "Click me!",
onClick: function(){
// Do something:
dom.byId("dojoButtonResult").innerHTML += "Thank you! ";
}
}, "dojoButton");
});
/js/dojo-portlet.js and /js/dojo-portlet-with-button.js are then linked with the respective portlets in the final part of gatein-resources.xml
gatein-resources.xml final
<portlet>
<name>DojoPortlet</name>
<module>
<depends>
<module>dojoPortlet</module>
</depends>
</module>
</portlet>
<portlet>
<name>DojoPortletWithButton</name>
<module>
<depends>
<module>dojoPortletWithButton</module>
</depends>
</module>
</portlet>
</gatein-resources>