Yahoo Mail moving to React
slideshare.net
slideshare.net
And those who say Yahoo! are just jumping onboard the React hype train or Node.js hype train, you have it all wrong. Yahoo! have been using Node.js for the last few years, in-fact early 2010 is around the time Yahoo! engineers started playing with Node.js, long before it was considered mainstream cool or being used really in any high-profile scale environment.
It is rare that a company the size of Yahoo! truly ever embraces moving at this kind of pace and embracing new open source technologies, languages, frameworks and libraries. Now that Yahoo! have openly declared their use of React on such a large scale, expect it to explode even more so in 2015. For an open source project that is a little over a year old, React is getting the kind of user-base and adoption that most open source projects can only dream of having.
This news excites me. I honestly cannot wait to see how it all turns out.
PS. I have noticed a few people in the comments section getting confused. Yahoo! Mail is NOT using React just yet. The current mail product is still using YUI and plain HTML/Javascript. If you read through, it mentions 2015...
Another option (albeit currently an undocumented one) is to use contexts to obviate the need to pass things down manually: http://davehking.com/2014/11/15/introduction-to-contexts-in-...
I am really too stupid to get it. "Single language for a whole stack" is a pretty stupid Java-sque argument, a naive assumption that one single language is good for all kinds of tasks.
Sharing code between client and server lets reduce duplication and use the same templating/rendering on both sides. Fits very well with complex single-page apps.
That said, I'm not sure there are that many apps that really need this vs. the tradeoffs you have to make going all-in on JS and the complexity this can bring.
I'm writing apps from the ground up using React and I've found the isomorphic bits take <10 lines of code as long as you design for it from the start.
As for blocking, it's something you deal with. Realistically speaking if you're doing CPU intensive tasks then Node is definitely the wrong solution. However, if you're doing tasks that are IO oriented then Node is fantastic.
Here's the answer:
Spawn $(nproc) more Node processes, use IPC if you need to.
Good luck seizing the theoretical performance gains one might see from threading (while not falling victim to diminishing returns related to context switching) in another comparable language.
For stateless web requests (solving the C10x problem), this is not inherently bad for most applications.
> which blocks the whole app if a single function blocks
This is behavior you'll see in many other languages.
Management of execution time is very prevalent in lower-level languages. The only languages not susceptible to this problem are high-level, preemption-capable, and possess some form of green threading/scheduler e.g. Erlang/Elixir.
IMO, if you need to rely on a scheduler to help ensure that blocking doesn't occur in a disruptive fashion, you're in no position to deride those who "began as a webdevs and knows nothing better."
> asynchronous call-back hells
This is a matter of taste, opinion, and necessity.
I personally hold the opinion that "callback hell" is a symptom of poor design, and properly managed callbacks are not unpleasant to work with (I may be subject to Stockholm Syndrome).
Also, try implementing an equivalent non-blocking webserver around an event loop in a lower-level language and let me know what non-callback strategies you come up with for the coalescence of asynchronous events.
As an aside, there are hundreds of different ways to improve or eliminate the composition of callbacks in JS: emulated coroutines via generators, C#-style implementations of async/await, promises, the list goes on.
> non-functional but GC'ed language
Which functional programming languages in common use aren't garbage collected? (again: in common use)
Which other common, productive, high-level programming languages (often tasked for C10K web servers) aren't garbage collected?
What does "non-functional but GC'ed" actually mean? What does the language's programming paradigm have to do with its memory management model in this context?
> I am really too stupid to get it
- People are productive and enjoy JavaScript. - Browsers, by and large, only run JavaScript code. - JavaScript on the server-side is a very capable, battle-tested building block for performant web software. - Admittedly: JavaScript is not a great language when compared to other modern programming languages. - Aforementioned opinionated gotchas aren't enough to dissuade communities from using JS.
If you have broken your code up into small enough modules and functions, and you know which tasks depend on other tasks, you will not have callback hell.
If you are unclear on the logic of your code, you can often make it work in a messy way with the "laundry list approach". This involves formulating a sequence of tasks that happens to work, without needing to understand the actual dependencies. Many synchronous languages facilitate a laundry list approach, as their inefficient blocking paradigm removes the need to formulate the laundry list as a sequence of nested callbacks. It's still messy code.
No. It's an indication that you're using a FOTM runtime environment. There's a reason why no production-ready runtime uses continous passing / callback models.
Or any of the other top-end (in requests/sec) webservers?
Hint: they aren't utilizing green threading and/or a scheduler.
Weak types: Check out Facebook Flow or TypeScript.
Global namespace: Not true with require/modules.
Ambiguous/unexpected behavior... please explain? You could use any number of libraries to add consistency there. It's incredibly easy to include a JSLint file in your repo and as a git hook to ensure consistent syntax usage. ES6 introduces lots of nice features for writing code, and is usable today with transpilers.
For frontend development, a lot of frameworks and libraries only work consistently with Javascript. I've looked at TypeScript for instance, and it indeed looks nice. But it has a bunch of edge cases with Angular and/or Backbone. You're just piling on complexity with these languages.
But you need to write your frontend SPA with JS. And the isomorphic part, if designed from the ground up adds almost no extra code. So, really it's almost free to render first with Node, if you're starting a fresh SPA. I don't see why you wouldn't want to do it.
And we can all agree the ES5 has some warts, so you may as well transpile. Whether it's ClojureScript, Coffee, Type, or anything else doesn't matter, I just think it's a problem solved. Webpack makes debugging them easy with sourcemaps and live-compilation. In fact you can get hot-reloading[1] in React. So your app re-compiles without reloading.
I'm happy with ES6 + Flow. It's all ES6 syntax anyway, works with all libraries, and is fast to write, good looking, and functional.
Given JS has first-class functions, and many libraries to follow functional patterns. You can write very stable code, with almost no chance of side effects within a given function/context.
I did, on the other hand, have to take over cobbled together jQuery, Backbone and Coffeescript applications.
Yahoo is writing a greenfield application, and they are avoiding exactly those problems by using React. So, literally your pain point is exactly what they are writing about avoiding, and yet you still comment on this article with the same anti-JS nonsense.
JS ecosystem is confusing. See: https://news.ycombinator.com/item?id=7074307
Utilities should be a part of the language's "battery".
Ambiguous/Unexpected behaviour: I mean I can redirect you to the popular "Wat" talk. Moreover, isn't that the entire premise of "Javascript: The Good Parts" anyway?
Also, it compiles to CommonJS, which means it works well with both node and browserify.
Yes, we need a blessed, "batteries included" stack for JS made of components that play nicely together. Here is a nice list to get started with (IMO, ymmv)
1. TypeScript or Flow
2. React
3. Promises: bluebird, when or p-promise
4. Observables: rxjs or most (they play well with promises)
5. immutable-js for immutable data structures
6. lodash and/or Ramda.js
7. browserify1. Not a problem, though I don't use either, I tend to use very small modules (not necessarily via npm, but require'd in my own project, or outside modules)
2. React, and even the Yahoo flux tools are pretty nice. React by itself is less useful.
3. I'd go with es6-promise here, which complies with the spec. I wrote i-promise as a module to give an ES6 compatible promise library, or native as available.
4. Observables are pretty evil... the whole flux architecture is to avoid direct observations in favor of a unidirectional data flow.. but that's more opinion.
5. completely agreed... immutable data flows work to prevent side effects. Even if you don't use these libraries, avoiding side effects is a big thing.
6. Also agreed, though you can usually get the parts you want without the weird deep dependency chains in lodash.
7. Agreed here, though webpack is interesting, imho it breaks too much with node's approach to includes, and doesn't work as well with reusing code on the server-side (imho).
Other things to look into include csp, streams, events and the gulp build tool.
Or they can also be used in place of asynchronous lists (like "object streams"). I find them handy for various tasks :)
Regarding es6-promise, its too minimal for my taste, and missing my favorite feature (provided by bluebird. when and p-promise): long stack traces on (possibly) unhandled errors, which are quite invaluable on the server side when debugging longer chains of events. p-promise has the additional advantage of being a relatively small library which is pretty awesome :)
[1]: example: flux implemented with rxjs: https://github.com/fdecampredon/react-rxjs-todomvc
I actually have this entire stack running without observables currently, and my goal is to build a variety of applications using it to really sort out the best techniques with it, and then open source it as a platform.
As for #7. I use webpack and love it. It does work wonderfully server side as well, you just have a build step with webpack that strips out anything you don't want for the server, and then have your server run that built file. Not perfect, but works well. It also avoids any need for gulp.
If you're already at the point where you are utilizing compilation, why not implement a compiler-level async/await solution (probably based off of a loop + a state machine, a la regenerator).
Even so, lambdas, observables and some FP constructs such as map/reduce/filter/etc can potentially eliminate the need for imperative style code. There are also some semi-imperative solutions to certain problems that work okay [1]
Another advantage of functional code is that its easy to extend - adding a combinator that implements filtered (typed) catch for promises is a lot easier than implementing a language construct such as `catch (e if e.code == 404)` for generators.
var only = (predicate, handler) => e => {
if (predicate(e)) return handler(e) else throw e;
}
promise.catch(only(e => e.code == 404, e => {
handle...
}))
Here is another example (its a bit of an overkill though :)You assume all libraries in JS is mature, well-supported, and will be there in the next 4 years at least.
I echoed other comments: JS ecosystem is unstable and confusing at the moment.
Case and point: EmberJS. I have to use ember-cli, npm, bower, and broccoli. Some of them overlap.
On require/modules, that's a freaking mess.
Ambiguous/unexpected behavior... nothing fixes it.
To make matters worse, there's always the promise of some magical library or tool that's going to fix your problems, until you discover that it sucks, or that it is unmaintained, or that it doesn't interoperate with another library and then you're back to search between thousands of pieces of crap that do the same thing.
I remember the days when people were having boners over CoffeeScript. Boy, that was a bad move.
I don't find require/modules to be too much of a mess.. unless you are using a lot of really large tool-chains with deep dependencies... npm dedupe helps point out problems there.
Breaking your logic into idempotent functional components without side effects as separate files/modules reduces a lot of what can be considered ambiguous or unexpected.
If you work with a functional flow, avoiding OO in JS as much as prudent, you can get a lot done without nearly as much confusion.
For now co/generators/promises get you really far along. In the future await/async will take it farther.
How is it weak?
As for blocking, if you are doing something that is blocking in your main event-loop, you're probably doing something wrong. Break it off into a req/res queue and let it flow.
Regarding call-back hell... you have next-generation tooling like co/koa as well as ES6 Promise patterns you can use. Not to mention the async library.
You can readily follow functional patterns in JS and Node... just because there is prototype based inheritance doesn't mean you need to use it, and most of the time, I don't.
Also, Node itself isn't really single-threaded... the main event loop is, which is where your JS code runs. The underlying platform calls are running against a thread pool.
I don't think the other "scripting" languages like Ruby, Python, and PHP stand much of a chance against it in the longer term. They just don't have the resources to compete.
Have you checked out the Computer Benchmarks Game? Here are some benchmarks they provide, comparing the JavaScript V8 to Python [1], Ruby [2], and PHP [3].
Looking at statistics such as these, I'm left thinking, "1. This is awesome! 2. Is there something about these other languages that prevents V8-like performance, or is this more a matter of browser performance being highly invested in by Google, Mozilla, etc.?"
[1] http://benchmarksgame.alioth.debian.org/u64/benchmark.php?te...
[2] http://benchmarksgame.alioth.debian.org/u64/benchmark.php?te...
[3] http://benchmarksgame.alioth.debian.org/u64/benchmark.php?te...
A somewhat more fair comparison would be V8 vs. PyPy, Rubinius/RuJIT, HHVM, and LuaJIT. LuaJIT and V8 would likely still come out on top due to the amount of work and sheer excellent engineering put into the compilers (and in LuaJIT's case, also the interpreter), but PyPy's performance should be a lot better than CPython's for these benchmarks.
I also imagine (though am mostly speculating) that a benchmark involving a full-stack frontend framework like Angular or Ember, with hundreds or thousands of JS objects and lots of DOM manipulation, should put V8's performance a bit closer to CPython's.
http://kripken.github.io/Massive/
I just remembered that there are demos of Unreal Engine running in js with a lot of LOC and fast performance.
Well, it would be a different comparison; and I dare say a website showing such a comparison would attract a lot of traffic, if only someone would "please take the program source code and the measurement scripts and publish those measurements."
Interesting idea! How would we make a version of the benchmark for CPython though?
The comparisons they do is not of idiomatic code... for example in python they do a lot of array programming and don't use numpy (http://www.numpy.org/). So for most languages the results in there are completely meaningless.
The performance of those programs with CPython explains the existence of numpy, and if you look you'll find that numpy programs are shown.
What were your thoughts on the regex-dna benchmark?
See: http://blog.chromium.org/2009/02/irregexp-google-chromes-new...
It might mean it wasn't a relevant comparison for you; but if those 10% of cases were performance critical it would be very relevant.
1. Bluebird with longStackTraces, [1] to get complete stack traces for an entire chain of async operations with minimal performance penalty, and
2. node-debug from node-inspector [2] as a debugger (same UI and features as chrome dev tools)
[1]: https://github.com/petkaantonov/bluebird [2]: https://github.com/node-inspector/node-inspector
As the companies I work(ed) for evolve from JS => jQuery => Backbone.JS => Backbone.JS + Marionette => EmberJS, so does my skill have to evolve. I also have to write some JS code on top of PhantomJS + CasperJS (not for automation testing but instead for performance monitoring) to support enterprise product at the moment.
I used to hate JS with passion but now after seeing Chromebook, Chrome Apps, NodeJS, and my current favorite: MeteorJS. I just have to suck it up and learn JS to be honest...
Would I bet an enterprise app to use NodeJS if it was using my own money? Probably No. Would I bet my weekend projects and ideas on NodeJS/EmberJS/JS? Yes.
I think the JS ecosystem is still unstable and a big mess but let's hope it moves to a better direction.
- awesome dependency management systems like NPM and Bower
- awesome task runners like Grunt and Gulp
- NPM has thousands of plugins, more than Java's Maven and Ruby Gems [1]
- Github badge support for builds, test coverage, dependency versions and NPM
- Close second best StackOverflow support behind Java (without taking into account Node.js) [2]
Imo it's probably the most modern, stable and evolved ecosystem out there currently.
Also keep in mind that in Java, most people have 1-2 choices at most and those choices tend to be way more mature and stable so we tend to feel comfortable with those (at most) choices.
You can slice and dice my analysis anyway you want. You can say lack of choices is bad and millions of Java devs will disagree with you. You can say that NodeJS is evolving like mad and thousands of other more experienced Devs that myself would argue that NodeJS ecosystems is playing "see which one sticks". Your values are different than of mine.
StackOverlow stats you posted doesn't mean anything. Literally. We know JS has been around for ages. The fact that JS claim of fame to be smaller/leaner than Java yet rank #2 behind Java humongous ecosystem is a question mark in my mind: "What The Heck?"
It can go either way.
Gulp vs Grunt, NPM and Bower. Java has Maven. One tool. Yes, there are Ant and Gradle but let's be honest, Maven is king whether you like it or not. With Java, I declare the archetype (web-app or simple app) and dependencies and away I go (unit-test is part of the build, integration-test requires a few additional lines).
With JS, I have to .. ? Let me know if it's simpler than Maven. Let's not waste time to argue about XML vs JSON or whatnot, that's a matter of taste, let's focus on the required steps to build, run tests, and package it up whether as a deployable or a dependency of others.
...and Leinengen and SBT and perhaps a build tool for every other JVM language...
> but let's be honest, Maven is king whether you like it or not
Maven would do well to offer an alternative CSS/Gradle-like syntax (if doesn't already) because XML is still hard to read.
'Most stable' ecosystem? How do you figure that? It's only been around a short while in its current form. Other languages have had their current ecosystems hanging around for decades.
'Most evolved' ecosystem? Technically a single server-side javascript have existed since 1994, but other than JScript on ASP and Lotus Notes xPages (lol), nobody really used it again for non-frontend work until Node came around in 2009. AFAIK, jQuery was really the beginning of the 'modern' Javascript age back in 2006, and has slowly been adopting the practices of other programming ecosystems since. I would wager V8 was the biggest boost to JS development in the past 10 years, as it finally stopped being the slowest interpreted/scripting language in the world. Is there even a CPAN equivalent for JavaScript yet? It seems they've only implemented an equivalent of PAUSE or PPM.
Anyway, it's obviously getting better, but it's still pretty young.
As someone who used JS server-side from Netscape Livewire, to ASP JScript and even via Synchronet, and other JS runtimes... I've always appreciated the core language. Long before "The Good Parts" because Crockford only got a lot of coverage for what I already knew. Same goes for some recent adjustments regarding Object.create (and even inheritance chains in general).
JS at it's core is a decent language. ES5/ES6 enhancements make it very usable. Currently developing against Node 0.11.x --harmony, with a an es6ify for browser support. Given Node's very good async i/o interfaces, I've written a lot of bridges the past few years between systems that have trouble communicating directly.
Namely SOAP providers are a pain to consume in general a lot of the time. Not a problem to create a JSON endpoint in node that runs it fine. Need to process a huge XML or CSV file... Node is actually pretty nice... and can generally ship the final data where you need it.
Node is imho the ultimate service middle-ware... And to me, this extends to being the servers/services that web applications talk to... relaying to other backend systems/databases.
'That's likely, though it's honestly got the same things as every other programming ecosystem'
I disagree on this point because dependency systems like Gems (for Ruby) and PIP (for Python) are miles behind NPM and Bower.
I'm also not aware of popular task runners on other programming languages in the same way Grunt or Gulp are.
Perl isn't a language I know well so I can't argue on that.
By 'Most evolved' I didn't mean Node.js but really the NPM / Bower module ecosystem. You rarely if ever have to write something from scratch due tu a lack of plugins.
I agree with you thought that thanks to V8, JavaScript has a performance level that is close to compiled, lower level code.
Well I'd say his opening might be the reason: "As the companies I work(ed) for evolve from JS => jQuery => Backbone.JS => Backbone.JS + Marionette => EmberJS, so does my skill have to evolve."
It's evolving fast, and this makes it unstable in terms of knowledge and what's being used. Depending on outlook (or age?) this can make it exciting. It's also a pain in the proverbials to keep up with, and everyone's at different places (while the HN crowd appears to have moved onto Gulp, many people I know are just discovering & starting to use Grunt).
Thousands of plugin says nothing about whether it's a stable ecosystem either: the majority could all be high quality, or they could be scratch-an-itch-and-move-on projects.
It's true though that your value as a developer shifts quite fast depending on the trends. But I feel that a fast moving world is merely a consequence of super large communities like the JavaScript one.
By "stability" I meant that NPM and Bower are quite reliable. Also, if you look at the usage stats for the top plugins, the still show in my opinion stability since you have a lot of devs contributing through pull requests.
It shouldn't be particular to JavaScript or Node.js.
But I do think it's cool that someone can transition from WPF to Web development with Angular without feeling too lost. Dynamic Web development used to be a very, very different ballgame from client application development.
File under "damning with faint praise", methinks. Not sure what it means if the "not all that bad" version is one that doesn't run natively anywhere yet...
Deleted comment
(edited for clarification)
I use C# myself and would not like to convert our whole app to js but I could be ok with Dart or TypeScript instead (or Go but that is not a scripting language).
That said, you're still free to develop your API using your favorite technologies. To be honest, this is where the heavy lifting is, anyway, so it makes sense to have stronger typing, richer data types, etc. at this level.
I've had the opposite experience with the SPA projects I've worked on, one of them pretty large.
With the possible exception of authorization/authentication, the API for all my projects has been pretty straightforward, whereas the client-side app has been where I've missed stronger typing and rich data types most acutely, to the point where I've been actively evaluating compile-to-js alternatives with a better/safer type system.
However, with the advent of Facebook's Flow, I might just stick with JS.
Agreed that client code can become very complex. It's one of the reasons I avoided doing too much on the client in the past. My solution to this has been to use TypeScript, which is fantastic for solving this sort of problem. Yes, it moves away from prototypal inheritance. It also doesn't play nice with JSX. It's still hugely worth it for me. I haven't tried Flow but it looks like it addresses the same problems.
Then I found out about ReactJS.NET [0] which allows for server-side rendering of ReactJS components from ASP.NET. I haven't had a chance to try it out properly yet but my preliminary test of it made it seem plausible for creating isomorphic apps in ASP.NET. Have you given it a shot? If so, what are your thoughts?
Any client-side routes will need to be mirrored on the server if you want isomorphism. This means you're using two routers. Many Node solutions will use different routers on the client and server, but there are a growing number that can be shared.
The router is my biggest stumbling block right now in my road to React. There are a variety. There seems to be a consensus around react-router, but now we have the Yahoo contribution. There are two problems that I'm having. The first is that, if you want to use HTML5 History (instead of the dreaded hash bang), you're kind of on your own. There is usually little documentation on how best to handle this. If you do this, you have to intercept and prevent navigation, but only for the relevant local routes, of course. This is intimately tied to eventing. If you're using React, you'll probably use React events (vs, say jQuery).
The next issue is that most of the examples out there are simplistic. They will show a simple page with one component embedded that swaps out a part of the view. Any real app will require layouts, views, and components. Some of these levels will vary based on routes. ASP.NET has an elegant solution for this. I haven't seen an analogy with React + router.
I think part of my problem is that I'm still ramping up. I'm guessing that this is largely teething pains.
react-router is all right and they've got server-side rendering working but it's still missing one very important facet that is required for most isomorphic apps; the initial server-side render should be capable of fetching whatever data is needed is fully render the page. Right now the best you could do is deliver a page with a spinner if the page requires some data on the initial render. Andrey Popp's react-router-component solved this issue by using react-async which uses fibers to allows for getInitialState to work asynchronously. The react-router guys think the "fibers stuff is stupid"[0] but they're still working on their own solution to the problem.
The only reason I'm still keeping tabs on react-router instead of abandoning it for react-router-component is that it doesn't look like Andrey Popp's is going to be maintaining react-router-component and react-router seems like the only other game in town when it comes to routing in React.
[0] https://github.com/rackt/react-router/issues/57#issuecomment...
P.S. I don't know that much about node and fibers to understand why fibers is stupid but it solves the problem and from what I read about fibers, it seems like the node community just don't like it because it resembles threads and they don't like threads in node.
https://github.com/rackt/react-router/wiki/Announcements#wha...
One of the exciting things about React, and Node.js more generally, is how quickly it is moving. This usually means that there are sharp edges and rough patches and that's been my experience so far. I'll take that any day over a backwater that gets no attention.
I am going to spend some time with react-router, since it looks like the one that is gaining the most traction. To my comment above, they do support nested views, which appears to solve the layout issue for me.
It's awesome that they've apparently solved the issue. Haven't quite grokked the example but will study it further.
> Any client-side routes will need to be mirrored on the server if you want isomorphism. This means you're using two routers.
A while back I worked on a library called [RouteJs](http://dan.cx/projects/routejs) that would expose certain ASP.NET MVC routes to JavaScript. The use case here was to have a way to build URLs client-side rather than hard-coding them (similar to the `Url.Action` helper in Razor) but a similar technique could be used to do client-side routing. That's actually a really good feature request for RouteJs :)
> The next issue is that most of the examples out there are simplistic. They will show a simple page with one component embedded that swaps out a part of the view.
Yeah, that's true. I have one page using server-side rendering in production, and it's a page on my site/blog: http://dan.cx/socialfeed.htm. It's also a simple page but I used it for building the original proof-of-concept for server-side rendering. I haven't actually tried using ReactJS.NET to build a single-page app, but I think that would be an interesting use case.
It is possible to build extremely dynamic websites that are not SPAs. It is possible to do it in a relatively straightforward fashion. (Using something similar to web components.) So why move?
Possible, but not easier.
People often smirk when I mention progressive enhancement these days. But the same people often claim that something is "impossible" to do using PE, while it's not only possible, but downwright easy. This makes me think most of them never even tried this approach seriously.
My overall strategy is creating some crude "date model" of the application in pure HTML, then identifying additional behaviors I need to make it look/work the way I really want to. I implement each behavior as separate JS libraries. The libraries are configured by adding additional directives to my markup, so using and re-using them requires no coding per se.
You would be surprised how much you can accomplish this way. Moreover, it forces you to write highly reusable components that are easy to reuse.
CSS3 is a great help in this regard, because (in most cases) you do not have to specify look-and-feel of anything in the library itself. You can simply generate some additional markup that can be styled separately for every app.
To put it another way, when you design transactional first, you actually design a very good approach to your business layer public interface. If you do that step right, you can do the next two with minimal effort:
1. An application API;
2. Client side javascript for improving the UI of common operations.
Single page applications often smell like the Windows Forms applications of old: A convoluted spaghetti of application states linked by insignificant events and event handlers, where the boundary between business logic and user interface is fuzzy or non-existent.
My only gripe with SPA was the initial load-time (looking at you Gmail), but with virtual-dom, being able to generate the html on the server gives you the best of both worlds.
BTW, you're posting this on Hacker News, which is the ultimate in retro Web-1.0 technology. Heck, it even uses tables for layout.
I think this is what Gmail does, though it still takes forever for the initial load. Anyway, I can see this becoming a complicated mess very quickly, and find Ractive/React to be much simpler solutions.
As for HN, I doubt anyone comes to HN for the design. PG and YC's brand helped create a solid community with good content and good discussions, which is what keeps bringing us back. But let's call a spade a spade - the UI design here is a joke, even more so considering that its target demographic is the tech community.
Now, whether the benefits of getting rid of that constraint are worth the costs depends entirely on what you're building.
<form action="/something" submit-to="#x, #y"></form>
<div id="x" />
<div id="y" />
Normally, the only thing I need to add to go from non-AJAX to AJAX is submit-to="[CSS Selector Here]". Possibly, some IDs. Everything else works automatically. The library adds a certain attribute to the "pasted" parts, so I can add visual transitions via CSS3. I can use form's action URL to rewrite current URL via push state.I love it though.
Also try talking about node on proggit, you'll get mocked and told how dumb and shitty it is.
Node is at a tipping point right now, and talking about how "dumb and shitty" it is won't change that. The technology has shortcomings no doubt, but there's just too many advantages to it from the business strategy side for the shortcomings to matter.
I use several frameworks/libs for different tasks: Webmachine, N2O, Cowboy
I don't believe in RoR type of frameworks. I believe in clear separation between server and client. We are steadily moving towards a web of websockets and "one page JS applications". Won't comment on whether that is nice thing or not. I am not sure for myself. For client we are stuck with JS. Sucks but it's a fact of life.
Erlang (or other things using this model, though, nothing as mature exists) is the only sane way of writing "multi-user" or "mega-user" servers. For me, server side is a solved problem (because of Erlang). And I'm talking about huge, clustered backends. Node.js feels like a child's toy compared to Erlang.
I would suggest that everyone who claims to be a web programmer should at least know how to use Erlang. Otherwise, you aren't really aware of how big the world really is. And what is possible actually. This may sound elitist, and it probably is, and I am probably not a good person for talking like that. But you can't really argue with things like this: http://blog.whatsapp.com/196/1-million-is-so-2011
Once you have experienced things like this, and once you really understand why it works and how to steadily reproduce it on every project you work on... well, that's why I claim that server side is a solved problem.
Edit: that said, a big company would certainly have the resources to make Erlang work well for web development, and, yes, it's way more solid than Node.js from an architectural point of view.
That can still be worth it, given the advantages the run time gives you, but I think you'd really want to know exactly what you're doing.
Everytime someone points a erlang, they bring up whatsapp. And everytime they do that, I tell them facebook the company that owns it is a php shop (Atleast, that was the core driver. Things might be different today with hiphop).
And no, you are not absolutely right, Facebook is not a PHP (only) shop. Their chat backend is in Erlang and that's a much bigger tell-tale than their legacy code.
Also, a lot of us Erlangers speculate that Facebook bought WhatsApp (not only but also) because of their huge infrastructure know-how and (Erlang) talent.
Not true anymore. They switched away from Erlang because of reliability and scaling problems. So saying that mega-user server side is a solved problem because of Erlang feels like a stretch.
That erlang know-how commands a high price on the market is a good argument for developers to invest in developing that know how, and for organizations to work on fostering it in their staff.
Its only "bad for erlang" if you assume the only way to adopt erlang is for an organization to wake up out of the blue one day and decide "from this day forth, all our work will be in Erlang, and we're going to go out on the market today and hire up Erlang talent to enable that to occur."
What's your typical day-to-day setup, and what's your workflow look like?
I love Erlang and its concept, but the lack of friendly developer tools and easy testing put me off after the one successful (commercial) project I completed a couple of years ago.
I'm all geared up to become an Erlang evangelist (particularly for the reasons you give - Node.js really does feel like a toy in comparison), it's just the process of putting the code together feels painful compared to the tools I'm used to. (whether Visual Studio or PHPStorm or...)
If you can spend a few minutes discussing your setup, I would find it immensely useful.
Some of my colleagues use IntelliJ IDEA and they swear by it. I certainly recommend trying.
No,it's way too low level to be "the new PHP",and frankly async programming is hard,way harder than writing sync code by default.
Most of all to me node is fun which is especially important when you have to conquer problems in un-fun environments (most Bigco systems).
(This is the best link I can find quickly: https://www.paypal-engineering.com/2013/11/22/node-js-at-pay... I am sure there are more.)
Slides: http://www.slideshare.net/jeharrell/9-antipatterns-for-nodej...
But then bluebird came out and changed everything, and many of the other promise libraries followed suit. Most promise libs are now really lightweight (with the only remaining exception being Q).
See https://gist.github.com/spion/6990910 ; http://spion.github.io/posts/why-i-am-switching-to-promises.... ; https://github.com/spion/async-compare/blob/master/latest-re... -
For example, bluebird (and most other promise libraries today) have 2 to 3 times lower overhead than caolan's async and are comparable to the most hand-optimized raw callbacks.
Related: https://news.ycombinator.com/item?id=6784967 http://venturebeat.com/2012/01/24/why-walmart-is-using-node-...
http://www.joyent.com/blog/walmart-node-js-memory-leak
Eran's recounting of the issue: https://www.joyent.com/developers/videos/walmart-node-js-mem...
It's interesting to note despite the memory link, the incredible amount of traffic WalMart was handling with its Mobile apps running on NodeJS. That's what was more impressive to me.
While there are definitely dedicated server-side and client side JS people, speaking the "same language" helps within teams and allows for some shared responsibilities.
That's appealing to large organizations with decent turnover.
It also encourages an ecosystem wherein almost any developer out there can work on either side for you.
Server side rendering takes time, even 10 ms. On an single event loop, that is terrible. You can only server 100 request/second due to the 10 ms limit. While it is nice that you can move a request into the backing queue while waiting for the data, you're capped at 100 requests/second.
Where I think Node shines is low level network management. Netflix could use it to pipe video data from one of its boxes out to a user. It's got that kind of work built right into it. As a result, I think that storage, spooling and possibly even sending would be best in Node. Those are largely I/O bound, schlep data from port to port operations.
My understanding of PHP is that it's really hard to have really global variables. Compare this to Node.js where Javascript naturally does this. I can't find it now, but I remember back when Node was young a guy had an issue with his shopping cart system. People's orders were screwed up. Turns out that he missed a `var` in a function. PHP, I don't think, could do this easily since the widest screw up scope is file. So you're still limited to request scoping.
http://php.net/manual/en/language.variables.scope.php
PHP also has "superglobals"
http://php.net/manual/en/language.variables.superglobals.php
And no, you don't really need global variables in frontend that much; and backend PHP programs (which you should not do of course) have long-lived global variables.
Why??
... badly written JS, sad, unfortunately that's the fact.
I have worked with javascript for years but it was always for DOM manipulation. When it comes to building an app with javascript, i feel like it is too fragile to depend on.
Anyone can help me to get rid of this feeling?
The core language (syntax, available directives) hasn't changed much since the time everyone deservedly hated it. Its performance was optimized, it got many more libraries and it is still the only language supported by browsers. But the question is, why all of this applies to JavaScript and not Python/Ruby/whatever?
A lot of its benefits people claim simply weren't around when they chose to stick with it. It's like saying you chose IIS over Apache because of features of C# 5.0 and ignoring the fact that you chose IIS in 2004, where C# 5.0 was not around. It's a dishonest argument.
Speaking of which. How can people claim that JS benefits from the same language running on client and server when 90% of server-side libraries do not work on the client and there are potentially major differences even in core library (e.g. forEach)?
Also, a huge part of JS ecosystem are kludges, crutches and workarounds that make the stack way, way more complex that it should be. (E.g. source maps. Imagine someone minifying PHP for faster parsing and then asking everyone to use some source mapping technology for debugging. They would be laughed out of any conference or discussion.) This mentality permeates everything. I mean, seriously, require directives need to be implemented as a library? Namespace isolation is a closure-based hack? Can you imaging stuff like that being tolerate for any other language?
Source maps or debugging symbols have been accepted for compiled languages for a long time.
Meanwhile, people debugged binaries for several decades before your language even been developed.
Do you see anything wrong with this picture?
1. Cooperative multitasking. Really? In 2014? Hello?
2. Weakest of weak typing. undefined is not a function? Anyone?
3. Everyone can override everything.
4. Conventions, that's the only way you can build software in JS. Anyone know of a person who doesn't break conventions?
Having programmed in something like Erlang, which IMHO is the sanest technology available today for doing web, JS feels horrible.
1. It turns out the reactor pattern is a good way to build network servers that scale reasonably well with minimal developer effort. In my experience developers tend to avoid writing threaded code in synchronous languages, and threads don't show up very often in run-of-the-mill solutions. To be sure, JavaScript's lack of threads is a blemish, but oddly it forced the community to focus heavily on distributed architectures, and as a result most of the tooling encourages distributed systems, which is a win for some common use cases.
2. Type safety is a hotly debated topic and I don't think you can find resolution on this one. For some people, "weakest of weak typing" is a benefit.
3. Static vs. dynamic, see #2.
4. Do you mean that everything must be enforced by convention instead of static code analysis, compile-time checks and type safety? If so, I think you're making the same point three times.
Erlang is a beautiful language and may be the most correct in some sense, but doesn't look nearly as attractive to the kinds of teams I work on when you start to consider developer availability, library ecosystem, tooling, ISP support, documentation and community.
They're both good, in both cases.
2. Weak typing is a nice feature for prototyping, but for larger projects, a stronger type system is better at catching bugs. Many JavaScript programmers (myself included) are used to using separate systems to check types for them. My team uses the Closure Compiler, which, along with compiling the JS to a more optimized version, is also happy to check all your types and fails to build if your types don't line up.
3. Again, I believe this is something that you can make sure that the compiler catches. And, of course, anyone can write bad code (in any language); if you're overwriting stuff halfway across the codebase, then that's "bad code" and you should avoid doing that (and during the code review stage, you should be making sure that your coworkers don't do that either).
4. Like for any language, have guidelines for how you write code, and enforce some of your conventions with the compiler and with linting tools. It leads to a more consistent codebase.
Doing CPU-bound computation in your application server is an anti-pattern. IO-bound computation, however, is where Node excels.
The thing to realize is that pre-emptive multitasking is costly. It is convenient for the programmer (the programmer doesn't need to worry about blocking and locking up the rest of the program), but it comes at a cost. Lightweight "green" threads, or equivalently, Node's evented dispatch mechanism, are a much more efficient use of the CPU. For applications composed of short-lived computations (e.g., < 1ms), it doesn't make sense to interrupt them and context switch. It's more performant to let them complete and then switch. You just have to make sure you aren't doing any CPU-intensive computations in the app server—which you probably shouldn't be doing anyway.
The downside of Node's approach is callback hell. And that's why we have Go.
Yeah, preemptive multitasking may be costly. But as you say, when you have lots of users, most of their tasks are sleeping or waiting for timers. That's where preemptive multitasking excels. You can have millions of sleeping tasks and several (at times) doing real work. That's why Erlang is "scalable" and node.js is not. Especially if you need to have state in your workers and if you need them to live longer.
Saying that node's cooperative multitasking excels in IO-bound computation is a clear sign that you haven't tried Erlang.
I have another counter-point for this as a rails developer tinkering with golang recently. I think Go got this correct in many ways. Having light weight goroutines that can scale well; having good IO which does epoll/libuv style wait in the background transparently when you read/write. Easy to understand multiprocessing language in general. I have no idea why it's not taking off in web development though.
Wat?!
By the end of the 90's, people started the "10K project", aimed at adjusting Linux and Apache so that a hight-end machine could support 10k simultaneous Apache threads, all doing IO at the same time. And they were successfull.
That was more than 14 years ago.
Have you used Async.JS? In my experience, it has always solved my deep callback problems.
Not a good idea, but that's rarely a hindrance for both enterprisey and startup "human resources" management. Reminds me a bit of how we treated torchbearers and henchmen in D&D...
And lo and behold, they have decided that an anonymous class with only one method is equivalent to an anonymous function object, and given us syntactic sugar to invoke it without the class declaration boilerplate.
You're essentially doing the same as complaining that conditionals aren't a Smalltalk language feature.
Contrast with JavaScript, where functions are first-class, can be declared at top level, can be passed as arguments to and returned by other functions, can be called by dereferencing a variable, can be nested, can be partially applied, etc.
The minimal syntactic sugar for anonymous inner classes added in Java 8 doesn't even begin to approach the power of the function support in languages like JavaScript. Language-level support for this stuff matters.
Many uses of first-class functions is for reducing boilerplate to begin with.
Also to respond to your points...
1. This I see as the most valid argument, but not a deal-breaker (see Walmart, LinkedIn using Node without problems scaling).
2. Check out Flow by Facebook [2] or TypeScript.
3. Not true with require/modules.
4. It's incredibly easy to include a JSLint file in your repo and as a git hook.
[1] http://nerds.airbnb.com/isomorphic-javascript-future-web-app... [2] http://flowtype.org/
I find this sentiment odd. Obviously it's not ideal for many workloads, but for some things it's the sane option. I work with Tornado in python at work and cooperative multitasking is probably the thing I'm thankful for the most. The server is very IO bound, so it keeps logic seemingly synchronous but hasn't shown any throughput issues thus far.
2,3,4. TypeScript, Flow, PureScript add varying degrees of strictness, checking and purity (from low to high, in that order)
Erlang feels very complicated. I mainly build simple CRUD apps. Would I still benefit from using Erlang?
Software development is one part creation, one part understanding existing software, and one part changing existing stuff. Javascript has proven a bit difficult on the last part.
Avoiding the use of OO contexts and this helps a lot in terms of avoiding side effects, and improving testing and predictability as well.
I don't think you can necessarily overcome the deep-seated knowledge that the language is hot garbage. You can learn to use tools to reduce it and understand the language enough to realize where its truly horrific spots.
They're joining the likes of Facebook, Netflix, Square, Microsoft, Instagram, Khan Academy, SoundCloud, Trello, New York Times, and others in adopting reactive extensions.
[1] http://www.reactivemanifesto.org/What exactly do you mean by reactive here? As one of the other posters said, react's 're-render the virtual dom' concept doesn't have any direct relationship with the reactive manifesto, though flux might be a better candidate.
https://github.com/yahoo/dispatchr
Reflux is a great solution when you need to coordinate between multiple components.
But seriously you're on HN and you're upset about people arguing/discussing a web technology? I don't even see one mention of "m'lady"
I think Javascript is fun and easy to use. That's good enough for me.
That it helps preserve balance with iOS and Android in the "software eating the world" conversation, is a bonus.
In the last years JavaScript has exploded with new frameworks and "compile to JS languages". But I have yet seen anything close to usable. Maybe it's because I've become "speed blind" after coding JS for over 15 years. I do not see all the problems ppl see in JavaScript, until I look at code written by beginners that seem to use every framework out there, and over-complicate the code, and naming everything with one letter variables and the name of their favorite pizzas.
On the topic of JavaScript - I love Node as a glue. For larger applications - I just don't know how to structure (architect) a large application on a language like JS. Maybe that's just my ignorance.
1) Break any functionality possible into a separate npm module - not just a separate file with module.exports. Keep the npm module small and break it up further if it gets too big.
2) This module will be small enough that it is trivial to debug, refactor, test, and document. If it gets to a size where these tasks are hard for any reason and you wish for strong typing or something, the module is too big.
3) Please make sure that you do test and document the module. This will make your team way faster in the future.
https://github.com/doxout/promise-observer
and its statically verified documentation as well (therefore never goes out of date)
The Clojure + ClojureScript approach has many more batteries included. You get all the benefits of reusing the codebase on both sides of the fence while the language is solving the "Transactional Store", efficient dirty checks, nice server-side concurrency primitives and many unrelated problems for you.
I've been using and enjoying React and am excited to learn more about Reagent. It seems like Clojure + Reagent will make development quicker and more enjoyable.
https://medium.com/code-adventures/farewell-node-js-4ba9e7f3...
Anyone experience the same?
He also says that node isn't moving fast anymore, which is unfortunately true. The node core team was stuck trying to release 0.12 for quite a while because of some significant changes to internals (V8, AsyncListener). Once 0.12 is out, things should be much easier. On the plus side, the ecosystem is still moving at the same speed which is pretty great, and JS gets new advanced tooling every day: typescript, flow, 5 (!) es6 compilers...
Boy oh boy do I wish that were the case.
It seems that every job, even backend positions, require Angularjs or Backbone.js knowledge. Having largely ignored the two and hoping they would die, I am ready to learn React + Flux to accelerate to this cause.