I've always been a bit annoyed that there are two major realms of javascript projects -- Node and "the browser" -- and while most browser JS can be easily run inside Node with a couple libraries for DOM stuff if needed, porting Node stuff to the browser is usually an afterthought.
This all seems like a lot of wasted energy on the part of developer communities, which could be alleviated by all JS developers just developing for the "least common denominator" (the browser) and using various shims to use features only available in Node or other JS environments besides the plain old browser.
This would not only cut out a lot ecosystem cruft and make development-in-the-browser more realistic, it also makes it commonplace to give the browser superpowers…Look for example at browserver, which sets up an http server inside the browser, but because the browser cannot actually accept http requests, uses websockets to talk to a proxy Node server that can.
So I want to ask, what are the real technical constraints of a web browser's javascript environment versus Node?
I thought Node was just "a javascript environment, plus http server and local filesystem, minus the DOM and the chrome". Are there technical reasons why developers could not potentially move to the approach I described above, developing for the browser JS environment (does this have an official name?) and using shims for Node?
Code that runs on the client usually have very different goals from the code that runs on the server. However when it makes sense to use some libarary's features in both environments there are a lot of them that are defined using a universal AMD form which makes them platform independent (e.g. Q).
The major difference between both environments is that one is subject to rigorous security policies and restrictions (browser) while the other isin't. The browser is also an untrustable environment for security-related operations such as enforcing security permissions.
I'll also add #jfriend00 comment in here since I believe it's also very relevant a exposes other differences:
The biggest practical difference is that you have to design a browser
application to work in an installed base of existing browsers
including older versions (lowest common denominator). When deploying a
node application, you get to select the ONE version of node that you
want to develop for and deploy with. This allows node developers to
use the latest greatest features in node which won't be available
across the general browser population for years. #jfriend00
Projects like browserver are interesting and I am all for experimental development, but are they truly useful in practice? Libraries should be designed for the environment in which they are truly useful. There are no benefits in making all libraries available in both environments. Not only that it will generally result in an increased code complexity, some features will sometimes not be shimmable resulting in an inconsistent API between platforms.
Here are some of the differences between these two environments:
Node.js has built-in libraries for HTTP and socket communication with which it can create a web server and thus be a replacement for other types of servers such as. Apache or Nginx
Node.js does not have browser APIs related to DOM, CSS, performance, document, as well as all APIs associated with the "window" object. Precisely because of the lack of a window object, the global object was renamed "global".
Node.js has full access to the system like any other source application. This means it can read and write directly to or from the file system, it can also have unlimited network access, and it can execute software...
Since the development of JavaScript is moving very fast, browsers often lag behind the implementation of new features of JavaScript, so you need to use an older version of JavaScript in the Browser, but this does not apply to Node.js, you can use it all modern ES6-7-8-9 JavaScript if your version of Node.js supports it.
Although within ES6 there is a syntax for working with modules (import/export syntax), it has only recently been added to node.js as an experimental option. Node.js mainly uses CommonJS syntax to work with modules.
Related
I'm beginner to MEAN stack, while studying NodeJS, I'm came up with the following statement that's taking my mind
Node.js is a very powerful JavaScript-based framework/platform built
on Google Chrome's JavaScript V8 Engine.
but what exactly does it mean by
built on Google Chrome's JavaScript V8 Engine.
and if it's built on Chrome's JS V8 Engine, why does it works on Firefox as well?
MEAN stack, reorganized from back to front:
MongoDB: data persistence, stores data for later retrieval
Node.js: web application server, responds to requests from clients
Express: web application framework, reduces Node boilerplate
Angular.js: browser framework
So Node.js does not "work on Firefox" (it doesn't work on Google Chrome either): its a server-side technology. Think of it as a replacement for Python/Ruby/Java in that role. So it can/does respond to requests from all sorts of clients (like Google Chrome and Firefox).
What the "built on V8" means is that it uses the same JavaScript interpreter/just-in-time compiler as Google Chrome. But the similarities with chrome pretty much stop there: Node has no rendering engine/css parser/DOM but does have things you need in a server like an HTTP library and a filesystem API.
Also, and I mean no offence: we all started where you are, the fact that you are even asking the question (which again is not a bad thing!) means that building on a stack like MEAN is over your head. The documentation is going to assume that you know things you seem to not know. I strongly recommend furthering your understanding of JavaScript and Node through some tutorials and barebones test apps before trying to throw databases and frameworks into the mix.
In order for a programming language to be executed by a computer, it needs to be translated into a format the machine can understand (generally termed machine code). Javascript is no different. When your browser is presented with Javascript code on a website, something needs to compile or, in the case of Javascript, interpret the instructions into machine code.
V8 is the program that was developed by Google to do exactly that. When you use Chrome and it detects Javascript on a page, it passes it to V8 to run the compilation and then your computer executes the resulting code.
V8 was open sourced by Google. The creator of Node, Ryan Dahl, modified the source code so that V8 could be used outside of Chrome and inside an operating system like Linux or MacOS. That is what is meant by your first quote.
The important thing to note here is that you do not execute your Node programs in a browser but rather with the actual computer you are using. There's no correlation between V8 and Firefox, Safari, IE, etc. All of those browsers have their own Javascript interpreters.
Ok let's get through this:
Node.js is a very powerful JavaScript-based framework/platform built on
Google Chrome's JavaScript V8 Engine.
JavaScript is a programming language used in internet browsers. It was invented in 1995 by NetScape, I think, and has been submitted to a certification organization called ECMA in 1996.
ECMA has taken the original idea of JavaScript and made a standard called ECMAScript which each JavaScript implementation should follow. You see, JavaScript is not a language that just exists somewhere in the ether - each internet browser comes with it's own implementation of the language - this means that JavaScript usually only works in internet browsers such as Mozilla, Safari, Opera or Chrome for example. (Internet Explorer also comes with an implementation of ECMAScript but they call it JScript for licensing reasons I believe)
The implementation of JavaScript that comes with Google Chrome runs on the powerful V8 engine which is written in a language called C++. V8 interprets your JavaScript code and provides it all the variable types, manages memory etc. The great thing about V8 is that it is open-source and can be embedded in any other C++ program.
So the creators of Node had the idea of taking V8 and enhancing it by adding features that a server needs to serve websites - reading files, responding to requests, routing etc. This means that it is now possible to program the server-side implementation of a website using JavaScript thanks to the Node.js application that interprets your code and essentially translates it to C++ and later machine code further down the line. The important distinction is that Node.js DOES NOT run in your browser! It runs on a server much like when you code the back-end using PHP and apache.
V8 Engine is an interpreter for Javascript used in Google Chrome.
The statement that NodeJS is built on top of this engine means that it uses this interpreter for it's own thing, so it can also be used on the server, not just in the desktop environment (like in Google Chrome).
NodeJS is a separate application that you can communicate with over the internet, it's like Apache, Nginx or similar, but it's not used for one thing only (like the ones mentioned), but it's mostly used for making web-server like applications.
Node uses the same JS "engine" that runs chrome.
An engine in this case, is a piece of software that compiles, or "translates" your JS code into machine code; or the 0s and 1s your computer can understand.
This compilation is a complex process, and there are a few different approaches to solving it, for example google's v8 or mozilla's spidermonkey. Each of these support the entire JS standard (to a certain extent), i.e any JavaScript code can run on them.
When you run a node server, it runs on a machine that acts as a server. The code is not run on the user's machine at all; hence it doesn't matter which browser is used to view your content.
In the MEAN stack, it's angular code that runs on the user's computer. However, it is written in JavaScript, which can be run on any javascript engine.
Node.js is JavaScript on the server. For example, you can start a Node.js server on http://localhost:8000/, and you can access it with Chrome or Firefox.
Using Node.js (which uses V8), servers can be written in JavaScript rather than PHP or Ruby.
Actually NodeJS is cross platform server side framework. You might know as it is best suited for I/O bound and Data Streaming Applications, it uses Google Chrome's JavaScript V8 Engine for above mentioned purposes
So it's independent of browser and platform.
How to run compiled files directly using Google Native Client (PNaCl)? It tried checking their documentation. It said that -
Native Client is a sandbox for running compiled C and C++ code in the browser efficiently and securely, independent of the user’s operating system.
But in their documentation, they only deal with sources of the application. Is there any way to run compiled code directly? I want to run files with .exe and .deb extensions
I'm not limiting the answer to Native Client. Any mechanism which can do that sort of work will work for me.
You can't run pre-compiled code within NaCl or PNaCl. You have to use the compilers provided by the SDK. There are three main reasons for this:
NaCl is an execution sandbox which relies on crafting machine code (x86-32, x86-64, ARM, MIPS) in a very particular way. This is regular machine code from the CPU's point of view, but allows the sandbox to run a validator and make sure that the code can't do anything malicious. This is called Software Fault Isolation, and is explained in this paper. The other ISA sandboxes are also documented.
PNaCl targets NaCl, but is an architecture-agnostic intermediate representation. This means that you ship what can be thought of as bytecode, and the browser figures out which type of machine code (x86-32, x86-64, ARM, MIPS) to generate based on the user's machine. The developer doesn't generate 4 binaries.
In both above cases, the code can execute as-is on Windows, MacOSX, Linux, ChromeOS, and (while not usually shipping) Android. This means that the NaCl sandbox presents itself as an operating system, and offers the same APIs. These APIs are different from other OSes, though they're pretty close to POSIX especially if you use nacl_io.
The above points require that you use the compilers provided by the SDK.
It is technically possible to run binaries built for other architectures or operating systems since the system is Turing-complete. That's what QEMU does, what Rosetta did, what Transmeta did, and what the Android Runtime for Chome (ARC) enables. This usually requires binary translation and emulation of all operating system calls. This is technically difficult to implement, and often has severe performance cost. I do not recommend exploring this option.
As #JFBastien pointed out, emulation is the only option to execute pre-compiled native code in the browser environment. But it is an option nevertheless. Depending on your demands on performance, it might even be a viable option.
Click here for example to boot up an emulator running Windows (a very old version though) in your browser.
From the menu pick, for example, notepad.exe (using the cursor down key on your keyboard) and hit enter. There you have it: an unmodified, precompiled, native notepad.exe running inside your browser! (and probably even faster than back in the day when this OS was new).
There are a lot of emulators written in Javascript all around the web. Running a small Linux distribution with usable performance and even with networking(!), graphics and sound is actually possible. Check out the OpenRISC emulator. You can even run an ssh daemon and log into it from your local machine!
I'm working with a team on a TypeScript librabry called Classical.js, and we would very much like the core module of this library to be JavaScript environment agnostic. In my mind, that means it should not only function correctly cross-browser, but also as a dependency in a node.js project.
First of all, am I missing any major JavaScript environments in my test matrix that I should be aware of?
Unfortunately no one on the team develops with node. Therefore we're not quite sure what APIs to avoid (obviously the DOM) to ensure compatibility. Are there are a standard set of GOTCHAs that node developers run into when using code that has only been tested in the browser?
One discrepancy that we did (hopefully) account for the name of the global scope, which, if memory serves me correctly, is represented by an object named global in node and window in the browser. These are the sort of GOTCHAs that we are looking for.
I think you have an important issue here, one that that's currently underexposed: you want to create an isomorphic library, and you want to know which libraries you depend on are isomorphic. I think it would be a good thing when isomorphic modules would be clearly marked as such in for example npm.
There is a nice blog on this topic here: http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/
Basically, isomorphic libraries should only use functionality build in JavaScript the language itself (ES3, ES5, ES6, ...).
You should avoid anything related to the DOM (window, document, navigator, ...), as this is only available inside a browser environment.
Many core modules of node.js cannot be used in a browser (like file system, os, process, network, streams, etc). For many core modules there are browser safe versions available (for example for crypto and http). Browserify uses these versions when bundling a node.js app for use in the browser.
There are a lot of JavaScript engines out in the wild, implemented in all kind of languages like C, Java, Python, etc. Also running directly on hardware like Espruino. These engines may not be 100% compliant with the language specs. For example, I encountered one day that the JS engine in Java (I think it was Rhino) didn't like a variable to have the name boolean. In these cases I would argue that these engines should get better compliancy rather than you having to work around their bugs/limitations.
Anyway, there is an easy way to test whether your library is isomorphic: try to run it in both node.js and the 5 biggest browsers :)
What are the major differences between the Netscape Enterprise Server implementation of Server-Side JavaScript (SSJS) and the node.js implementation?
Why did not Netscape's implementation gain attention while the node.js seems to be far more popular?
Back in 1999/2000, I used to work at a company that used Netscape Server and SSJS. I don't know how popular it was at the time, but from first hand experience, I can tell you that almost everything about it was terrible:
It was a giant pain to debug (any changes to source files, even static files, required full reloading of the application, which was not a fast operation)
A simple error (such as an uncaught exception) often would lead to catastrophic server failure. Somewhat amusingly, this is the default behavior of NodeJS, although it is much easier to get around this problem with Node.
Although the syntax was JavaScript, it failed to implement one key advantage of modern JavaScript: runtime interpretation. Server Side JS with Netscape Server required compilation before deployment, and therefore dictated a very slow development process.
It followed a multi-threaded execution model (rather than modern JS VMs, which are almost always event-loop based)
Possibly it's biggest weakness was a lack of asynchronous programming support. All IO operations were blocking, and as such it required a heavyweight multithreaded model to support multiple clients. The execution model was more similar to a J2EE container than to modern event driven JavaScript VMs (ie: V8). In my opinion, this is the number one thing that NodeJS gets right: the async philosophy is deeply embedded in the NodeJS development workflow and it is the key to its lightweight, event driven, extremely efficient concurrency model.
Just for giggles, here's a link to the SSJS reference guide from version 1.2 . Starting on page 21, you can see all the standard functions and synchronous APIs for file objects, database queries, etc...
My company ended up switching to ColdFusion shortly thereafter and never looked back.
The main difference would be the evolution of Javascript over the the past 15+ years. Node.js uses the V8 Javascript Engine which would be far more optimized for modern computers.
Wikipedia has a good list of the differences between various server-side JS solutions.
Here is a list of features for Netscape Enterprise Server - provides a good idea of what makes modern SSJS solutions much better.
Why did it not gain attention? Realistically, client-side JS has only recently started to become the standard for web development so it was unlikely anybody would have considered using it for server-side development when it wasn't even really widely adopted for it's original purpose. I say widely adopted in that previously it was always difficult to cater JavaScript solutions to all browsers.
I'm trying to find a (preferably open source) JS library to determine as much information as possible about the user's Web browser environment. I know it's possible to get such data as:
Screen resolution,
User-Agent, Accept-Language and other preferences usually sent in HTTP headers,
Installed plug-ins (through navigator.plugins),
Whether a particular browser feature is supported (SVG support, DOM capabilities)
What I'm looking for is a library which gathers such information and makes it available under a common cross-browser interface (there are a bunch of incompatibilties in how browsers report installed plugins, for example). I found Modernizr which can detect HTML5-related functionality, but similar projects which report more generic information, such as the data listed above, would be more useful.
I maintain Common Feature Tests project, but it is merely a set of feature tests online, not a library. Feel free to use any of them on your page.
Sometimes I also use this simple test page for testing unknown environments (all tests there are really trivial one liners).
You should definitely check out Panopticlick, an academic study (with detailed explanation on theory, and supporting data) to determine what makes a browser installation unique.
Panopticlick uses a slightly outdated version of this plugin detection script...