I've been working on code that works on Browser, Web Workers and NodeJS. In order to export my module, I've been writing ugly code like this one:

(function () {
  /* ... Code that defines MyModule ... */
  var all;
  if (typeof self !== 'undefined') {
    all = self; // Web Worker
  } else if (typeof window !== 'undefined') {
    all = window; // Browser
  } else if (typeof global !== 'undefined') {
    all = global; // NodeJS
  all.MyModule = MyModule;
  if (typeof module !== 'undefined') {
    module.exports = MyModule;

One-line Solution

Guillaume Marty showed me that sink.js uses this as a replacement for self, window and global. I managed to add support for module.exports in a one-liner!

(function (global) {
  /* ... Code that defines MyModule ... */
  global.MyModule = (global.module || {}).exports = MyModule;

I have been looking for this magic line for a long time, I hope it will be useful to you too 🙂

If you liked this article, you might be interested in my Twitter feed as well.
  • Nico

    The pitfall (or the advantage, depends on what your primary intention was) in your solution is that you assume that your parameter "this" will be the global object.
    Which he may not be depending on the context.
    Your code will be more robust if you retrieve the global object this way :

    global = (function(){ return this || (1,eval)('this') })();

    I suggest you may read this article :

    Joyeux noël !

  • Vjeux .

    My goal isn't to have a bullet-proof version involving weird tricks such as indirect eval calls but something that work under normal conditions for Browser, WebWorkers and NodeJS.

    Thanks for the link, re-reading it from times to times can't harm 🙂


Related Posts

  • August 20, 2011 Idea – mouseFreeze – A solution for Browser FPS Games (8)
    There is an open problem in porting real game into the web browser related to cursor handling. Problem Many games such as First-Person Shooters require the mouse to freely move, without the constraints of screen edges. However there is no such API in the browser to make this […]
  • September 22, 2011 URLON: URL Object Notation (43)
    #json, #urlon, #rison { width: 100%; font-size: 12px; padding: 5px; height: 18px; color: #560061; } I am in the process of rewriting MMO-Champion Tables and I want a generic way to manage the hash part of the URL (#table__search_results_item=4%3A-slot). I no longer […]
  • August 19, 2011 jParser – Binary File Parsing revisited using Javascript (11)
    Writing a parser for a structured binary format such as a 3D model is extremely annoying. You have first to declare your file structure, and then go over every structure again and make a proper code to parse it. This is mainly caused because the lack of introspection of C/C++ and for […]
  • August 19, 2011 Javascript – Stupid Idea: Hoisting at the end (0)
    JSLint imposes us to do manual hoisting of variables. What if we did it but at the end of the function? :P How you write function print_array (array) { var length = array.length; for (var i = 0; i < length; ++i) { var elem = array[i]; console.log(elem); […]
  • July 26, 2012 CSS – Cross Browser Drag Cursor (4)
    grab and grabbing are two great CSS cursors you can use when you are moving things around. Windows: Mac: Since those are not standard, it is really tricky to get them working cross browser. This article is going to show you all the available workarounds to get the best version […]