Pale Purple https://www.palepurple.co.uk Office Address Registered Office Blount House, Hall Court, Hall Park Way,,
Telford, Shropshire, TF3 4NQ GB
sales@palepurple.co.uk GB 884 6231 01
When creating more complex web applications, you end up with more and more Javascript, which can quickly become difficult to maintain. RequireJS is one approach to helping solve this (and other issues).
Managing many Javascript files within a project can be come an issue – especially if you want to mix-and-match components (or at least be able to reuse components elsewhere) – in that it’s hard to specify dependencies between ‘classic’ Javascript files, and it’s also often hard to reuse components as there may be naming conflicts or version issues.
require.js is one approach to solving this – it helps by :
A basic example is shown below – whereby we start with a “legacy” Javascript routine (js/legacy.js) and show it changing to be loaded via RequireJS. Obviously for the purposes of this article legacy.js is quite minimal.
file: js/legacy.js :
$(document).ready(function() { var field = $('#inputfield'); field.change(function() { $('#message').text('You typed in : ' + field.val()); }); });
and example html file :
<!doctype html> <html> <head> <title>Legacy test</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.js"></script> <script src="js/legacy.js"></script> </head> <body> <h1>legacy demo</h1> <p id="message">No message</p> <input type="text" id="inputfield" value=""/> </body> </html>
The two obvious issues are :
As this “application” grows, it’s likely that more js/xxxx.js files will be created – each of which may have their own external dependencies which will need specifying in each individual html file they’re used in.
RequireJs helps us solve the above problems, as this example shows….
Firstly we’ll start by just using require.js for dependency management –
file: js/hellorequire-shim.js :
require.config({ // base url where modules are found baseUrl: 'js', paths: { jquery: 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery' }, shim : { 'legacy' : { deps: ['jquery'] } } }); require(['legacy']);
The ‘final’ line (require([‘legacy’]);) will cause RequireJS to load js/legacy.js code and run it.
Our HTML page will now change to look like :
<!doctype html> <html> <head> <title>Hello RequireJS</title> <script data-main="js/hellorequire-shim" src="components/require.js"></script> </head> <body> <h1>Require.js demo </h1> <p id="message">No message</p> <input type="text" id="inputfield" value=""/> </body> </html>
Download/install require.js to the components directory.
Note the ‘data-main‘ attribute which is used to tell require.js which component to run.
When RequireJS/require.js loads, it will add an asynchronous script tag to the body to load whatever is specified by the data-main attribute. It handily sticks a ‘.js’ on the end, so we have a little less typing – hence js/hellorequire-shim.js is loaded.
So – we’ve not (yet) made any changes to js/legacy.js – but we’ve got the beginnings of dependency management.
So – we’ve configured RequireJS for –
As our “project” grows, we’ll want to stop duplicating the configuration section – there are a few ways of doing this (see here for more details) – we currently like wrapping the require routines like so –
require(['config'], function() { require(['jquery', 'other', 'things'], function($) { console.log("Require.js demo loading"); // Run/use code here. }); });
where there is a js/config.js file containing :
// http://requirejs.org/docs/api.html#config require.config({ // base url where modules are found baseUrl: 'js', paths: { jquery: 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery' } // etc. });
Next we probably want to refactor our js/hellorequire.js a bit – so there’s a reusable AMD style module – so let’s define a module (we can also lose our dependency on jQuery at this level).
module/track.js :
define([], function() { return { trackField : function(from, to) { console.log('modularized demo'); from.change(function() { to.text('You typed in ' + from.val()); }); } }; });
Now, we can load our new module. If we want we can extend the module to add (or overwrite) functionality.
A “hellorequire-module.js” could now look like :
require(['config'], function() { require(['jquery', 'module/track'], function($, track) { console.log("Require.js demo loading"); track.trackField($('#inputfield'), $('#message')); }); });
with the HTML script tag looking like :
<script data-main="js/hellorequire-module" src="components/require.js"></script>
We could, if necessary, swap module/track to be a different component (as long as it exposes the same API as module/track.js).
The good thing about having moved to a module based approach is that what was once in legacy.js is now no longer polluting the global namespace – so we could load multiple variants of the ‘track’ module, each in isolation.
Further reading : RequireJS API
‹ iPXE Network booting for ISO images PHPUnit and PDO – max_user_connections reached ›