Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are 'module' and 'define' in JQuery source code?

I was trying to read and understand the source code of jQuery. But I can't find any information about the below part. I tried to understand the comments beside it, but can't get any helpful meaning from it.

if ( typeof module === "object" && module && typeof module.exports === "object" ) {
    // Expose jQuery as module.exports in loaders that implement the Node
    // module pattern (including browserify). Do not create the global, since
    // the user will be storing it themselves locally, and globals are frowned
    // upon in the Node module world.
    module.exports = jQuery;
} else {
    // Otherwise expose jQuery to the global object as usual
    window.jQuery = window.$ = jQuery;

    // Register as a named AMD module, since jQuery can be concatenated with other
    // files that may use define, but not via a proper concatenation script that
    // understands anonymous AMD modules. A named AMD is safest and most robust
    // way to register. Lowercase jquery is used because AMD module names are
    // derived from file names, and jQuery is normally delivered in a lowercase
    // file name. Do this after creating the global so that if an AMD module wants
    // to call noConflict to hide this version of jQuery, it will work.
    if ( typeof define === "function" && define.amd ) {
        define( "jquery", [], function () { return jQuery; } );
    }

I also debugged the code and found that both module and define are undefined.

I wondered where does the module and define come from? How can I understand it? What is it used for?

like image 880
Joe.wang Avatar asked Oct 21 '15 08:10

Joe.wang


2 Answers

This part is a UMD wrapper.

UMD wrapper?

It is meant to support the different methods that are used to import or load libraries. To do so, it is checking if one of the supported module system is available.

In summary, jQuery is checking here how it should define itself before doing so. This way, it supports global insertion as well as the two most common module patterns (commonJS and AMD).

Module pattern?

ES5 and prior did not officially support modules like most languages do (e.g. import my.module in java). As a result, by default it is hard to split your code into different modules or files to keep it well organised.

By default, The only way to import modules is to use the script tag in the HTML and rely on the global context (i.e. window) to link them. It does not check module's dependencies and you have to manually add each source files you depend on (and make sure that the dependencies of a file are inserted before it).

To solve this issue, there is currently 3 main strategies that have been developed so that you can define a module, what it depends on, and what it exports. It allows to automate module and dependencies import:

  1. The commonJS pattern that is originally node's module pattern though it is now also very used with web applications through builders like browserify or webpack. This is the pattern that is using module.exports to define a module (the module is then requested by its consumer with var module = require('modulePath');).
  2. The AMD (Asynchronous Module Definition) module pattern that is the pattern used by RequireJS for example. This is the pattern that is using define (define is used both to request dependencies and define a new module).
  3. And finally, more recently, the ES6 import pattern that will be the way to import modules with next JavaScript's version (actually there is amazing tools such as babel that allows you to already use it). It is not supported in the snippet here (but most ES6 module builders also support the two above-mentioned).
like image 93
Quentin Roy Avatar answered Sep 19 '22 15:09

Quentin Roy


define (and define.amd) is a RequireJS thing. I'm not sure about module but that's possibly related to Node.js (loosely guessing from the comments). This part of the code basically checks to see whether jQuery has been loaded alongside those other libraries, and if so it appears to ensure they are included correctly.

I imagine this is to get around issues where users have had issues with jQuery working alongside those libraries in the past, and this is jQuery's own workaround.

like image 30
James Donnelly Avatar answered Sep 19 '22 15:09

James Donnelly