When developing single page web applications, patterns of structure, organization and reuse become ever more important. This especially holds true when there is a need to maintain mulitiple web applications, each of which targeting a specific form factor, while also sharing many of the same underlying core APIs.
In the context of client-side templating, such patterns begin to emerge, quite naturally so, when leveraging RequireJS modules and the RequireJS text plugin.
Template Modules
One specific pattern I have found myself implementing is that of a single Templates Module which provides a centralized location from which all compiled templates within an application can be referenced. A rather simple pattern, Template Modules are only concerned with loading, compiling and providing a public API to access compiled templates; that is, a Templates Module simply requires all external templates, and provides named methods for retrieving the compiled template functions of each.
A basic implementation of a Templates module is as follows (while Handlebars may be used in this example, any template engine would suffice):
define( function( require ) { var Handlebars = require('Handlebars') , _template1 = require('text!app/templates/template-1.tpl') , _template2 = require('text!app/templates/template-2.tpl') , _template3 = require('text!app/templates/template-3.tpl') , _template4 = require('text!app/templates/template-4.tpl'); return { template1: function() { return Handlebars.compile( _template1 ); }, template2: function() { return Handlebars.compile( _template2 ); }, template3: function() { return Handlebars.compile( _template3 ); }, template4: function() { return Handlebars.compile( _template4 ); } } });
The main benefit of implementing a Templates Module is reuse, as different modules can use the same templates without a need for redundantly requiring and compiling the templates themselves. Additionally, Template Modules provide a convenient means of abstracting away the underlying template engine from client code, thus reducing the amount of refactoring needed should the template engine itself ever need to change.
When using the RequireJS Optimizer, each external template will be included in the optomized build and loaded synchronously, and so there is no additional overhead in terms of HTTP requests when requiring each template in a single location.
You can check out a basic example implementation of a Templates Module (in the context of Backbone) here.