javascriptnode.jsrequirejsrequirerequirejs-define

How can I convert a function to a module in RequireJS in a simplistic way?


I have been reading the documentation, but I can't seem to do this in an easy way. I think I confuse this too much with node.js which uses the same words, e.g. require, exports, module etc.

Imagine a main script something like this. (And imagine the functions are complex)

require(['jquery', 'domReady!'], function($) {

    $("#staticButton").click(function() {
        showMessage('What does this button do?');
    });

    function showMessage(message) {
        alert(message);
    }

});

Now imagine I want to use showMessage() in multiple scripts. How do I actually do that?

In Node.js I would attach showMessage() to exports.showMessage inside showMessage.js and do something like this everywhere I want to use it:

require(['jquery', 'domReady!'], function($) {

    var showMessage = require('showMessage'); // Easy huh?

    $("#staticButton").click(function() {
        showMessage('What does this button do?');
    });

});

But with RequireJS this gives me the error that I first need to load it. Do I need to require or define this before I can use the above syntax? Do I really need to add it in the main script require array? I don't like that. What if you have 20 functions?

require(['jquery', 'domReady!', func01, func02, (...) func20], function($, empty, func01, func02, (...) func20) {}

That's pure syntactic salt. I like the Node.js sugar way better:

var func01 = require(func01),
    func02 = require(func02),
    (...)
    func20 = require(func20);

I am confusing the two too much. Can someone explain how I simply put functions in external files and use them as simple as possible?


I'm assuming the module turned function needs to look like this:

define(function(require, exports, module) {
    return function(message) {
        alert(message);
    }
});

..but if that can be done easier, I'd love to hear about it.


Solution

  • You should try to think in terms of modules, functions are something more low-level in this context. You define modules, requiring them later returns their public "interface" as an object with some properties, which may happen to be functions.

    What I found useful was a "static utils module" pattern:

    utils.js

    define(function () {
        return {
            showMessage: function (text) {
                alert(text);
            },
            foo: function () {
                alert('bar');
            }
        }
    })
    

    Or a simplified equivalent: (-> docs)

    utils.js

    define({
        showMessage: function (text) {
            alert(text);
        },
        foo: function () {
            alert('bar');
        }
    });
    

    Then, inside your main.js:

    define(['utils'], function (Utils) {
        Utils.showMessage('!');
    })
    

    If you end up with too many dependencies (that usually indicates your module is doing too much, by the way) you can use the sugar syntax instead:

    define(function (require) {
        var Utils = require('utils');
        Utils.showMessage('!');
    })