Having the same language across our entire stack has huge, enormous, gargantuan benefits that shouldn't be underestimated, especially for a small team. Being able to easily move between backend and frontend code bases has had a gigantic positive impact on team productivity. Couple that with auto-generating client and server-side typescript files from our GraphQL API schema definition has made our dev process pretty awesome.
same here, except Apollo GraphQL, we still use REST. it is indeed nirvana. wish the community finally settle down on a stack at least for a decade.. shifting the backend every few years doesn't do good for dev productivity.. (had to recently use Go due to peer pressure. while performance wasn't a concern it was purely due to the "feel" that Node.js is not good enough for serious backend work - lack of multi threading , potential future performance and scalability etc.)
Would you mind enumerating them? I have an idea of what they are but curious about other perspectives.
My sense is that code sharing is not that common between a Typescript frontend and backend. You mostly need generated request/response data types but I don't think there's that much shared behavior because you can't import any of your backend-y logic (database, auth, external APIs) transitively into your frontend.
I think primary gain is what you've hinted at: 1 ecosystem and it's easier to onboard fullstack devs.
Problems I personally have with it:
1. no exact object types in ts as in flow - means they have to be emulated by destructing, sad, but you can live with it/you have to be careful
2. transpile times - but recent experiments with swc for tranpilation and deferring typecheck to run concurrently while tests are kicked off after swc finishes look promising
3. type system could be a bit smarter in few places, but no blockers so far
I'd recommend but with caution - spectrum of developer's competency is closer to php (almost anybody can do it) than the one of languages like ocaml/haskell/rust and others (where entry bar is higher). Vet your dependencies, hire competent developers and it can work very well.
Some of libraries we're using:
- https://github.com/appliedblockchain/assert-combinators - light, runtime type assertions ("parse, don't validate" style to avoid illusion of type safety at io boundaries)
- https://github.com/appliedblockchain/tsql - functional, tagged template based combinators for sql generation
I personally ran mission critical node services that interfaced with over 100,000 simultaneous compute nodes in AWS.
Here was the meeting:
https://www.meetup.com/pdxnode/events/142646682/
* Ben Acker will share about some awesome drawings and tales of Nodejs within Walmart Labs.
That is, where "mission critical" means "critical to some particular business". Not guiding rockets or critical medical use, etc.
Also as a data service for connection pooling databases that don't support connection pooling with supplied drivers or server-side.
Live medical data processing, large ETL pipelines, and coordination systems that set 100% uptime as a goal and any incident would have _very_ thorough RCA, retrospectives, and accountability reports.
While traditionally these were built with things like Erlang, Java Ecosystem tools (Camel, etc), the only time that using node had serious downsides was when integrating to particular languages ecosystems as a second class citizen.
Examples:
• Kafka. Until recently the node-rdkafka wrapper had quite a few bugs compared to the java client. We ended up writing our own internal client in typescript. Performance was worse, but we had easy scalability of our producer services and we were able to track down and resolve any issues quickly.
• z3. There hasn't been an official build for node yet. We had built a wrapper to use a specific fork of z3 that we had, which allowed identification and distribution of shared subsets of problems. This worked with an etcd-like streaming consumer where you would get live-pushed keyed-problem subsets and utilize those in a local in-memory cache to speed up solvers that overlapped.
• Distributed Actor-Like framework. Obviously Erlang, Akka, Akka.NET, etc are the prior art here. It didn't take too long to have our team analyze these and build out mimics in typescript.
• Wrappers for specific C++ statistics libraries. Some of our ETL pipelines would enrich data with a pass on certain identifiers/classifiers/aggregators. For a few of these we created js/ts wrappers, but it would have been nice if they existed.
• Standard Library. We took a microsoft-like approach and just created a standard library for ourselves. Tested and with lots of features, it meant that we rarely had to reach outside of our ecosystem for Collections, Encoders, Crypto, etc, and that they were all documented to our internal standards. If there was an issue, you had someone you could ask and get an answer within the hour.
Unfortunately all of the above is proprietary and we weren't allowed to release any of it.
We did retrospectives on technology choices and limitations once a year, to learn from decisions made going into the future. Each time when Node came up, the general consensus was "we could have done it in Java I suppose, but the Typescript/Node combination was much quicker to iterate on and we felt more confident in the solution after the fact".
Were I to do it over again, I probably wouldn't choose node, but my problems with it haven't had to do with static typing or type errors--we don't use typescript. Where we've continually struggled is indeterminacy in process control and error handling and writing robust services in light of that.
Typescript/Node.js/GraphQL back-end with React/Relay/Typescript on the front end.
https://github.com/coralproject/talk
It's pretty nice having the whole code base share types, syntax, structure, etc. It's served us well for many years!
Some of our clients include: The Washington Post, New York Times, Wired, USA Today, and Financial Times
IIRC, the performance of Node was ok but clearly worse than Go/Java/etc. Uber was using JS not TS back then, but the real issue (at least when I started) was lack of a defined interface for the API/mobile app communication. That was eventually addressed by adopting a forked version of Thrift.
It also used Node for a very core part of the app, and it was Node 0.10 to boot, but my understanding is that that's on the way to deprecation.
Microservices themselves are all in go or java these days.
Using Node.js for (large scale) mission critical backends, mostly in JS, but (on the topic of typed stacks) more and more of it is becoming Typescript.
> Wonder if Node.js will ever get wider adoption like Java got.
I'm not sure if it it will ever go as wide but it does seem to be going that way.
The dramatically larger ecosystem and community is great, but notably the static typing is far more powerful in practice. I really wouldn't pick Java to improve type safety nowadays.
Huh? Node is almost dominant for all kinds of API and web backends...
[0]: https://jobs.lever.co/substackinc/69f5ed72-9a51-404d-9db1-20...
import { setTimeout } from 'timers/promises';
await setTimeout(1000);
console.log("awake");
(But note that you'll have to activate ESM mode to write this script, e.g. by writing it in a `.mjs` file instead of a `.js` file or by adding a setting to package.json.) https://redfin.engineering/node-modules-at-war-why-commonjs-... /\*
\* A sleep function that returns a promise.
\*
\* @example
\* Sleep for 100ms
\* ```
\* await wait(100);
\* ```
\*/
export async function wait(ms: number) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}const wait = require('util').promisify(setTimeout)
It doesn't need to be that tricky.
My initial thoughts were “urgh I just want to have .js files in my projects” but I’m wondering if I’ll warm to them given that they make things a lot easier.
Are people eventually just all going to use .mjs files for everything?
I prefer my batteries included. Also importing from "timers/promises" isn't a global namespace.
The most common stuff I like to be part of the standard lib, either node or javascript, but it works fairly well now I guess so no biggie.
That said, I'll probably spend more time searching the node docs for how to import/use it than just implementing it myself.
OTOH I use promisified timer in almost all of my web scraping scripts, to reduce the load on the server, so I'm glad I'll be able to drop this thing from my utility library.
Also please be sensitive and don't use "kill" in new code. ;) We already have to deal with "abort".
Yes, a way to terminate down-stream. It turns out to be a pretty messy problem. I didn't know AbortSignal was in Node now. It's been a while since I revisited this issue. I should read more.
> Also please be sensitive and don't use "kill" in new code. ;) We already have to deal with "abort".
Point taken!
"The right tool for the right job" and all that jazz.
Observables are neither a part of the language nor a part of the Node api. I suppose that was what the parent's criterion.
I invested quite some time on node.js and eventually bailed out and now am using other alternatives. It did not work out as not all applications need those async-logics which made code unnecessarily difficult.
Nowadays for me, nodejs along with npm/yarn are just more of a frontend tool, which are still very useful and essential.
Is it a good idea to make hype a relevant factor in choosing web or app's architecture?
I know it's possible and that some teams do it, but the story wasn't great with (much) earlier versions of node. Some teams just wrote their stuff in another language and just use a child process in node to call it, serializing everything as a string and DE serializing it in the other language. The problem with that though is that you suffer a pretty decent performance penalty serializing and deserializing, and though it still might be worth it, it's also not great since some teams actually just called similarly to how you'd call a shell script.
Is it much better than that now?
That said, in my own experience it was seldom worth it to rewrite something in C++ for performance sake. After rewriting some computationally heavy part as a native addon, I often ended up gaing only ~20% more perfomance at best when compared to properly optimized JS implementation, and even that was not guaranteed since V8 improved rapidly. That was not a good enough reason to keep a whole different tool chain around, so I'd end up going back to JS.
[1] https://medium.com/netscape/javascript-c-modern-ways-to-use-...
The correct way to do this is to write a native addon that uses libuv to create your own thread (`uv_thread_create`) that does all the interaction with the GUI APIs. You then manage your own message queue to pass messages between your GUI thread and the V8 thread (using `uv_async_send` to invoke a C function that dispatches events from the queue into JS-land).
I'm curious, because I'm useless at RegEx.. But will this break current RexEx implementations ??
> ..We propose the adoption of an additional indices property on the array result (the substrings array) of the RegExpBuiltInExec abstract operation (and thus the result from RegExp.prototype.exec(), String.prototype.match, etc.).
> This property would itself be an indices array containing a pair of start and end indices for each captured substring. Any unmatched capture groups would be undefined, similar to their corresponding element in the substrings array. In addition, the indices array would itself have a groups property containing the start and end indices for each named capture group.
> NOTE: For performance reasons, indices will only be added to the result if the d flag is specified.
https://github.com/tc39/proposal-regexp-match-indices
From given example:
const re1 = /a+(?<Z>z)?/d;
const s1 = "xaaaz";
const m1 = re1.exec(s1);
// indices are relative to start of the input string:
m1.indices[0][0] === 1;
m1.indices[0][1] === 5;
s1.slice(...m1.indices[0]) === "aaaz";You have to scroll down all the way to "Node.js ES2021 Support" to start seeing features that work in Node 16 but not Node 14 (the current LTS version). Of course, it's possible to use Babel to bring those features into Node 14, but I enjoy leaving it out of my toolchain when possible.
Apple presenting some major hardware news today. Perfect time to release v16 :)