

How to safely determine if JavaScript is running in Node.js or the browser  - etler
http://timetler.com/2012/10/13/environment-detection-in-javascript/

======
shtylman
You are looking at the problem wrong. Instead of putting these hacks into your
code you should use some sort of bundler (component/browserify/script/etc..)
to prepare your code for the client. That way you leave it up to the user to
determine how they want to package the stuff versus making assumptions about
it.

~~~
firefoxman1
Yeah, I'm pretty sure that the code you publish to NPM can be different than
your client-side script.

Shouldn't we just be making two _slightly_ different versions?

~~~
shtylman
That is the point. You don't need to be making two versions. This has nothing
to do with npm even. Just write your code using the commonjs require syntax.
When you want client side scripts use one of the many different bundlers which
can resolve the requires and turn it into whatever loader style you want (flat
time, AMD, custom, etc). This provides much more flexibility and keeps the
code free of boilerplate which serves no purpose.

------
ricardobeat
The `this.module` trick is still relying on behaviour that is specific to
node. Why not go the simple way then?

    
    
        typeof process !== 'undefined'
        && process.versions
        && process.versions.node

~~~
etler
That's true, but I was looking for a solution that could not be tricked by
defining a variable on the client side. I know the probability of someone
using that particular variable is low, but my proposed solution is fool proof
and also simple.

~~~
TimothyFitz
module = NaN will cause your script to be tricked, because NaN !== NaN.

Not sure how to fix it, because isNaN can be overridden.

~~~
riquito
You can check yourself if a value is NaN

    
    
        // NaN typeof is ... number
        typeof value === 'number' && value != value
    

btw, the original isNaN() doesn't check if a value is NaN, it checks if a
value is coercible to a number

    
    
        > isNaN("hello world")
        true

------
vjeux
It's actually very hard to make a bullet proof test. Here's a way to spoof
your test :)

    
    
      > var n = 0; window.__defineGetter__('module', function () { return n++; })
      > this.module !== module
      true

~~~
etler
Yeah, I shouldn't say "bullet proof". But basically a simple way to not
reserve any variable names. You can definitely get around it if you're
determined but if you do that you probably want the script to run that way
anyways, and that's fine. I just didn't like how existing checks made it a
hard requirement for end users to not use certain variable names.

------
jrockway
A classic example of much engineering effort spent on avoiding passing an
argument to a function. I would write:

    
    
       foo = foo_lib.import({clientside_api: true});
    

Now it works every time and it's easy to determine why.

------
sjs
You can check for many things on either side. Even if you're paranoid checking
2-3 of these should suffice. There's nothing bullet-proof if someone is trying
to fool the test.

In the browser: window, window === this, document, navigator, many JS APIs
such as Audio, Canvas, many DOM and CSS objects, etc. The top level is
littered with these things.

Node: module, process, require.main === module, Buffer.

------
iso8859-1
Here's how Emscripten does it:
[https://github.com/kripken/emscripten/blob/master/src/shell....](https://github.com/kripken/emscripten/blob/master/src/shell.js#L11)

