4 strategies for passing parameters to RequireJS modules
RequireJS is a great library for managing JavaScript files, modules and the dependencies between them. This post requires (pun intended) some knowledge of the framework. If this is all new to you, point your browser to requirejs.org to find out what all the fuzz is about.
Introduction
Recently I took upon me the task of cleaning up all the JavaScripts in a web application (built on ASP.NET) where total script anarchy had ruled for years. You could find scripts all over the place. Needless to say, RequireJS became my weapon of choice to bring order to the chaos.
As in many (probably all), server-side web applications, I found my self wanting to pass server-side data into client-side scripts. So the question was: How can I do this with RequireJS? This blog post is a summary of 4 different strategies to achieve this.
Setup
To keep it simple, I'm going to use JavaScript to display an alert box with a greeting based on the input given. In the spirit of keeping things simple, the input is only hardcoded strings.
#1 Passing parameter to method
Starting of slow, we let our require module return a JavaScript object with a method that accepts a parameter. This is pretty basic stuff, and should be sufficient for most scenarios.
index.html
<script src="scripts/require.js"></script>
<script>
require(['scripts/app'], function(app){
app.greet('World');
});
</script>
app.js
define(function(){
return {
greet: function(name){
alert('Hello ' + name);
}
};
});
#2 Passing object to method
While #1 works great when you have one, or only a handful of parameters, it can get quite messy when you're dealing with a lot of parameters. To counter this we can let our module accept an object instead.
index.html
<script src="scripts/require.js"></script>
<script>
require(['scripts/app'], function(app){
app.greet({
salutation: 'Dr.',
name: 'Who'
});
});
</script>
app.js
define(function(){
return {
greet: function(config){
alert('Hello ' + config.salutation + ' ' + config.name);
}
};
});
#3 Using RequireJS configuration
By loading the pre-defined RequireJS module aptly named "module" into your own module, you can define and access configuration data.
Note: The definition must be done before you include the require.js file, and this only works for define and not require modules.
index.html
<script>
var require = {
config: {
'app': { //This must match your module name
name: 'Sherlock'
}
}
};
</script>
<script data-main="scripts/app" src="scripts/require.js"></script>
app.js
define(['module'], function(module){
alert('Hello ' + module.config().name);
});
#4 Using a separate configuration module
Sometimes you'll have multiple modules needing the same input, then you can define a separate configuration module, and load it into your module like any other. I think this gives an nice clean separation between logic and data, but it can be a bit of an overkill i many situations.
index.html
<script>
var require = {
config: {
'config': {
name: 'Everybody'
}
}
};
</script>
<script data-main="scripts/app" src="scripts/require.js"></script>
config.js
define(['module'], function(module){
return {
name: module.config().name
}
});
app.js
require(['config'], function(config){
alert('Hello ' + config.name);
});