Explanation of define of the RequireJS library

JavascriptRequirejs

Javascript Problem Overview


I started to read several tutorials about RequireJS. In none of them was the "define" keyword explained satisfactorily for me. Could someone help me with the following :

define(
  ["Models/Person", "Utils/random", "jquery"], 
  function (Person, randomUtility, $) {..}
)  

What is "define"? Is define a function with an array and an anonymous function inside of it? Or is it something else? Can someone give me more information about this kind of definitions?

Addition: Thank you nnnnnn and pradeek for your answers. Here in Europe it was 2:30 in the night when I was posting the question. Maybe therefore I didn't recognize it was a simple function call.

Javascript Solutions


Solution 1 - Javascript

define is not specific to RequireJS, it is part of the AMD specification. Burke will note that RequireJS doesn't implement exactly how AMD specifies it, since AMD didn't really keep browsers in mind.

define doesn't have an anonymous function in it. define is a method made available to AMD based JavaScript files for loading their data. Libraries like RequireJS make this available to you. The specific implementation probably isn't valuable to you. So I'll go over the one you provided as it's the most common way to declare a module.

define( [array], object );

Array is a list of modules that this module depends on. There is a 1 to 1 relationship between modules and files. You can not have multiple modules in a file nor multiple files for one module.

Object is the module you are defining. This can be anything, a struct, or a function that returns a struct. Read the docs on RequireJS for more details.

If object is a function, the arguments passed to the function are the modules listed as dependencies in the first define argument. It is also important to note than when you pass a function as object, it will only run one time. The methods or properties created on this one instantiation can be accessed at any time though, can then be accessed by other modules that list this module as a dependency.

Good luck, I recommend playing around with this and reading the docs when things don't make sense. RequireJS docs are great as a quick start on how AMD modules work.

Solution 2 - Javascript

I found define defined near the bottom of require.js (I too was wondering what kind of a thing this define word is, and this is the answer I was looking for):

/**
 * The function that handles definitions of modules. Differs from
 * require() in that a string for the module should be the first argument,
 * and the function to execute after dependencies are loaded should
 * return a value to define the module corresponding to the first argument's
 * name.
 */
define = function (name, deps, callback) {
    var node, context;

    //Allow for anonymous modules
    if (typeof name !== 'string') {
        //Adjust args appropriately
        callback = deps;
        deps = name;
        name = null;
    }

    //This module may not have dependencies
    if (!isArray(deps)) {
        callback = deps;
        deps = null;
    }

    //If no name, and callback is a function, then figure out if it a
    //CommonJS thing with dependencies.
    if (!deps && isFunction(callback)) {
        deps = [];
        //Remove comments from the callback string,
        //look for require calls, and pull them into the dependencies,
        //but only if there are function args.
        if (callback.length) {
            callback
                .toString()
                .replace(commentRegExp, '')
                .replace(cjsRequireRegExp, function (match, dep) {
                    deps.push(dep);
                });

            //May be a CommonJS thing even without require calls, but still
            //could use exports, and module. Avoid doing exports and module
            //work though if it just needs require.
            //REQUIRES the function to expect the CommonJS variables in the
            //order listed below.
            deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);
        }
    }

    //If in IE 6-8 and hit an anonymous define() call, do the interactive
    //work.
    if (useInteractive) {
        node = currentlyAddingScript || getInteractiveScript();
        if (node) {
            if (!name) {
                name = node.getAttribute('data-requiremodule');
            }
            context = contexts[node.getAttribute('data-requirecontext')];
        }
    }

    //Always save off evaluating the def call until the script onload handler.
    //This allows multiple modules to be in a file without prematurely
    //tracing dependencies, and allows for anonymous module support,
    //where the module name is not known until the script onload event
    //occurs. If no context, use the global queue, and get it processed
    //in the onscript load callback.
    (context ? context.defQueue : globalDefQueue).push([name, deps, callback]);
};

Solution 3 - Javascript

I found this page Why AMD? very helpful. To summarize from this page, AMD specification is helpful in overcoming "write a bunch of script tags with implicit dependencies that you have to manually order" problem. It is helpful in loading the dependencies before executing the required functions, similar to import in other programming languages like python. AMD also prevents the global namespace pollution problem. Check "It is an improvement over the web's current "globals and script tags" because" section.

Solution 4 - Javascript

I think the RequireJs API specification sums it up pretty well:

> If the module has dependencies, the first argument should be an array of dependency names, and the second argument should be a definition function. The function will be called to define the module once all dependencies have loaded. The function should return an object that defines the module.

They list examples of all the various syntactic forms of defines.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWolfgang AdamecView Question on Stackoverflow
Solution 1 - JavascriptDrewView Answer on Stackoverflow
Solution 2 - JavascriptBlueMonkMNView Answer on Stackoverflow
Solution 3 - Javascriptvine'thView Answer on Stackoverflow
Solution 4 - Javascriptundefined behaviourView Answer on Stackoverflow