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

前端 未结 3 1190
故里飘歌
故里飘歌 2021-02-14 18:09

I am working on a JavaScript library for JSON/XML processing. My library works in browser as well as Node.js (with xmldom and xmlhttprequest modules).<

相关标签:
3条回答
  • 2021-02-14 18:21

    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 _;
      });
    }
    
    0 讨论(0)
  • 2021-02-14 18:29

    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;
    }
    
    0 讨论(0)
  • 2021-02-14 18:47

    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 })
    
    0 讨论(0)
提交回复
热议问题