The situation went from bad, to worse, to the best possible outcome, and that's remarkable to say the least.
Congratulations to everyone involved and thank you for the hard work.
The situation went from bad, to worse, to the best possible outcome, and that's remarkable to say the least.
Congratulations to everyone involved and thank you for the hard work.
Documentation is quickly out of date, libraries seem to have incompatibilities which only become obvious when they don't work, there's no 'recommended' approach for even basic tasks.
I won't pretend I'm speaking for everyone, as clearly there are lots of people doing great things with Node. However, it doesn't seem to be a language like Ruby or Python where I would feel comfortable using it for a small but important project.
I'm always grateful to everyone who works on open source projects, but I wouldn't hold Node up as a great example of the open source community.
The future has never looked more stable for Node, just take a peek at the names of the companies sitting on the board: https://nodejs.org/en/blog/announcements/foundation-elects-b...
This doesn't make sense in light of your initial comment. One of the big goals of IO was to move to semver and address unpredictability/instability that you describe.
If anything, the merging of Node and IO should give you confidence that project governance will be on the right track moving forward.
Also, when you consider the advancements in transpiled js, the js/node community is looking very wise compared with other language maintainers.
And of course they failed right from the start. From semver.org: Version 1.0.0 defines the public API.
So their jumping to 4.0.0 from 0.x.x means they don't care to have a public API!
See https://github.com/nodejs/node/blob/master/CHANGELOG.md and search for 1.0.0
As for no recommend approach - that's deliberate. I don't think most people working on Node want a Rails equivalent.
Perhaps Go is a better comparison than Ruby and Python.
Isn't that true for many platforms?
Either way, I have multiple apps running Node in production, and I've never had the issues described. You don't have to be as breakneck as Node itself - some things I have are still running v0.10x just fine.
I would say that the ROI is lower for time spent learning Node. I've found that with all the other languages I've learnt, in a couple of days I've been able to build something useful, leave it running in production and reuse skills learned a year later.
With Node, even the name of the language is not stable! A few weeks back I went to install Zombie, and now I have to install iojs and not Node. Assumedly it's now Node again. If you live and breathe the language, subscribe to the mailing lists, go to the meetups, etc, these things might be obvious. But when you're just dipping in and out, it really dents your confidence in the language.
I'd agree with your first paragraph in that Node is a bit lower-level out of the box and probably takes more effort to get started building a web-app, but I think the time invested jumping in at that low-level is actually useful vs diving in at a higher 'framework level' with some of the other popular web languages.
Also it does have superior installer/package-manager/deployment stories compared to say ... Python & Django, which does have an impact on ROI.
One of my main use cases for Node is Zombie, and that required io.js after v3. No mainstream PHP, Ruby or Python application has required a different interpreter.
So jsdom 3.x used a lib called "contextify". When io.js was released and the changes included, node support was dropped. Now node 4.0.0 is out and has those changes, jsdom now works on node again.
I see things like this all the time and it really puts me off OSS.
It's not just Node itself to blame. There seems to be a culture of breaking things in the Node.js ecosystem. Breaking changes in third-party libraries are common. I have to specify exact dependency versions in my package.json, and almost every time I update one of them, something goes wrong.
That's where semantic versioning comes in. Most libraries follow it - if the major version number changes, it's a breaking change. If it doesn't, you're safe to upgrade.
There are some major libraries that are on version 15 or greater... there's nothing good from a user's perspective about having a library they use do a major breaking release every other month.
What's worse is many libraries take advantage of "it's the wild west until 1.0" rule in semver and simple never release a 1.0.
I contrast this with node/npm where my projects seem to behave identically across deployments (and in some cases, when in a bind, I've even been able to simply tar & scp the project src and have it run without further effort beyond installing node, something I've never been able to do with ruby).
I'm amazed. A single module had to be bumped (Elasticsearch@8) while we directly rely on 50+ third party modules... Our npm-shrinkwrap is 2600 lines long.
That's not really a sign of instability to me, but rather great work
NPM is a very powerful tool. In fact, it's our deploy tool: we run `npm install` on servers (private Sinopia npm repository) to deploy. But to do that, you must follow many many rules that are written nowhere.
Our first major improvement to this work flow was a tar of the app with all of the dependencies coupled with `npm rebuild` after unpacking. This worked quite well.
However, recently, we have switched to using Docker to generated this sealed packages which is working great.
Our NPM workflow also ensures builds are easy to replicate. Most problems in development occur because of obsolete versions of some packages (our apps contain many private modules)... Clean npm-installs shields us from that in production.
We try hard to keep our dependencies up to date to limit the risks of an upgrade. We progressively apply dependencies updates to dev->staging->sandbox->production environments.
Was I worried when node.js forked? sure! but the situation is much better now. I think node.js can move forward smoothly now.
This is a useful way to understand what Node is. Node's core API is for building any sort of network service: A DNS server, an SMTP server, HTTP server, socket listener, etc. and so it applies to a wide and varied set of problems. Rails is for building a very specific type of database-backed web application.
I'd argue only Erlang and Elixir are going to survive into the multi core multi server future, but that would be little more than a slightly educated opinion unless I take the time to write a very large explanation with cited references. I don't have time for that this week.
I think what's holding Erlang back is mostly its rather obscure syntax. Only a mother could love that.
It wouldn't really be possible anyway. Async programming is hard and the shortcuts one can take with synchronous Ruby are impossible with Async Javascript. Nodejs has a "fibers" lib though , but it doesn't look like it is widely popular, but AFAIK it is the only to truly abstract async programming.
var user;
try {
user = yield db.insertUser('foo')
} catch(err) {
if (err.code === '23505') {
this.flash['error'] = 'Username taken';
this.redirect('/register');
return;
}
throw err;
}The thing is that people are actually using Koa/co to solve this problem. I've yet to see someone use fibers as their core webapp control flow abstraction.
A great essay on this is "What Color is Your Function": http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y...
https://github.com/petkaantonov/bluebird/blob/master/API.md#...
There are plenty of libraries that provide whatever level of support you want, but one big reason people seem to use Node is for the ease of the DIY process. Honestly, I don't need an all-in-one system, because my system has needs that aren't easily modeled in ActiveRecord (or at least weren't during Rails 3 days when I moved over to Node). Instead, I am doing mix-and-match with smaller libraries to help database access, realtime (websocket) services, OAUTH, and a trad REST backend.
I also think it's fair to compare the release of node and the release date of ruby or python - it was really only then that we can start talking about needing frameworks for building web applications that run in the javascript language, whereas the other two languages could have done so right away (or ... later, once the web application world became more than just a cgi gateway on top of a c++ stack, like the lunch menu randomizer I had running back in 1995). Still, no matter how you slice it, node and server-side javascript are still relatively new on the scene, and not necessarily well-suited for an all-in-wonder, highly-opinionated framework.
Actually, no, it didn't. JavaScript was first introduced "on the server side" about 20 years ago in the Netscape web server[1].
We learn from history that we learn nothing
from history.
George Bernard Shaw[2]
1 - http://docs.oracle.com/cd/E19957-01/816-6411-10/getstart.htm2 - http://www.wisdomquotes.com/quote/george-bernard-shaw-19.htm...
Node was in part influenced by CommonJS, which tried to unify the various competing but relatively obscure (mostly non-browser) JS environments. To say that it learned nothing from the history of SSJS (or JS environments in general) is, frankly, wrong.
That said, Netscape's SSJS is entirely unrelated to Node or anything like it[0]. Node lets you write application servers, Netscape's SSJS effectively was more like Rhino-meets-JSP or maybe GWT (i.e. the heavy lifting was apparently implemented in Java, not JS).
[0]: http://docs.oracle.com/cd/E19957-01/816-6411-10/jsserv.htm
The JS of 2009 was an entirely different language
from the JS Netscape originally created. Plus
Netscape's web server was an evolutionary dead end
and a proprietary closed-source product.
The reason I cited Netscape's server was to unequivocally show that NodeJS did not introduce JavaScript to "a new environment" as the GP stated. Why previous efforts failed to gain traction or if it is even a good idea to use JavaScript to define server-side logic is left as an exercise to the reader. Node was in part influenced by CommonJS, which
tried to unify the various competing but
relatively obscure (mostly non-browser) JS
environments. To say that it learned nothing
from the history of SSJS (or JS environments
in general) is, frankly, wrong.
It would seem we have differing perspectives of history. CommonJS was started in 2009[1], the same year as NodeJS[2]. The lessons of history I implied regarded attempts to use JavaScript as a server-side solution over the past 20-ish years. While you make the distinction: Node lets you write application servers,
Netscape's SSJS effectively was more like
Rhino-meets-JSP or maybe GWT (i.e. the heavy
lifting was apparently implemented in Java,
not JS).
I suggest that this is irrelevant, as the details of how the JavaScript logic is executed is orthogonal from the fact that systems such as these use JavaScript to define behaviour itself. The fact remains that there have been more than one previous project/offering/effort which had JavaScript as a key component. IMHO, it behooves interested parties to do whatever postmortem examinations possible before committing to the same or significantly similar path.Node is for writing small standalone services. Netscape's SSJS was for creating dynamic web pages -- just like CGI scripts or (at the time) PHP.
SSJS may be considered prior art for "JS on the server" but it's barely recognizable. As far as I can tell the execution was entirely synchronous; but Node is defined by its evented -- and therefore asynchronous -- I/O. It's a data point for comparison but it's not a good lesson to learn from, other than what not to do.
A lot of the shortcomings of Node come from the limitations of JS at the time. Callbacks and streams (arguably two of the biggest issues with Node) are a result of Node being asynchronous. At the time, event listeners and callbacks were the best tool JS offered and the best thing the JS community had.
I can only imagine you're trying to say that Node should have taken more inspiration from other languages that solve problems better (like gradual typing, or the Maybe monad or the actor model). But none of this has anything to do with Netscape's SSJS.
You explicitly point out Netscape's SSJS as a part of history Node should have learned from. What specifically do you think Node should have learned from it? Are you just trying to say "SSJS is a bad idea (because Netscape's SSJS was bad) and shouldn't have been attempted again, even in an entirely different way"?
[0]: http://stackoverflow.com/questions/18350910/netscape-enterpr...
Just different importance discerned from the same post IMHO.
This has nothing to do with the parent comment about node deliberately differing from rails, it's typical hn/reddit pedantry.
I'd use it for a personal project, or hackathon, but I'd be really cautious of developing mission-critical software in it.
Not sure about your problems with node and the 'massive instability'issues you've had, or if they are related to a third party library and not the Node core.
The leading 0 denotes probable instability in the API that devs are willing to take the risk for and act upon.
You're familiar with SemVer, aren't you?
With Node for core and basic problems, I find myself thinking "Should I follow this blog post written by a highly respected developer but which is a year old and therefore forever in Node-land, or this blog post written last week by a nobody?". I don't like thinking that way about production code I'm writing for clients, so I use languages where I don't have to think that way.
Perhaps using a framework would make things easier, but I'm reticent to rely on it in the main part of the project when it causes so many problems just in the small parts.
Your previous comments address the paradox-of-choice idea, but the uncontroversial path in Node is to 'just use Express' right? How it that a worse situation than in other languages where there are also trendy frameworks competing against the default option. You name PHP as a better situation but from what I gather PHP is even worse at casting off legacy frameworks. Laravel is the new trendy, whereas it was CodeIgniter/Symphony before that and EE/Wordpress before that. And in Ruby, there's similar competition over an alternative to Rails [0].
[0] https://blog.engineyard.com/2015/life-beyond-rails-brief-loo...
A more recent example comes from Zombie, which I use for functional testing. When they moved to v3, they required io.js instead of Node. So eventually I decided to go with Zombie 3 and moved to io.js, but then another library broke which required Node instead of io.js.
They're the two big ones that stand out, but there have been lots of other small annoyances.
So, if you think that Ruby or Python could get things done for you and you're very familiar with them, go for either and get it done but to pick on Node just because you don't quite grasp its inner workings is really odd of you and the whole reasoning behind your critique is rather absurd.
Having said that the IO split has been a royal PITA. We got pegged to Node 10.x because JSDom only supports IO and Jest (which is what we wanted JSDom for) only supports Node :-P. I've been waiting a year for it to get cleared up.
It sounds like we made the right choice, though, because in this thread the people who are complaining about Node seem to be the ones who tried switching back and forth between IO and Node. There is actually only one bug in Node that has impacted me (related to the way connections are shut down) and it isn't fixed yet in master so not upgrading hasn't really impacted us. We just have to live without some of the ES6 features.
Personally, I'm a big fan of Go (old C++ programmer). We started using it a little over 2 years ago. The language definition has changed in that time, so I wouldn't call it stable ;-) The core libraries are rock solid, though. We barely use any 3rd party libraries (I think we use 2) so it's not really fair to compare that with other languages.
Although we have a fair amount of python in our shop, I don't seem to work on those projects very much (a month here and there). I can't say too much about it other than our Python code breaks due to 3rd party libraries more often than any of our other code. However, I think this is probably due to injudicious choices for our 3rd party libraries ;-)
Overall, I would say that my experiences don't match yours, but I wonder if it's because we never tried moving to IO.
It seems that you don't like Node and are intent not to use it. I respect that and am not trying to push it. I think asynchronous programming in the reactor pattern is a good solution pattern for many types of problems, and Node.js is a solid application of that pattern. But it certainly is more complicated than synchronous programming in the kinds of environments you listed.
I do wonder however what compels you to shit all over a thread celebrating a project milestone with an opinion that comes from an admitted lack of knowledge.
I am using this discussion as a means of saying "here's what I think Node needs to get more people using it in production". My opinion is that they need to do more work on stability of the API, and improve documentation, to win over us enterprise types who value long-term stability over short-term features.
My opinion? You probably should withhold your judgement of the "open source community" if you only have superficial knowledge about their efforts.
Asynchronous programming a la Node (with callbacks etc) is an anti-pattern.
We've had better ways to handle that for 4 decades now.
It would make your comment much more helpful, IMHO.
People associate threads with shared-memory concurrency, which can be really hard to deal with, but shared heaps are not the important part - blocking is.
Blocking threads means that all your functions can call each other, all control flow constructs just work, and debugging is sane. With blocking threads functions don't need to belong to a special class of async functions that in general need to be called from other async functions.
It would have been great if node invested in allowing many concurrent blocking JS threads. To see what that could have looked like, see Dart's Fletch project: https://github.com/dart-lang/fletch
Generators are just iterators, and are synchronous. The consumer asks for a value with next() and the value must be computable (even if that value is a Promise).
If you have an async function (one that returns a Promise or in the future a Stream), and you need to call it from a sync function, and somehow incorporate the future value into the return value of the sync function, you're stuck. You have to async-ify your functions all the way up the call chain.
With blocking this isn't a problem. We just need environments that make blocking cheap.
As for "having to change an entire call stack", that just stopped happening after a while. The rule of thumb was that if the function is impure (e.g. relying on mutable state) then it will likely become async, too. That lets me plan ahead.
While I am not certain what the GP specifically references, I can say that about 40 years ago the Actor model[1] was officially documented. The literature documenting benefits of an Actor model over a callback approach are easily found. For understanding the pain which callback-based systems often produce, a person can familiarize themselves with the Win32 API (disclaimer: this is a masochistic exercise not recommended for anyone).
1 - https://www.cypherpunks.to/erights/history/actors/AIM-410.pd...
The flexible experimental approach inevitably conflicts with the constraint of back-compatibility (e.g. of x86, java).
Node seems more like the Drosophilia-like JS frameworks.
- Python: 24 years old
- Node: 6 years old
Maybe your comparison is somewhat unfair...
- language
- io loop + vm
- language + environment + ecosystem
- language + environment + ecosystem
It's fair to say Ruby didn't take off until 1.8 which came out in 2003, but how in any way is Node 20 years old?
Documentation is quickly out of date, libraries seem to have incompatibilities which only become obvious when they don't work, there's no 'recommended' approach for even basic tasks.
--
Do you have examples? My counter to your anecdotal evidence is my own--we've successfully built and managed multiple projects in production, that service millions of customers, which were written in nodejs, and have been doing so since 2013. The issues with Io led to no discernible conflicts to our businesses.
If you're reading the mailing lists, going to meetups, etc, these things might not seem like huge issues. But if you're just trying to run a small Node project as one amongst many bits of software in many languages, Node causes a disproportionate number of problems.
I've given a couple of examples below - Zombie switching to io.js, and the whole self-signed certificate debacle from a couple of years ago.
Node has its place, and it's not for everything, but for quickly whipping together sturdy, flexible web APIs, it's great.
Not sure if this is what you meant, but I read the ancestor comment not as being about "will the process crash randomly?" but "will an upgrade break something in my app?"
It's just that I've seen whole comment threads go by with people tripping over this misunderstanding without ever acknowledging it.
npm coupled with drastically and frequently changing libraries (and transitive dependency clashes) does make a hell of a dependency mess; I agree.
But, on the plus side, most node libraries are easy to modify. In fact, I have a private repository full of github forks that I've had to make over the years (and not had the time or patience to submit pull requests). Luckily, npm supports private repos easily.
Really? I mean, you probably could have made any other point and have it hold even the slightest amount of water.
OK, let's help you out on finding some good documentation on Ruby:
http://ruby-doc.com/docs/ProgrammingRuby/
https://en.wikibooks.org/wiki/Ruby_Programming
http://mislav.uniqpath.com/poignant-guide/book/chapter-1.htm...
Module are dynamically included. Methods are dynamically generated. The generation static document can only give a partial view of the running objects.
[1] - https://nodejs.org/api/http.html#http_http_incomingmessage
I am so glad that gcc got its house in order. As a bonus the compiler got significantly better in pretty much all the ways it could (at least for users, no idea about internals.)
These interactions strongly mimic the interactions of the market. What's the true driving force?