Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is function(global, factory) used in so many JS libraries?

Tags:

javascript

In so many JavaScript libraries, I see global, factory as parameters of functions.
Eg:

jQuery:

( function( global, factory ) {

    "use strict";

    if ( typeof module === "object" && typeof module.exports === "object" ) {
//...

Vue.js:

(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  typeof define === 'function' && define.amd ? define(factory) :
  (global = global || self, global.Vue = factory());
}(this, function () { 'use strict';

  /*  */

// ...

There probably are much more examples...

My question is: Why is the global and factory used as parameters so often and what are they?

like image 519
Learn for Fun Avatar asked Feb 23 '20 17:02

Learn for Fun


Video Answer


3 Answers

As mentioned by several people in the comments, the real answer is that this is the structure of UMD modules.

I'm writing this as an answer primarily because it's hard to illustrate this in comments. But you can clearly see what the code is doing in your Vue.js example:

    ┌──────────────────┐       ┌──────────────────┐
    │                  ▼       ▼                  │
    │    (function (global, factory) {            │
    │                                             │
    │                                             │
    │        /* deleted for clarity */            │
    │                 ┌───────────────────────────┘
    │                 │
    │    }(this, function () { 'use strict';
    │       │
    └───────┘
             /* */

         })

So basically it is an IIFE. You can rewrite this construct more clearly if you give the anonymous functions names:

// rename function () { 'use strict' ...
function Vue () { 'use strict';
    /* */
}

// rename function (global, factory) ...
function UMD (global, factory) {
    /* deleted for clarity */ 
}

UMD(this, Vue);

So global is basically this which when referenced from outside of any function points to the global object (window in browsers and not named in node.js) and factory is a function that creates the Vue.js object (or jQuery in the case of jQuery). Basically factory is the implementation of the library.

This structure is written in such a way as not to create any unnecessary variables or functions in the global scope and thus avoid polluting the global scope and avoid variable/function name clashes with other libraries.

As for why it assigns this to global? That's because window is (was?) a completely unprotected variable in global scope (that's why node.js does not give it a name) and any 3rd party code can overwrite it with a different thing or modify it. If you want the original global object of the browser while using unknown 3rd party code you need to use this this trick.

like image 138
slebetman Avatar answered Oct 09 '22 17:10

slebetman


i created tiny lib for better understand by slebetman answare

   (function (global, factory) {            
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    global.tinylib= factory();         

    } (this,function() {

// your code shoud place here
    }))

eg: this is simple i created library

(function (global, factory) {            
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = 
factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    global.tinylib = factory();         

    } (this,function() {
 -----------------------------------------mylibrary code start------------------    
 var tinylib= (function(el) {
 var obj={}
 var myelement=el

 obj.setColor=(color)=>{
 myelement.style.color=color;
  }
    return obj;
 -----------------------------------------mylibrary code end------------------    

  })
 return tinylib;
    }))

Usage of created Library

import {tinylib} from 'tinylib'

initialize:

var lib=tinylib(document.getElementById('color')) //now we use lib variable whenever we want to invoke example showen below

usage:

lib.setColor('red')
like image 24
ßãlãjî Avatar answered Oct 09 '22 17:10

ßãlãjî


In addition to the other answers, I thought that it may be worth mentioning that esbuild is adding support soon for the 'global' and 'factory' ('umd') syntax.

https://github.com/evanw/esbuild/issues/507

like image 1
Jorvy Avatar answered Oct 09 '22 17:10

Jorvy