Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery library module export

I am trying to understand how jQuery sets itself up.

Right at the beginning jQuery automatically calls a function, which exports a module.

How does the setup work?

Here some more detailed sub-questions which might answer the the more general question:

  • What is the use of the recursive call to function(w) at module.exports?
  • What is the use of the noGlobal variable?
  • Where is the factory actually set up and what is its type?
  • Why can the factory argument get called with one argument and with two as well?
  • What is the global argument supposed to contain? (I wish there were a type like in c++...)

(function( global, factory ) {

    if ( typeof module === "object" && typeof module.exports === "object" ) {
        // For CommonJS and CommonJS-like environments where a proper `window`
        // is present, execute the factory and get jQuery.
        // For environments that do not have a `window` with a `document`
        // (such as Node.js), expose a factory as module.exports.
        // This accentuates the need for the creation of a real `window`.
        // e.g. var jQuery = require("jquery")(window);
        // See ticket #14549 for more info.
        module.exports = global.document ?
            factory( global, true ) :
            function( w ) {
                if ( !w.document ) {
                    throw new Error( "jQuery requires a window with a document" );
                }
                return factory( w );
            };
    } else {
        factory( global );
    }

    // Pass this if window is not defined yet
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
like image 582
Beginner Avatar asked May 06 '15 14:05

Beginner


1 Answers

What is the use of the recursive call to function(w) at module.exports?

It isn't a recursive call, more of a deferred initialization function. In some CommonJS environments, like Node.JS, the global object does not have a document property, while others such as Browserify and Webpack do.

jQuery requires the document property to initialize, so it first check to see if the global object contains a document property. If it does, it initializes immediately, making in-browser CommonJS environments happy. If it does not, it returns a function that can be used to later initialize jQuery. This function could later be called on a fake window, creating with something like jsdom.


What is the use of the noGlobal variable?

The noGlobal variable is used here.

Excerpt from jQuery:

// Expose jQuery and $ identifiers, even in
// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
// and CommonJS for browser emulators (#13566)
if ( typeof noGlobal === strundefined ) {
    window.jQuery = window.$ = jQuery;
}

Essentially, if noGlobal is undefined, jQuery will add itself to the global window object. The only time it will not do this is if it is loaded by a CommonJS loader, with a document property on the global object, such as Browserify or Webpack. The call below is where noGlobal is not undefined.

factory( global, true )

Where is the factory actually set up and what is its type?

The factory variable is a function, and it is declared here:

function( window, noGlobal ) {

It is the second argument passed into the IIFE.


Why can the factory argument get called with one argument and with two as well?

Because JavaScript.

In JavaScript, there is no requirement to match the number of arguments a function is declared with. Any omitted arguments have the value undefined.


What is the global argument supposed to contain? (I wish there were a type like in c++...)

It is supposed to contain the global object for the JavaScript environment. In a browser, this object is known as window, and in Node, this object is known as global. In both environments, using this in the global scope will resolve to the global object, whatever it's global name is.

However, due to some 3rd-party wrappers which can change the scope in which jQuery is initialized, jQuery will first check if the window object is available and use it if it is. If not use, it will default to using this.

typeof window !== "undefined" ? window : this

one more question: where is the w argument coming from?

When the global object does not contain a document, it returns a function that accepts one argument, the w. This object would be a window-like object with a document that can be created with something like jsdom.

like image 101
Alexander O'Mara Avatar answered Oct 21 '22 15:10

Alexander O'Mara