Just my two cents.
Just my two cents.
I think this "benefit" of using the same language for front and backend is pretty over-hyped, as well. In theory, I can agree that it sounds good. In practice, use the best tool for the job on both ends to fit your team's abilities and strengths.
The other neat thing is that if your frontend and UI are cleanly separated, you can swap them out individually without the other even noticing. If our backend gets to be too sluggish, I can replace it with something lower level gradually over time (Go?) without leaving a bunch of deprecated backend JS cruft to clean out.
Just to give one example: any data query can get answered locally or from the server, depending on what's already cached and whether you're online. Before, I had to implement every call twice and make sure they stayed in sync. Now I can implement once and run the same code in both places.
And other interesting possibilities open up. The server can just run the client's data synchronization code to pull changes from another server, giving realtime server-to-server replication nearly "for free".
I'm working on a webapp that mimics functionality of an existing desktop application -- mostly as a self-educational project. As I'm writing it and adding features, I can push processing from server-side to client-side and vice versa with hardly more than a copy and paste of the relevant chunk of code.
Say I don't really care about the security of some particular process, and I really don't want to use up any additional resources on the server for it, I can just push that load to the client browser in a couple clicks.
Did I just write some feature into the client that I suddenly realize presents a security problem? With node, there's no need to change my frame of mind or rethink how to do something in a different language -- just copy and paste from client.js to server.js and do some slight cleanup.
That said, you hire "backend-focused" developers, "front-end" developers, etc., but to me that still means they should be able to do whatever tasks are necessary (Go, JS) to get their job done.
However, one of the more frustrating pieces of this is that I never dive deep into one paradigm. I'm continually having to work bilingually. When I was working with node.js, I didn't feel nearly as much bilingual stress (even though I've written backends in python, ruby, java, groovy, and scala!)
As such, my single person one-off and side projects will be in node.js. It's about cognitive overhead in the moment. I agree that it's a mediocre solution for larger teams and enterprise is not its sweet spot, but it's great for projects in the small.
In the domain I'm in (internal enterprise cough) I find that most people are expected to be full stack. On the other hand, these tend to be more simple UIs in general, so the front end knowledge isn't as vital (cue 'good' full stack developer comments...)
I have a main screen with a query whose processing takes over a minute to perform it on all of the data, but seconds for incremental changes after that. Each row returned has a detail screen associated with it, and the users have a requirement to be able to move to a detail screen, update a record, and return to the main screen without continually incurring the heavy query penalty each time they return to the main screen. Business also has a requirement that the database of record is normalized. (Denormalizing and precomputing is good, but you run into problems when the feed updates.) Do you...
A. keep a Nosql (say... redis) cache, precompute, and perform two commits? This adds a non-trivial amount of complexity keeping them in sync, not including watching for jobs from outside feeds that can update at any time. This isn't bad for a simple system, or a system with a lot of engineers, but it's non-trivial to get right and easy to find out a bug after the fact.
B. Keep it all in the session? This has its own problems: if using an ORM, you're going to be increasing your memory load per user substantially. Otherwise, you're having to keep a separate data structure around and marshal/unmarshal, creating an additional complexity layer, and I haven't seen a great way to do this.
C. Keep a single page application and implement a polling mechanism behind the scenes to keep the information fresh? With a system like Ember or Angular, this may not be trivial but it's not terrible either, and I'd argue it's superior to a redis cache.
I know that I can provide a better user experience by prefetching. I don't know how to do this with progressive enhancement.
And most importantly, you've now created two code paths, both of which need testing, both of which require maintenance, and one of which (in a web application) will never be used. What's the ROI?
Now, for some domains (say, e-commerce), progressive enhancement is the right way to go. I've done it. For web applications, which are the extension of client-server applications designed for a limited captive audience (employees), I don't see the ROI.
Don't forget your form needs to be comprised of up and down submit-buttons; wouldn't want the progressive-CSS lords coming down on us.
Those fearful of JS come along... Collapse comments? Refresh the page, but don't forget to pass previous state of comments previously collapsed! Submit an up arrow? Don't forget that blob of state! Loaded deep-nested replies? Push it into state! Careful; none of this matters to 99.9% of your users, because they are understanding they'll lose the statefulness on refresh, while everything stateful happens inline and without refreshing the page and bringing in sections of the page as dictated by our stateful blob.
For example, if you ever tried PE for real you would know that there is no point in implementing collapsible comments in pure HTML. That's exactly the kind of functionality you "enhance" via JavaScript. Of course, like most modern developers you've never really tried the practice, so you don't have any experience with such things.