3 ms·
How to safely determine if JavaScript is running in Node.js or the browser
- ricardobeat 14y agoThe `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 14y agoThat'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 14y agomodule = NaN will cause your script to be tricked, because NaN !== NaN. Not sure how to fix it, because isNaN can be overridden.
- etler 14y agoAhh, that's clever. Overall I just don't want to tell people what variable names to use, even if they are obscure. At the very least the end developer can use the variable names for everything else other than NaN.
- riquito 14y agoYou 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
- shtylman 14y agoYou 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 14y agoYeah, 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 14y agoThat 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.
- vjeux 14y agoIt'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 14y agoYeah, 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.
- deleted 14y ago[deleted]
- sjs 14y agoYou 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.
- jrockway 14y agoA 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.
- iso8859-1 14y agoHere's how Emscripten does it: https://github.com/kripken/emscripten/blob/master/src/shell.js#L11 https://github.com/kripken/emscripten/blob/master/src/shell....