In an attempt to bring some sort of order to my JavaScript projects, I’m introducing the require.js library. As it says, require.js is a Javascript file and module loader.
1 |
<script src="scripts/requirement34aFinal.js"></script> |
This means that I can break away from HTML files that have line after line like the preceding. Instead, I can specify the file that needs to be loaded for the upcoming function and require.js will load it for me. It can also handle some optimization of files.
require.js requires that you format your code using define blocks that specify the contents of the files. The format given in the example require.js is fairly nice, but doesn’t allow you to leverage off of private variables. The change to do so fits neatly into require.js’s syntax and somehow feels more natural than doing the private variables on their own.
Obviously you need to include require.js in your project via a <script> tag – there’s no getting around that. In the script tag you also specify the name of a JavaScript file that will be run as the page loads – in this case, main.js. This is all that you need to pollute your HTML with.
1 |
<script data-main="scripts/main" src="scripts/require.js"></script> |
For this example, I’m going to need to load my “game engine” (really just a moving red square), jQuery (really really lazy) and the requestAnimationFrameShim. All of these are saved in appropriately named separate files in my main/scripts directory – respectively, gameEngine.js, jQuery.js and requestAnimationFrameShim.js.
Next up, we enter some require.js code into the main.js file that will be loaded as the page loads. We specify the names of the files (without the .js extension) as well as some code that should be run:
1 2 3 4 5 6 7 |
require(["gameEngine", "jQuery", "requestAnimationFrameShim"], function(engine) { var canvas = $("#mainCanvas")[0]; var context = canvas.getContext("2d"); engine.initialize(context, canvas); engine.start(); }); |
The engine in the function definition will be loaded with the value of the define() element in the gameEngine.js file – we’ll have a look at that in a moment. In addition, jQuery.js and requestAnimationFrameShim.js are loaded and ready for us. In this function we retrieve the value of a <canvas/> element and get the 2D context from it. We then call the initialize() method on the engine and then start() it.
The gameEngine.js is where we first define our own require.js module. Our module will have five private variables – a reference to the 2D context to allow us to draw, the width and height of the canvas, the current x position and a reference to the object used as part of the declarations. In addition, we have one private function loop() that allows us to make sure we control the looping.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
define(function(engine) { var context; var x = 0; var that = {}; var width, height; var initialize = function(newContext, canvas) { width = canvas.width; height = canvas.height; context = newContext; context.fillStyle = 'red'; }; that.initialize = initialize; var start = function() { requestAnimationFrame(loop); }; that.start = start; var loop = function() { requestAnimationFrame(loop); context.clearRect(0, 0, width, height); context.fillRect(50 + x, 50, 100, 100); x++; }; return that; }); |
Here we have dynamically loaded module, with the benefits that having private “member” variables provide.
Leave a Reply