How to write a module that works with Node.js, RequireJS as well as without them

给你一囗甜甜゛ 提交于 2019-12-03 13:41:40

Take a look at how underscore.js handles it.

// Export the Underscore object for **Node.js**, with
// backwards-compatibility for the old `require()` API. If we're in
// the browser, add `_` as a global object.
if (typeof exports !== 'undefined') {
  if (typeof module !== 'undefined' && module.exports) {
    exports = module.exports = _;
  }
  exports._ = _;
} else {
  root._ = _;
}

...

// AMD registration happens at the end for compatibility with AMD loaders
// that may not enforce next-turn semantics on modules. Even though general
// practice for AMD registration is to be anonymous, underscore registers
// as a named module because, like jQuery, it is a base library that is
// popular enough to be bundled in a third party lib, but not be part of
// an AMD load request. Those cases could generate an error when an
// anonymous define() is called outside of a loader request.
if (typeof define === 'function' && define.amd) {
  define('underscore', [], function() {
    return _;
  });
}

This is what I ended up with:

// If the require function exists ...
if (typeof require === 'function') {
    // ... but the define function does not exists
    if (typeof define !== 'function') {
        // Assume we're in the Node.js environment
        // In this case, load the define function via amdefine
        var define = require('amdefine')(module);
        // Use xmldom and xmlhttprequests as dependencies
        define(["xmldom", "xmlhttprequest", "fs"], _jsonix_factory);
    }
    else {
        // Otherwise assume we're in the browser/RequireJS environment
        // Load the module without xmldom and xmlhttprequests dependencies
        define([], _jsonix_factory);
    }
}
// If the require function does not exists, we're not in Node.js and therefore in browser environment
else
{
    // Just call the factory and set Jsonix as global.
    var Jsonix = _jsonix_factory().Jsonix;
}

Here is a template I'm currently using, it's both AMD and node compatible though not directly loadable stand-alone in the browser...

The main advantage to this approach is that the domain-specific code does not need to care about what imported it, for the general case.

/**********************************************************************
* 
*
*
**********************************************************************/
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)(
function(require){ var module={} // makes module AMD/node compatible...
/*********************************************************************/




/*********************************************************************/




/**********************************************************************
* vim:set ts=4 sw=4 :                               */ return module })
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!