With my limited understanding of RequireJS and Node.js (plus JavaScript in general), I usually take a look at the source of some well-known JavaScript libraries. Every time I see something like this:
( // Wrapping
function (root, factory) {
if (typeof exports === 'object') { // Node.js
var underscore = require('underscore');
var backbone = require('backbone');
module.exports = factory(underscore, backbone);
} else if (typeof define === 'function' && define.amd) { // Require.JS
define(['underscore', 'backbone'], factory);
}
}(this, function (_, Backbone) { // Factory function, the implementation
"option strict";
function Foo() {}
return Foo; // Export the constructor
})
); // Wrapping
What I can understand (hopefully):
<script>
tagif
checks in the very beginning); the result of factory
function is either assigned to module.exports
(Node.js) or used as argument of define
function (RequireJS).Q1: how this code works without RequireJS and Node.js? if
and else if
checks would fail, factory
function is never executed and the scripts returns nothig.
Q2: what's the purpose of passing this
as root
argument? It's never used
Actually I think the code snipped in your question will not work with browser globals. The pattern used in this snipped is called UMD - Universal Module Definition. In fact there are many variations of this pattern, you can browse more examples on https://github.com/umdjs/umd
As for the questions:
Q1 This snippet will not work in browsers without RequireJS or any other AMD loader, for obvious reasons - there only two checks - for the NodeJS and define function, so without using AMD library the factory function won't be called.
To make the factory function called just add another condition for browser globals
if (typeof exports === 'object') { // Node.js
var underscore = require('underscore');
var backbone = require('backbone');
module.exports = factory(underscore, backbone);
} else if (typeof define === 'function' && define.amd) { // Require.JS
define(['underscore', 'backbone'], factory);
} else {
// Browser globals
factory(root._, root.Backbone);
}
Note that we used root object passed to the wrapper function and as nekman pointed out it will be set to window
in browser environment, so we just pass global objects defined on that window to the factory, these objects usually defined by other script
tags on the page. Hope this answers your second question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With