Author: buildbot
Date: Mon Apr 13 02:19:42 2015
New Revision: 947361
Log:
Production update by buildbot for tapestry
Modified:
websites/production/tapestry/content/cache/main.pageCache
websites/production/tapestry/content/coffeescript.html
websites/production/tapestry/content/css.html
websites/production/tapestry/content/javascript-modules.html
Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.
Modified: websites/production/tapestry/content/coffeescript.html
==============================================================================
--- websites/production/tapestry/content/coffeescript.html (original)
+++ websites/production/tapestry/content/coffeescript.html Mon Apr 13 02:19:42
2015
@@ -151,14 +151,14 @@
</div>
</li></ul>
-</div><p><strong>CoffeeScript</strong> (<a shape="rect" class="external-link"
href="http://coffeescript.org" >http://coffeescript.org</a>) is a language that
to compiles down to JavaScript.</p><p>Tapestry can automatically compile your
CoffeeScript code into JavaScript on the fly. This is done with the optional
tapestry-webresources module. It is recommended for anyone who wants to use
CoffeeScript in their application ... just let Tapestry do the compilation at
runtime (with access to Tapestry's full exception reporting
capabilities).</p><p>To use the tapestry-webresources module, just add the JAR
to your project. For example, if you're using Maven:</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl"
style="border-bottom-width: 1px;"><b>pom.xml (partial)</b></div><div
class="codeContent panelContent pdl">
+</div><p><strong>CoffeeScript</strong> (<a shape="rect" class="external-link"
href="http://coffeescript.org" >http://coffeescript.org</a>) is a language that
to compiles down to JavaScript.</p><p><em>Starting with version 5.4,</em>
Tapestry can automatically compile your CoffeeScript code into JavaScript on
the fly. This is done with the optional tapestry-webresources module. It is
recommended for anyone who wants to use CoffeeScript in their application ...
just let Tapestry do the compilation at runtime (with access to Tapestry's full
exception reporting capabilities).</p><p>To use the tapestry-webresources
module, just add the JAR to your project. For example, if you're using
Maven:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>pom.xml
(partial)</b></div><div class="codeContent panelContent pdl">
<script class="theme: Default; brush: xml; gutter: false"
type="syntaxhighlighter"><![CDATA[<dependency>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-webresources</artifactId>
<version>${tapestry-release-version}</version>
</dependency>]]></script>
-</div></div><p>All of Tapestry's own client-side code in written in
CoffeeScript and compiled, at build-time, to JavaScript.</p> <div
class="aui-message warning shadowed information-macro">
- <span class="aui-icon icon-warning">Icon</span>
+</div></div><p>All of Tapestry's own client-side code in written in
CoffeeScript and compiled, at build-time, to JavaScript.</p> <div
class="aui-message hint shadowed information-macro">
+ <span class="aui-icon icon-hint">Icon</span>
<div class="message-content">
<p>You are completely free to use either
JavaScript or CoffeeScript in your Tapestry application.</p>
</div>
Modified: websites/production/tapestry/content/css.html
==============================================================================
--- websites/production/tapestry/content/css.html (original)
+++ websites/production/tapestry/content/css.html Mon Apr 13 02:19:42 2015
@@ -74,7 +74,7 @@
<span class="icon icon-page" title="Page">Page:</span>
</div>
<div class="details">
- <a shape="rect" href="css.html">CSS</a>
+ <a shape="rect"
href="legacy-javascript.html">Legacy JavaScript</a>
</div>
@@ -83,7 +83,7 @@
<span class="icon icon-page" title="Page">Page:</span>
</div>
<div class="details">
- <a shape="rect"
href="legacy-javascript.html">Legacy JavaScript</a>
+ <a shape="rect" href="assets.html">Assets</a>
</div>
@@ -92,7 +92,7 @@
<span class="icon icon-page" title="Page">Page:</span>
</div>
<div class="details">
- <a shape="rect" href="assets.html">Assets</a>
+ <a shape="rect"
href="layout-component.html">Layout Component</a>
</div>
@@ -101,7 +101,7 @@
<span class="icon icon-page" title="Page">Page:</span>
</div>
<div class="details">
- <a shape="rect"
href="layout-component.html">Layout Component</a>
+ <a shape="rect" href="css.html">CSS</a>
</div>
@@ -148,7 +148,9 @@ public static void deactiveDefaultCSS(Or
configuration.override("InjectDefaultStyleheet", null);
}
]]></script>
-</div></div><p>Note: In Tapestry 5.3 and later, the misspelled
"InjectDefaultStyleheet" is corrected to "InjectDefaultStylesheet".</p><p>In
Tapestry 5.4, the "core" JavaScript has a configuration into which you may
inject overrides.</p></div>
+</div></div><p>Note: In Tapestry 5.3 and later, the misspelled
"InjectDefaultStyleheet" is corrected to "InjectDefaultStylesheet".</p><p>In
Tapestry 5.4, the "core" JavaScript has a configuration into which you may
inject overrides.</p><h2
id="CSS-OverridingBootstrap(Tapestry5.4andlater)">Overriding Bootstrap
(Tapestry 5.4 and later)</h2><p>The SymbolConstants.BOOTSTRAP_ROOT
("tapestry.bootstrap-root") symbol tells Tapestry where the Bootstrap css file
is. You can override that symbol (see <a shape="rect"
href="configuration.html">Configuration</a>) to have it point to your own
version of Bootstrap (or even to an empty file if you want to eliminate
Bootstrap entirely).</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>AppModule.java (partial)</b></div><div class="codeContent panelContent
pdl">
+<script class="theme: Default; brush: java; gutter: false"
type="syntaxhighlighter"><![CDATA[configuration.add(SymbolConstants.BOOTSTRAP_ROOT,
"classpath:/META-INF/assets");]]></script>
+</div></div><p>For the above, your bootstrap.css file would be in your app's
META-INF/assets/css folder.</p><p> </p></div>
</div>
<div class="clearer"></div>
Modified: websites/production/tapestry/content/javascript-modules.html
==============================================================================
--- websites/production/tapestry/content/javascript-modules.html (original)
+++ websites/production/tapestry/content/javascript-modules.html Mon Apr 13
02:19:42 2015
@@ -31,7 +31,9 @@
<link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet'
type='text/css' />
<script src='/resources/highlighter/scripts/shCore.js'
type='text/javascript'></script>
<script src='/resources/highlighter/scripts/shBrushJava.js'
type='text/javascript'></script>
+ <script src='/resources/highlighter/scripts/shBrushXml.js'
type='text/javascript'></script>
<script src='/resources/highlighter/scripts/shBrushJScript.js'
type='text/javascript'></script>
+ <script src='/resources/highlighter/scripts/shBrushPlain.js'
type='text/javascript'></script>
<script type="text/javascript">
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.all();
@@ -66,7 +68,82 @@
</div>
<div id="content">
-<div id="ConfluenceContent"><p>As web applications have evolved, the use of
JavaScript in the client has expanded almost exponentially. This has caused all
kinds of growing pains, since the original design of the web browser, and the
initial design of JavaScript, was never intended for this level of complexity.
Unlike Java, JavaScript has no native concept of a "package" or "namespace" and
has the undesirable tendency to make everything a global.</p><p>In the earliest
days, client-side JavaScript was constructed as libraries that would define
simple functions and variables:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<div id="ConfluenceContent"><div class="navmenu" style="float:right;
background:#eee; margin:3px; padding:3px">
+<h3>Related Articles</h3>
+<ul class="content-by-label"><li>
+ <div>
+ <span class="icon icon-page" title="Page">Page:</span>
</div>
+
+ <div class="details">
+ <a shape="rect"
href="javascript-faq.html">JavaScript FAQ</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon icon-page" title="Page">Page:</span>
</div>
+
+ <div class="details">
+ <a shape="rect" href="ajax-and-zones.html">Ajax
and Zones</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon icon-page" title="Page">Page:</span>
</div>
+
+ <div class="details">
+ <a shape="rect"
href="client-side-javascript.html">Client-Side JavaScript</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon icon-page" title="Page">Page:</span>
</div>
+
+ <div class="details">
+ <a shape="rect"
href="legacy-javascript.html">Legacy JavaScript</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon icon-page" title="Page">Page:</span>
</div>
+
+ <div class="details">
+ <a shape="rect" href="assets.html">Assets</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon icon-page" title="Page">Page:</span>
</div>
+
+ <div class="details">
+ <a shape="rect"
href="component-cheat-sheet.html">Component Cheat Sheet</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon icon-page" title="Page">Page:</span>
</div>
+
+ <div class="details">
+ <a shape="rect"
href="javascript-modules.html">JavaScript Modules</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon icon-page" title="Page">Page:</span>
</div>
+
+ <div class="details">
+ <a shape="rect"
href="coffeescript.html">CoffeeScript</a>
+
+
+ </div>
+ </li></ul>
+</div><p><strong>JavaScript Modules</strong> are a mechanism for bringing
modern concepts of variable scope and dependency management to JavaScript.
<em>Starting with version 5.4</em>, Tapestry uses <a shape="rect"
class="external-link" href="http://requirejs.org/" >RequireJS</a> <a
shape="rect" class="external-link"
href="https://github.com/amdjs/amdjs-api/blob/master/AMD.md" > </a>modules
internally, and provides support for using RequireJS modules in your own
Tapestry application.</p><h2 id="JavaScriptModules-TheNeedforModules">The Need
for Modules</h2><p>As web applications have evolved, the use of JavaScript in
the client has expanded almost exponentially. This has caused all kinds of
growing pains, since the original design of the web browser, and the initial
design of JavaScript, was never intended for this level of complexity. Unlike
Java, JavaScript has no native concept of a "package" or "namespace" and has
the undesirable tendency to make everything a global.</p><p>I
n the earliest days, client-side JavaScript was constructed as libraries that
would define simple functions and variables:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
<script class="theme: Default; brush: js; gutter: false"
type="syntaxhighlighter"><![CDATA[function onclickHelp(event) {
if (helpModal === undefined) {
helpModal = ...
@@ -82,7 +159,7 @@ $("#helpButton").click(onClick
$("#helpButton").click(onClickHelp);
})();]]></script>
-</div></div><p>This is an improvement in so far as it assists with name
collisions. The variables and functions can only be referenced by name from
inside the wrapper.</p><p>However, if you are building a library of code to
reuse across your application (or building a library to share between
applications) then something is still missing: a way to expose just the
function you want from inside you wrapper to the outside world.</p><p>The
old-school route is to choose a hopefully unique prefix, building a cumbersome
name (perhaps <code>myapp_onClickHelp</code>), and attach that to the global
window object. But that just makes your code that much uglier, and leaves you
open to problems if not all members of your development team understand the
rules and prefixes.</p><p>Enter the <a shape="rect" class="external-link"
href="https://github.com/amdjs/amdjs-api/wiki/AMD" >Asynchronous Module
Definition</a>. The AMD is pragmatic way to avoid globals, and adds a number of
bells and whistles th
at can themselves be quite important.</p> <div class="aui-message hint
shadowed information-macro">
+</div></div><p>This is an improvement in so far as it assists with name
collisions. The variables and functions can only be referenced by name from
inside the wrapper.</p><p>However, if you are building a library of code to
reuse across your application (or building a library to share between
applications) then something is still missing: a way to expose just the
function you want from inside you wrapper to the outside world.</p><p>The
old-school route is to choose a hopefully unique prefix, building a cumbersome
name (perhaps <code>myapp_onClickHelp</code>), and attach that to the global
window object. But that just makes your code that much uglier, and leaves you
open to problems if not all members of your development team understand the
rules and prefixes.</p><p>Enter the <a shape="rect" class="external-link"
href="https://github.com/amdjs/amdjs-api/blob/master/AMD.md" >Asynchronous
Module Definition</a>. The AMD is pragmatic way to avoid globals, and adds a
number of bells and w
histles that can themselves be quite important.</p> <div class="aui-message
hint shadowed information-macro">
<span class="aui-icon icon-hint">Icon</span>
<div class="message-content">
<p>Tapestry uses the <a shape="rect"
class="external-link" href="http://requirejs.org/" >RequireJS</a> library as
the client-side implementation of AMD. It supplements this on the server-side
with Tapestry services for even more flexibility.</p>
@@ -118,7 +195,7 @@ $("#helpButton").click(onClick
<p>With AMD, the JavaScript libraries may be
loaded in parallel by the browser (that's the <em>asynchronous</em> part of
AMD); RequireJS manages the dependency graph and invokes each function just
once, as soon as its dependencies are ready, as libraries are loaded. In some
cases, a module may be loaded just for its side effects; such modules will be
listed last in the dependency array, and will not have a corresponding
parameter in the dependent module's constructor function. In
<code>confirm-click</code>, the <code>bootstrap/modal</code> module is loaded
for side-effects.</p>
</div>
</div>
-<p><code>confirm-click</code> defines a local function,
<code>runDialog</code>. It performs some side-effects, attaching event handlers
to the body and the document. The module's export is a JavaScript object
containing a function that allows other modules to raise the modal
dialog.</p><p>If a module truly exports only a single function and is unlikely
to change, then it is acceptable to just return the function itself, not an
object containing the function. However, returning an object makes it easier to
expand the responsibilities of <code>confirm-click</code> in the future;
perhaps to add a <code>dismissDialog</code> function.</p><h3
id="JavaScriptModules-LocationofModules">Location of Modules</h3><p>Modules are
stored as a special kind of Tapestry <a shape="rect"
href="assets.html">asset</a>. On the server, modules are stored on the class
path under <code>META-INF/modules</code>. In a typical environment, that means
the sources will be in <code>src/main/resources/META-INF/module
s</code>.</p><p>Typically, your application will place it's modules directly
in this folder. If you are writing a reusable library, you will put modules for
that library into a subfolder to prevent naming conflicts. Tapestry's own
modules are prefixed with <code>t5/core</code>.</p><p>If you are using the
optional <code><a shape="rect"
href="coffeescript.html">tapestry-web-resources</a></code> module (that's a
server-side module, not an AMD module), then you can write your modules as
CoffeeScript files; Tapestry will take care of compiling them to JavaScript as
necessary.</p><p>The service <a shape="rect" class="external-link"
href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/services/javascript/ModuleManager.html">ModuleManager</a>
is the central piece of server-side support for modules. It
supports <em>overriding</em> of existing modules by contributing
overriding <a shape="rect" class="external-link"
href="http://tapestry.apache.org/5.4/apidocs/org/apache
/tapestry5/services/javascript/JavaScriptModuleConfiguration.html">module
definitions</a>. This can be useful to <a shape="rect" class="external-link"
href="http://en.wikipedia.org/wiki/Monkey_patch" >monkey patch</a> an existing
module supplied with Tapestry, or as part of a third-party library.</p><h3
id="JavaScriptModules-LoadingModulesfromTapestryCode">Loading Modules from
Tapestry Code</h3><p>Often, you will have a Tapestry page or component that
defines client-side behavior; such a component will need to load a
module.</p><p>The simplest approach is to use the <a shape="rect"
class="external-link"
href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/annotations/Import.html">Import</a>
annotation:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+<p><code>confirm-click</code> defines a local function,
<code>runDialog</code>. It performs some side-effects, attaching event handlers
to the body and the document. The module's export is a JavaScript object
containing a function that allows other modules to raise the modal
dialog.</p><p>If a module truly exports only a single function and is unlikely
to change, then it is acceptable to just return the function itself, not an
object containing the function. However, returning an object makes it easier to
expand the responsibilities of <code>confirm-click</code> in the future;
perhaps to add a <code>dismissDialog</code> function.</p><h2
id="JavaScriptModules-LocationofModules">Location of Modules</h2><p>Modules are
stored as a special kind of Tapestry <a shape="rect"
href="assets.html">asset</a>. On the server, modules are stored on the class
path under <code>META-INF/modules</code>. In a typical environment, that means
the sources will be in <code>src/main/resources/META-INF/module
s</code>.</p><p>Typically, your application will place it's modules directly
in this folder. If you are writing a reusable library, you will put modules for
that library into a subfolder to prevent naming conflicts. Tapestry's own
modules are prefixed with <code>t5/core</code>.</p><p>If you are using the
optional <code><a shape="rect"
href="coffeescript.html">tapestry-web-resources</a></code> module (that's a
server-side module, not an AMD module), then you can write your modules as
CoffeeScript files; Tapestry will take care of compiling them to JavaScript as
necessary.</p><p>The service <a shape="rect" class="external-link"
href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/services/javascript/ModuleManager.html">ModuleManager</a>
is the central piece of server-side support for modules. It
supports <em>overriding</em> of existing modules by contributing
overriding <a shape="rect" class="external-link"
href="http://tapestry.apache.org/5.4/apidocs/org/apache
/tapestry5/services/javascript/JavaScriptModuleConfiguration.html">module
definitions</a>. This can be useful to <a shape="rect" class="external-link"
href="http://en.wikipedia.org/wiki/Monkey_patch" >monkey patch</a> an existing
module supplied with Tapestry, or as part of a third-party library.</p><h2
id="JavaScriptModules-LoadingModulesfromTapestryCode">Loading Modules from
Tapestry Code</h2><p>Often, you will have a Tapestry page or component that
defines client-side behavior; such a component will need to load a
module.</p><p>The simplest approach is to use the <a shape="rect"
class="external-link"
href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/annotations/Import.html">Import</a>
annotation:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
<script class="theme: Default; brush: java; gutter: false"
type="syntaxhighlighter"><![CDATA[@Import(module =
"t5/core/confirm-click")
public class Confirm
{
@@ -135,13 +212,13 @@ public class Confirm
...
javaScriptSupport.require("my-module").invoke("setup").with(clientId,
actionUrl);]]></script>
-</div></div><p>In the first example, <code>my-module</code> exports a single
function of two parameters. In the second example, <code>my-module</code>
exports an object and the <code>setup</code> key is the function that is
invoked.</p><h3 id="JavaScriptModules-DevelopmentMode">Development
Mode</h3><p>In development mode, Tapestry will write details into the
client-side console.</p><p><img class="confluence-embedded-image"
src="javascript-modules.data/Tapestry_Integration_Test_Application_and_JavaScriptSupport__Tapestry_API_Documentation_.png"
data-image-src="/confluence/download/attachments/41813130/Tapestry_Integration_Test_Application_and_JavaScriptSupport__Tapestry_API_Documentation_.png?version=1&modificationDate=1401727827000&api=v2"></p><p>This
lists modules <em>explicitly</em> loaded (for initialization), but does
not include modules loaded only as dependencies. You can see more details about
what was actually loaded using <em>view source</em>; RequireJS ad
ds <code><script></code> tags to the document to load libraries and
modules.</p><h3 id="JavaScriptModules-Librariesvs.Modules">Libraries vs.
Modules</h3><p>Tapestry still supports JavaScript libraries.  When the
page is loading, all libraries are loaded before any modules.</p><p>Libraries
are loaded sequentially, so if you can avoid using libraries, so much the
better in terms of page load time.</p><p>Libraries work in both normal page
rendering, and Ajax partial page updates. Even in partial page updates, the
libraries will be loaded sequentially before modules are loaded or exported
functions invoked.</p><h3 id="JavaScriptModules-AggregatingModules">Aggregating
Modules</h3><p>An important part of performance for production applications is
JavaScript aggregation.</p><p>In development mode, you want your modules and
other assets to load individually. For both CSS and JavaScript, smaller files
that align with corresponding server-side files makes it much easier to debug pr
oblems.</p><p>Unlike assets, modules can't be fingerprinted, so on each page
load, the client browser must ask the server for the module's contents
frequently (typically getting a 304 Not Modified response).</p> <div
class="aui-message warning shadowed information-macro">
+</div></div><p>In the first example, <code>my-module</code> exports a single
function of two parameters. In the second example, <code>my-module</code>
exports an object and the <code>setup</code> key is the function that is
invoked.</p><h2 id="JavaScriptModules-DevelopmentMode">Development
Mode</h2><p>In development mode, Tapestry will write details into the
client-side console.</p><p><img class="confluence-embedded-image"
src="javascript-modules.data/Tapestry_Integration_Test_Application_and_JavaScriptSupport__Tapestry_API_Documentation_.png"
data-image-src="/confluence/download/attachments/41813130/Tapestry_Integration_Test_Application_and_JavaScriptSupport__Tapestry_API_Documentation_.png?version=1&modificationDate=1401727827000&api=v2"></p><p>This
lists modules <em>explicitly</em> loaded (for initialization), but does
not include modules loaded only as dependencies. You can see more details about
what was actually loaded using <em>view source</em>; RequireJS ad
ds <code><script></code> tags to the document to load libraries and
modules.</p><h2 id="JavaScriptModules-LibrariesversusModules">Libraries versus
Modules</h2><p>Tapestry still supports JavaScript libraries.  When the
page is loading, all libraries are loaded before any modules.</p><p>Libraries
are loaded sequentially, so if you can avoid using libraries, so much the
better in terms of page load time.</p><p>Libraries work in both normal page
rendering, and Ajax partial page updates. Even in partial page updates, the
libraries will be loaded sequentially before modules are loaded or exported
functions invoked.</p><h2 id="JavaScriptModules-AggregatingModules">Aggregating
Modules</h2><p>An important part of performance for production applications is
JavaScript aggregation.</p><p>In development mode, you want your modules and
other assets to load individually. For both CSS and JavaScript, smaller files
that align with corresponding server-side files makes it much easier to de
bug problems.</p><p>Unlike assets, modules can't be fingerprinted, so on each
page load, the client browser must ask the server for the module's contents
frequently (typically getting a 304 Not Modified response).</p><p><span>This is
acceptable in development mode, but quite undesirable in production.</span></p>
<div class="aui-message warning shadowed information-macro">
<span class="aui-icon icon-warning">Icon</span>
<div class="message-content">
<p>By default, Tapestry sets a max age of 60
(seconds) on modules, so you won't see module requests on every page load. This
is configurable and you may want a much higher value in production. If you are
rapidly iterating on the source of a module, you may need to force the browser
to reload after clearing local cache. Chrome has an option to disable the
client-side cache when its developer tools are open.</p>
</div>
</div>
-<p><span style="line-height: 1.4285715;">This is acceptable in development
mode, but quite undesirable in production.</span></p><p>With JavaScript
aggregation, the module can be included in the single virtual JavaScript
library that represents a <a shape="rect" class="external-link"
href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/services/javascript/JavaScriptStack.html">JavaScript
stack</a>. This significantly cuts down on both the number of requests from
the client to the server, and the overall number of bytes
transferred.</p><p>Adding a module to the stack is not the same as
<code>require</code>-ing it. In fact, you must still use
<code>JavaScriptSupport.require()</code> regardless.</p><p>What adding a module
to a stack accomplishes is that the module's code is downloaded in the first,
initial JavaScript download; the download of the stack's virtual library. When
(and if) the module is required as a dependency, the code will already be
present in the browser an
d ready to execute.</p><p>Tapestry <strong>does not</strong> attempt to
do dependency analysis; that is left as a manual exercise. Typically, if you
aggregate a module, your should look at its dependencies, and aggregate those
as well. Failure to do so will cause unwanted requests back to the Tapestry
server for the dependency modules, even though the aggregated module's code is
present.</p><p>Because Tapestry is open, it is possible to contribute modules
even into the <strong>core</strong> JavaScript stack.  This is done
using your application's module:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<p>With JavaScript aggregation, the module can be included in the single
virtual JavaScript library that represents a <a shape="rect"
class="external-link"
href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/services/javascript/JavaScriptStack.html">JavaScript
stack</a>. This significantly cuts down on both the number of requests from
the client to the server, and the overall number of bytes
transferred.</p><p>Adding a module to the stack is not the same as
<code>require</code>-ing it. In fact, you must still use
<code>JavaScriptSupport.require()</code> regardless.</p><p>What adding a module
to a stack accomplishes is that the module's code is downloaded in the first,
initial JavaScript download; the download of the stack's virtual library. When
(and if) the module is required as a dependency, the code will already be
present in the browser and ready to execute.</p><p>Tapestry <strong>does
not</strong> attempt to do dependency analysis; that is left as a manual ex
ercise. Typically, if you aggregate a module, your should look at its
dependencies, and aggregate those as well. Failure to do so will cause unwanted
requests back to the Tapestry server for the dependency modules, even though
the aggregated module's code is present.</p><p>Because Tapestry is open, it is
possible to contribute modules even into the <strong>core</strong>
JavaScript stack.  This is done using your application's module:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
<script class="theme: Default; brush: java; gutter: false"
type="syntaxhighlighter"><![CDATA[ @Contribute(JavaScriptStack.class)
@Core
public static void
addAppModules(OrderedConfiguration<StackExtension> configuration) {