JBoss Community Archive (Read Only)

GateIn Portal 3.8

Introduction to JavaScript Modules

GateIn Portal is a platform focusing on aggregating markup in the browser with portlets, but also on integrating JavaScript because each Portlet application can optionally come with JavaScript.

Since GateIn Portal 3.3, an effort was started, to bring in a support for the most recent JavaScript use cases. All important goals were met in GateIn Portal 3.5 where GateIn Modules were introduced. The most important concern was performance. With GMD, GateIn Portal is able to provide an on demand, flexible and parallel loading of JavaScript resources. The need for modularity is addressed and there is a natural mechanism to isolate JavaScript coming from different applications. Last but not least, GateIn internal JavaScript was rewritten on top of the jQuery library running in total isolation of the portlet runtimes.

GateIn Portal 3.8 brings an experimental support for hosting large 3rd party AMD-compliant frameworks such as Dojo. This is enabled by Native AMD Modules.

The notion of JavaScript Module

GateIn Portal JavaScript handling is built on top of the JavaScript module concept. JavaScript does not provide a natural way for namespacing and the notion of module was designed to solve this problem. This natural lack of namespacing could be perceived as a lack, but on the other hand, the language provides generic means to implement modules with support for namespace isolation and even more goodies, such as dependency management, their resolution at runtime, loading of JavaScript resources on demand and in parallel.

This guide will give just a brief introduction to JavaScript modules as neither the concept nor its implementation was developed within the GateIn project. GateIn Portal has rather chosen to use an existing JavaScript module loader implementation RequireJS. Please refer to RequireJS Documentation for any details not provided here.

Module in Ecmascript 6

Ecmascript 6 will provide native modules, you can read more about in this article

In the essence, the notion of module can be defined as a tuple consisting of

  • Module identifier

  • List of dependencies - i.e. (possibly empty) list of modules required by the module to work properly

  • The module code usually expressed as a self-executing function (the module function)

  • Result - the object returned by the module function that is usually consumed by other modules

At runtime, the dependency system defines a graph of module functions to execute and the result of each module is injected in other dependent modules. It can be seen as a simple dependency injection system providing parallel loading, namespacing and dependency management.

GateIn Portal supports several module formats:

  • GateIn Module Definition (GMD) - the most appropriate way to define a JavaScript module in GateIn. The module is expressed as a simple function, the list of dependencies being expressed in the gatein-resources.xml file. This format clearly decouples the module code in a JavaScript file from the module dependencies expressed in a single XML file.

  • Native Asynchronous Module Definition (AMD) - the native module format supported by RequireJS.

  • Adapted Module - this format allows to adapt other module formats such as CommonJS to GMD modules.

As noted already, modules provide more than just namespacing. This section explains the other benefits of modules. As an example, let us create a module consuming the jQuery library:

(function($) {
  $(“body”).on(“click”, “.mybutton”, function(event) {
    alert(“Button clicked”);
  };
})($)

The JavaScript part of our module is a mere function that takes as argument the jQuery object $:

  • The jQuery object is provided as a module dependency expressed as a function argument $. The module code can use the name it likes for jQuery, in our module we use the $ name. Note that the jQuery object $ can be used without needing to invoke the $.ready function because jQuery will be already loaded and initialized when the module function is executed.

  • Our module is scoped to the entire page and this code will react to any click on the .mybutton selector. Since a single event listener handles as many portlets as we have on the page we benefit of performance but also simplicity

Let us now integrate this module into GateIn Portal. For that purpose, we declare it in the WEB-INF/gatein-resources.xml file of our application's WAR file:

<gatein-resources
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.gatein.org/xml/ns/gatein_resources_1_3 http://www.gatein.org/xml/ns/gatein_resources_1_3"
  xmlns="http://www.gatein.org/xml/ns/gatein_resources_1_3">
  <portlet>
    <name>MyPortlet</name>
    <module>
      <script>
        <path>/mymodule.js</path>
      </script>
      <depends>
        <module>jquery</module>
        <as>$</as>
      </depends>
    </module>
  </portlet>
</<gatein-resources>

The module tag declares our module and its dependencies, in this case we declare that jQuery is the only dependency and it should be named $ when our module is executed. We have created a dependency relationship between our module and the jQuery module:

  • Our module will be loaded only when the portlet is displayed

  • GateIn will first load the jQuery module before loading our module

  • Several different versions of jQuery can coexist in the browser without conflicting

This introductory example is simple but outlines all important features provided by modules: performance, isolation, dependency management and ease of use.

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-10 13:20:43 UTC, last content change 2014-04-15 07:13:34 UTC.