crazy4groovy
3/19/2013 - 1:37 PM

allow it to be used in the browser or nodejs

allow it to be used in the browser or nodejs

;(function(vash){

    // this pattern was inspired by LucidJS,
    // https://github.com/RobertWHurst/LucidJS/blob/master/lucid.js

    if(typeof define === 'function' && define['amd']){
        define(vash); // AMD
    } else if(typeof module === 'object' && module['exports']){
        module['exports'] = vash; // NODEJS
    } else {
        window['vash'] = vash; // BROWSER
    }

})(function(exports){

    exports.whatever = function(){}

    return exports;
}({}));
// https://github.com/chjj/marked/blob/master/lib/marked.js

;(function() {

var marked = function(){}

if (typeof module !== 'undefined') {
  module.exports = marked;
} else {
  this.marked = marked;
}

}).call(function() {
  return this || (typeof window !== 'undefined' ? window : global);
}());

// This pattern requires an additional index.js to include the above file for nodejs:
module.exports = require('./lib/marked');
// https://github.com/RobertWHurst/LucidJS/blob/master/lucid.js
(function(factory) {

	//AMD
	if(typeof define === 'function' && define.amd) {
		define(factory);

	//NODE
	} else if(typeof module === 'object' && module.exports) {
		module.exports = factory();

	//GLOBAL
	} else {
		window.LucidJS = factory();
	}

})(function() {
	var api;

	//return the api
	api = {
		"emitter": EventEmitter
	};

	return api;

	function EventEmitter(object) {}
});
;(function(window, undefined) {

  /** Detect free variable `exports` */
  var freeExports = typeof exports == 'object' && exports &&
    (typeof global == 'object' && global && global == global.global && (window = global), exports);


  /*--------------------------------------------------------------------------*/

  // expose Lo-Dash
  // some AMD build optimizers, like r.js, check for specific condition patterns like the following:
  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
    // Expose Lo-Dash to the global object even when an AMD loader is present in
    // case Lo-Dash was injected by a third-party script and not intended to be
    // loaded as a module. The global assignment can be reverted in the Lo-Dash
    // module via its `noConflict()` method.
    window._ = lodash;

    // define as an anonymous module so, through path mapping, it can be
    // referenced as the "underscore" module
    define(function() {
      return lodash;
    });
  }
  // check for `exports` after `define` in case a build optimizer adds an `exports` object
  else if (freeExports) {
    // in Node.js or RingoJS v0.8.0+
    if (typeof module == 'object' && module && module.exports == freeExports) {
      (module.exports = lodash)._ = lodash;
    }
    // in Narwhal or RingoJS v0.7.0-
    else {
      freeExports._ = lodash;
    }
  }
  else {
    // in a browser or Rhino
    window._ = lodash;
  }
}(this));
;(function(exports) {
    /*global define:true,EventEmitter:true*/
    'use strict';

// EventEmitter is an external dependency - ed.
function construct(EventEmitter) {
    
    function StateMachine(options) {}

    // followed by actual class def - ed.
}

// We need to build the StateMachine class using the construct function
// This construction will occur differently depending on the existence of AMD
if(typeof define === 'function' && define.amd) {
    // In this case, AMD is present on the page
    // We will assume (if wrong, I'm sorry) that the script is being loaded with it
    // So we should load EventEmitter from the components directory via AMD too
    var preBuilt;
    define(['./components/eventEmitter/EventEmitter.js'], function(EventEmitter) {
        // This function will try to use a previous result of the construct function
        // This saves rebuilding every time

        // If it has not been built yet then it will be
        if(!preBuilt) {
            preBuilt = construct(EventEmitter);
        }

        // Now return the built version which may have been loaded from the cache thing
        return preBuilt;
    });
}
else {
    // Without AMD on the page they must load EventEmitter manually
    // Which also means StateMachine must be built and exposed manually
    // So we use the global EventEmitter instance and drop StateMachine into the global object too
    exports.StateMachine = construct(EventEmitter);

    // If the dependency is not met the user will probably get an undefined warning
}

}(this));

This Is Absolutely Tiring

Every time I start a node module, or a new JS project, I'm confronted with this same question: how do I structure it to allow it to be used in the browser or nodejs, without requiring a build step, and without getting in the way of my development?

While developing, I typically create some type of browser-based environment; Firebug and Web Inspector are still miles ahead of anything else we've got. Ideally I want to be able to add a file via a script tag, and have that be the only requirement.

As @visionmedia points out, this is ridiculous.

This gist is meant to compile all of the various ways I've seen of guarding against/for a variety of module systems. Fork it and add your own, I'll try to bring them into this one.