The JavaScript ecosystem is delightfully weird
fly.io
fly.io
It also didn't help that Node was fixed at 0.12 for years and years, and we had the IO.js fork until Node was released by Joyent for OSS community members to take over. That caused more issues to boot.
Also the whole bundling fiasco started with Babel, which wasn't a bundler at all and instead started as a means to provide polyfills for supporting "old browsers" (really, IE). From that whole thing came the concept of "evergreen browsers" which is a term that has largely fallen out of the common vocabulary with the rise of Edge.
Now we have "anything is a valid feature request" TC-39, and "it's really just Google at this point" browsers dictating how the web works.
It's a nightmare. As a maintainer of several large JS packages, and being so dreadfully burnt out on JS, there are other words I'd use to describe the whole thing than "delightful".
I’m not altogether against giving it a different name. It’s very limited compared to what proper ahead-of-time compilers manage. I’d really like to see some actual effort put into partial evaluation and symbolic-execution-guided code simplification and dead code removal. Google tried something a little like it in Closure Compiler’s advanced optimisations mode, many years ago, but hasn’t really kept it up; and Facebook tried some five years ago with Prepack, but quickly gave up on it for unclear reasons.
My first project that used JS was in 1996, so I've been along the ride every step of the way. Up until today where I am working with all of this on an Angular 15 enterprise project.
I actually would describe it as delightful, compared to what it was like only a short 10 years ago. 1996-ES6 was painful.
I understand your pain as maintainer and am also burnt out on ... um ... 27 years of JavaScript. Yikes.
But now it can just be written in TypeScript and I'll let the transpilers and other tools handle the details.
It is so much better.
[EDIT] Though I actually agree that it's nearly-tolerable now that we have TypeScript and async/await to force what always should have been the default behavior.
It's always getting better, and always has opportunities to get better
The Web APIs are pretty lacking:
* WebUSB has only been available for a couple of years
* WebGPU is only now becoming a thing despite the aborted attempt that was WebGL
* Raw TCP/UDP sockets are still experimental
* WASM is still struggling to solve the scaling challenges to make it possible to make available a large portion of existing software as libraries for JS to interop with without overhead.
* WebCrypto doesn't have streaming hash support & fails to standardize protocols that are relatively popular (e.g. ED25519)
From a language level, there's all sorts of footguns/edges that can't be fixed due to back compat and the language is both slow in adopting good features but also fast to adopt features that don't work too well or just plain annoyances when switching between langauges (e.g. did any/all really have to be unique and called some/every?).
The ecosystem also has large annoying challenges with TypeScript being super slow to type check even small projects, a mess of bundlers to pick from (most of which are ass slow except for ESBuild and maybe SWC), linters (only really ESLint in the game which is slow for TS), formatters (prettier which is slow but thankfully there's now dprint), ES/CJS bifurcation that's a nightmare to manage, tooling that only works with very specific combinations of things, etc etc etc.
You can usually build something passably if you know what you're doing but it's a mess for someone new entering the field and even after having spent some time in it I'm finding myself futzing with project settings quite a bit to accomplish some slightly off the beaten path combination of tools.
Before long that "actually good" is lumped in with the time when it was bad... but now, of course, it's actually good!
I've never seen the need for Deno. Every library I've written that has more than a few hundred users has inevitably been spammed about "Deno support when?" which also turned me off from it.
But anyhow, boy oh boy, look at what we have today.
From my quick research, it looks like the initial release of google's closure compiler, which had some amount of tree shaking, predates Coffeescript by about a month.
At the time I laughed. Guy must be having a bad day. Javascript rules, look at this widget I made.
Cut to a few years later. I am fed up with React, and the entire javascript ecosystem in general. The trend-based, article-driven development, the new framework/pattern you have to learn/unlearn every six months, the SPAS that made a simple web app spool up the user's laptop fan with all the javascript it was processing just to do basic stuff we could do much more simply in the 90s.
I ultimately quit being a developer in 2019, switched to doing design full time. I still write javascript for personal projects, because it's the thing I'm most familiar with. But, only vanilla javascript.
Javascript rules, but also: f*ck javascript.
>Guy must be having a bad day.
He was having a bad day because he was doing stupid things with the code he wrote that led to problems. I've never had a problem with Javascript's type system, or having the wrong type show up where it shouldn't. I accepted the dynamic nature of JS long ago when it first came out in Netscape, and I adjusted my coding style accordingly. And Javascript types are not a mystery, type coercion is fairly simple and doesn't produce unexpected results if you actually understand the language. If you don't understand the language (or any programming language), then writing things like "F*CK JAVASCRIPT" in massive letters on a whiteboard is something that might happen.
Different languages have their own strengths and weaknesses as well as generally accepted coding practices and sometimes different paradigms. I find the folks who struggle the most are trying to write JS as if they are still a C# or Java developer so they constantly run into square peg round hole issues and blame it on the tool. I love JavaScript. I also love C#. But you've got to approach how you solve problems with them differently. How you write long term maintainable code in both is different.
Weird take. Because the best way to write maintainable JS by far, whether you're using TypeScript to enforce it or not, is to keep all the lessons that informed the design of Java in your heart. Go ahead and decompose your program into classes and interfaces, eschew with clever tricks and just focus on readable code instead, and make sure you or anyone else can without much difficulty work out at any given point what the "shape" (type) of a value is.
I must be living in a parallel world cause I write React & TypeScript code on a daily basis (among many other things, including writing Python and SQL too), I've done it for a few years now and I quite enjoy it. Last time I had to learn a new "pattern" was Hooks I guess, and it was like 3 years ago? I was hesitant at first, I didn't have any issues with class components... but Hooks actually increased my productivity and simplified my code. Otherwise I feel like coding in React hasn't changed much over the years. I would definitely not want to go back to the technologies I was using in the 2010s.
Its so delightfully simple at its core. Typically super easy to debug. Extremely composable and reusable.
I’d much rather have some dependency discipline and a vibrant fast-moving ecosystem than the opposite. Just pick the fruit of other people’s labor when it’s ready instead of dogfooding questionable and bloated deps.
Oh yeah and do not read medium articles about JS.
Maybe it’s worth logging off Twitter for a while and understand that you can just not pay attention to these ‘trends’ and learn a new pattern every six months and you’ll be absolutely fine. Yes, ecosystems and communities can encourage this, but individuals also have got to take some responsibility for opting themselves out (or into) this hamster wheel.
I’ve seen this React Server Components stuff on the periphery for a while now, but I don’t really understand it and I don’t intend to for a while. I’ll let the twitter us hype beasts sort out what they want to do with it and I’ll circle back and check out what it’s like in a few years.
A good example is an experience I had a few years ago (circa 2018)
My work acquired some new software which published some results using a REST endpoint. I wanted to pass some parameters to the endpoint get a response and display the response on a webpage.
I'm used to working with Python/R and SQL databases it is relatively easy to write code in these languages to execute a SQL query and publish the result.
To do the same thing with endpoint I had to learn about ajax, asynchronous code, callbacks and then later deferred promises. What I thought would be relatively simple ended up being horrendously complicated to code.
I think part of the problem is the javascript language changes and adds new features so rapidly it is very hard to search google for help in my case I found code examples using callbacks, I had massive issues trying to make it work only to later discover that was old way to do it and the new way was to use Promises instead. Most of google searches I made went to horrendously outdated stackoverflow posts and there was no obvious way to tell if answer was best practice or not.
Doing the same google search again today in 2023 it looks like they have reinvented how to do it with something called "Await" now.
Maybe it's more simple in Python but this really isn't that complicated, it's certainly not a valid criticism of JS.
Nothing wrong with being C++. The reason JS is so massive and weird is because it's the language that everybody uses, or has to use at some point. Upsides and downsides.
https://www.reddit.com/r/ProgrammerHumor/comments/621qrt/jav...
* `var` is no longer a thing.
* Even `let` is less common now.
* Using closures and prototypes to enable functions to be used like classes and have private variables and static variables, have been replaced with proper classes
Nowadays if you want to use the good parts of Javascript, just install eslint with insane defaults and let it tell you if you're trying to use the non-good parts
Looking at the book now, I still like some sections like "Curry" and "Memoization".
where do I find these insane defaults?
On the other hand, it's a testament to the comment being written (or at least edited) by a human, and not an LLM right?
First, find the docs for ESLint and each of the integration packages that you've installed for each major dependency. Then just set each rule to the strictest setting. Then as you're developing, you'll start running into overzealous rules, prompting you to either disable the rule or write some override/exception.
TSConfig, on the other hand, isn't extensible so you can just throw a couple configs from github.com/tsconfig/bases in your `"extends": [...]`. The base config `@tsconfig/strictest` might be of interest to you.
You'll able to accomplish exactly the same with both, so why create yet another way? Seems bit wasteful..
JS as a language isn't nearly as big as C++ or, say, Swift... I'd say Python complexity is on par or even higher than JS, in terms of core language features.
There are some language features that are outdated but it's hardly like the C++ situation.
For objects with methods you can make literals, use a constructor with new and have prototype methods, use a class, or use Object.extend, or Object.create or probably other tricks.
For async code we have callbacks or promises. And promises can just use the Promise class and .then(), or you can use async / await. And the promise class also has polyfills in npm if you want that instead. Or there’s tricks with generators.
Functions can be written with function foo(), or const foo = function(), or const foo = () => {…}. Or const container = { foo() {} }. Or use class methods (which have different syntax again).
Importing external code can use commonjs (require()). Or import statements. Or dynamic import. In the browser you can use multiple script tags and have scripts assign their library to a global object. In nodejs code can also change what require does.
I can keep going - don’t even get me started on bundlers. You’re probably right - the language probably still isn’t as big as C++. But it’s big enough that almost nobody knows every javascript feature. I was around in the early days of nodejs (0.4 was my first version). At the time the design of the language, and of nodejs, seemed simple, clear and cohesive. Don’t get me wrong - I love a lot of the newer features. But javascript as a language feels like a bit of a bloated mess.
> There are far more ways to write javascript than any of us want.
Some of the examples you cite are due to JavaScript being minimalist though. For object creation there are a few different syntactic methods but it is straightforward how they compare semantically - they are basically equivalent. C++ has numerous methods to do similar things but they each have their own numerous rules and exceptions. Ironically in C++ there is often only one way to do something a certain way, as a similar syntax for initialization may (not will) do something completely different depending on external context - such as merely putting parens around a set of braces.
The diagnostic output of the compilers alone when you misplace a symbol is longer than many JavaScript libraries.
> But it’s big enough that almost nobody knows every javascript feature.
I don’t think this is true. It just isn’t that big of a language. The examples given certainly don’t paint a picture of immense complexity - a few things have accreted during the years, it’s not outside of simply just learning them in a few weeks.
It’s not just about the length of the spec (which is much shorter) but the complexity of those specified features within the system as a whole - JS as a system just isn’t relatively that complex.
> the language probably still isn’t as big as C++.
For anybody that does modern C++ and JavaScript professionally (as opposed to those that are content continuing to write C++ like it’s CFront) this is a coffee spitting understatement.
Working Draft, Standard for Programming Language C++ from 2020-01-14 (1815 pages): https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n48...
I'm not sure what's the "correct" spec for the current C++ standard is. Still a big difference between these languages, but 846 pages isn't exactly small either.
Intel 64 and IA-32 Architectures Software Developer’s Manual, Volume 2 Instruction Set Reference (2552 pages!!!): https://cdrdv2-public.intel.com/774492/325383-sdm-vol-2abcd....
The ECMAScript language spec is closer to the C spec than the C++ spec, by a large margin. I'm not sure how much you can deduce about relative complexity from these figures.
Note: I'm a moderate JS dev so correct me if I'm wrong.
Meanwhile, the ECMAScript spec really does not leave very much wiggle room. It (like every other web standard) is almost just documentation or often even pseudocode-ification of an actual implementation... Certainly makes you think.
No, it's not massive compared to C++, it's actually quite simple. No explicit pointer management, no memory management, no user defined operator overloading and so on and so forth. The only difference between classes and function prototypes AFAIK is "super" late binding, otherwise one can replace classes with functions everywhere they want.
The problem isn't javascript itself, it's the different runtimes that have different API. But the javascript spec is tiny compared to C++.
As for the ecosystem, it's mostly node's that is a mess, as the result of core Node API being barebone. Browser API are actually quite extensive and do a lot of stuff, from shaders to XML parsing to sound generation, but this isn't javascript it's the DOM/Browser API.
JavaScript === C
TypeScrit === C++
You can shoot yourself in the foot writing vanilla JavaScript. There should be a book "TypeScript: The Good Parts" though: the language brings a lot of stuff that is better not to use.
No classes in JS was much better than with. As someone who used and contributed to CoffeeScript, I was initially excited by them but in retrospect, they've been a huge negative IMO.
Douglas Crockford saw it immediately: https://www.youtube.com/watch?v=PSGEjv3Tqo0&t=300s
I'd rather either Clojure or Java to using Scala and having all the possible complexity and interactions between paradigms it makes possible. Sometimes less is more.
It’s not so much that you can’t use a MOP in JS, so much that people don’t, and will look at you funny if you do.
As a lover of simple and straightforward code, I never used the MOPs—I hand-coded “class.prototype.method = function()” like God intended*—and I’m happy the standard uses that more traditional approach. But I can see how someone who did use a MOP would feel that the class syntax is a step backwards.
*that’s a joke.
I also don't understand the big deal with arrow functions. Yeah I use them, but they're basically regular functions except slightly shorter to write. `async` was a big improvement, though.
Most users just use arrow functions as syntactic sugar. But it's really good syntactic sugar.
I accept that in gigantic apps worked on by multiple teams, and libraries shared with 3rd parties, Typescript makes sense. But 90% of the time I see it used it's with a smallish node app or SPA worked on by a few people, and all Typescript does is slow things down.
I feel like I can count on one hand the number of times I've gotten burnt by a run-time JS bug that a compiler would have caught. I just don't see that as a strong use case for the overhead and development drag of TS. I only see sharing lib-ish code across teams as a net benefit of TS.
99% of the time when the TS IDE complains over something that a JS linter wouldn't have caught, it's just because something wasn't defined properly in TS, not because it's an actual error in the code.
Close! C# programmers. :)
Well... C# .Net developers, as Microsoft found, correctly, that you can't build complex products easily with a lack of types.
I also don't think many program in vanilla Javascript; it seems everyone is using JSX.
Complex apps still had lots of tests, which basically solve the same problem as TS is trying to address, without having to write a different language than what gets run by the browsers.
Obviously tests are still useful in TS, but not as many I think. Also, the feedback loop of a static type system is, IME, much faster than with tests only.
On the flip side, the TS type checker is painfully slow, the code is noisy, and you’ll waste a lot of time satisfying the type checker.
For me, the sweet spot has been dynamic (runtime) type assertions in JS. Fast feedback loop, no transpilation hassles, good error messages when type-related errors occur. Downside is that now the editor can’t statically analyze types.
Lately, I’ve been experimenting with using swc to transpile TypeScript without typechecking it. Now there’s a fast feedback loop and I use the IDE to discover type errors. (And the integration build checks types too.) I’ve just recently started this experiment, so jury’s out on whether it’s better than runtime type checking.
And my editor does the autocomplete thing seemingly just as well as the autocomplete I get from TS, even when I just write JS code normally.
I said easily. Types remove whole categories of errors.
I think the industry has generally found dynamic typing to be a mistake. Most dynamic languages are now trying to retrofit types.
I enjoy coding in vanilla JS - my canvas library is 100% vJS, with a hand-written .d.ts file in the root directory in case anyone wants to import it into their TS project.
That said, I also enjoy jogging along cliff edges and sheltering under trees during storms so I'm not the sort of person who should be offering programming advice...
The great thing is it's powerful enough that you don't lose JS's dynamic features, but your code becomes much more self documenting and clearer, and your IDE has a much better idea how to support you. I would never go back to vanilla JS, typescript saves me way too much time and from too many headaches.
I think you experienced a different JS than I did. JS has always had classes, they were just "harder" to build/use and every "Framework" had a different mixed bag of "utilities" and patterns to work with it and they weren't always compatible. (Mixing jQuery style classes and Dojo style classes was "fun", for two random examples. I could go on all day about the long tail from MOO Tools to YUI to Backbone to…) ES2015 class syntax just standardized already common patterns and increased interoperability and cleaned up a lot of footguns regarding Prototype-style inheritance along a "garden path".
The class syntax garden path is much nicer than the weed-filled hedge maze it mostly replaced.
I agree. Honestly I don't understand the obsession some people in the JS world have against classes.
React components with state made more sense with classes than hooks. And yeah some people argue hooks are composable yada yada but if you need a React expert to write a useInterval hook to use a fundamental language feature, then maybe the model is not a great idea to begin with.
https://overreacted.io/making-setinterval-declarative-with-r...
Of course I know I'm in the minority here.
To be fair, you can build a lot of React components without ever feeling a need for something like an HOC and never deal with some of the inheritance problems that Hooks were built to solve so some of that "classes are a better way to write components" feeling is that one has never quite before had the multi-inheritance itch to scratch that Hooks solves for. It's obviously hard to judge a tool when you don't know if you've had the problem it solves for or not.
That said, I don't miss higher order components, but I do find myself reaching for renderprops sometimes. I think it's still a great pattern.
Chrome DevTools is the de facto debugger of Javascript, which becomes apparent once I have to take advantage of Javascript's capability of moving beyond the browser, on alternate runtimes. To debug node.js for the server and Hermes for my apps, in both cases I need to use the Chrome DevTools debugger which uses the Chrome Debugger Protocol. In the case of Hermes, the Chrome DevTools that comes with React Native doesn't even come from your local copy of Devtools, but is dynamically loaded from https://chrome-devtools-frontend.appspot.com/.
As far as being a protocol goes, I have yet to see another viable implementation of a Javascript debugger. To profile my performance or check my memory usage, I need to use Chrome. Even worse, both node.js and Hermes have strange issues pop up with the debugger connected. In the case of Hermes, it is acknowledged that the Javascript runtime is not fully compatible with Chrome DevTools Protocol, whereas node.js occasionally exhibits segmentation faults with the debugger connected, or falls into non-terminating computation when connected to certain complicated programs (such as npm...)
It worries me greatly that to debug my code, not only must I have Chrome installed, but I must be connected to Internet and trust that some particular domain, controlled by presumably Google, maintains it. I struggle to understand why no alternative debugger for arguably the world's most popular language exists, or at least a local, independent copy of the debugger that is untethered to the whims and desires of an entity as trustworthy as Google.
I guess I'll be having to whip up at least the latter option (which seems feasible enough, if a little tedious; with ungoogled versions of Chromium available by some kind souls as a starting point) when have a bit more spare time, to keep my sanity checked.
More importantly though, if you are that distrustful of Chrome, you probably should not be using Node because it is based on v8, the Chrome Javascript runtime.
1) ability to debug locally, without an Internet connection.
2) ability to debug reliably, without fear of debugger features becoming 'updated' when one needs it most.
The fact that no independent debugger, without the Leviathan that is Chrome, exists, only hides this aspect even more, hardly doing justice to the importance of debugging in the practice of software.
Regards to the Firefox and Safari debuggers, they do not seem to be viable in practice with the alternative Javascript runtimes mentioned, both very popular and widely used, which is the reason that I claim Chrome DevTools to be the de facto 'Javascript debugger'. Neither do the two tools offer a debugger independent of the browser, as far as I am aware.
Still, unwilling tight coupling with an IDE is still quite unsatisfactory.
Here's an overview of some of the tools in case that's useful: https://sequoia.makes.software/debugging-nodejs-talk/#55
Your link lists the Chrome debugger, IDE debuggers, and the node inspector.
The node inspector is essentially deprecated. IDE debuggers more or less piggyback on the Chrome DevTools protocol, and although I mentioned I have not given them a fair try, but they definitely seem less official, featureful, and well-supported compared to the Chrome debugger. The fact is, this aspect of Javascript seems to have, unceremoniously, already fallen into Google's sole leadership, direction, and discretion, by force or by will.
The Chrome debugger, as mentioned, exists and is probably the most well supported of all debuggers, and is what I use in practice. However, as I mentioned, even 'the best', which is Chrome, does not work very well, exhibits usability regressions per the cadence of Google (e.g. blackboxing used to work, but is very broken today), and moreover compromises basic functionality and freedoms, which comprises my dissatisfaction.
In a better world, we would have something that is native to the language (not a browser), versionable, free, featureful (e.g. profiling and memory debugging), and accessible from the shell (e.g. other languages have gdb, pdb). It would be a good thing for a protocol to actually have multiple implementations.
Something that may at least recover basic functionality from the Chrome DevTools would be to degoogle it for hermetic usage, and separate it from the browser proper. As I mentioned, I am looking forward to make that happen.
It can't help enough with Node or Hermes, but those are too tied to v8 and thus Chromium internals to start with. (Which definitely leaves some questions about the current JS monoculture.)
Maybe it’s because it’s the only thing I’ve ever known, but… I like it?
I guess if I hack around on a side project and want to use vanilla JS, it’s the Wild West and there’s no rhyme or reason for anything (and everything looks gross).
But working inside various frameworks have been pretty enjoyable for me.
Side note: there’s also this hilarious video about the… delightful nature of JavaScript from 2012:
For the longest time doing the most simple thing in any programming language, putting code in a separate file and loading it to execute, was nearly impossible in JS and required learning and picking sides in an opinionated loader battle. It was confusing and pretty bad for newcomers.
Nowadays all that drama is settled and the core of modern JS is quite nice. I like it more than python to be honest.
It's all a bit of a cambrian explosion but it at least means you run into "this awful API has been baked into core and now we're stuck with it" less often.
I now prefer comprehensive standard libraries.
Using a mixture of old, deprecated versions of Webpack, Angular, Babel, and Typescript, and a very big pile of code with plain bad (if not plain wrong) type annotations I wish that statement applied to me.
Constantly attempting to keep all this nodejs stuff without vulnerabilities while migrating the least ammount of stuff at once is a daily challenge.
And that comparison is pretty low bar, everything involving say pytorch is a flaming pile of bad waiting to explode.
https://developer.mozilla.org/en-US/docs/WebAssembly/Underst...
I've tried at various times to get caught up, but it seems that every time I find articles / blogs that talk about How Things Are Done at the time they're written, with only the briefest nod to how it's better than The Old Busted Way (probably because the authors, being steeped in and surrounded by javascript for years, think that their readers will also be similarly up to speed).
Meanwhile, I feel like a historian in the year 5000, reading recipes from 2023 and wondering whether people used dog milk or cat milk (because those were the two kinds of mammals that most households had available).
Does anybody know of other resources that go into more depth on the evolution (and specifically the Whys) of the javascript ecosystem?
As the OP points out, a lot of what happens now is an artifact of the history of how these things have developed, and about which things were prioritized over the years. Many of these choices made sense at the time but may no longer be necessary, and some things were definitely lost in the process.
When we were developing Cappuccino, which includes its own transpiled to JS language (possibly the first such general purpose language), one of our important goals was making sure the compiler could run in the browser itself so no external build tools were needed; everything worked just dragging index.html in the browser and writing code in <script> tags if you wanted. Security changes in how browsers handle file: URLs made this harder to do, but anything that simplifies the process of actually running code is very welcome.
This is how "delightful" it is, and is the reason I'm waiting for it to die.
Every couple of years we decide on the 'no no, definitely this time we have it all figured out, trust us, just use X' "solution" to the problem of JavaScript. We have the definative 'this is how you do it', until the next one.
I'm there with ya, but I wouldn't hold your breath. I'm trying to minimize my JavaScript exposure by using streaming, and it's going well enough with a minimal JavaScript "runtime". However, I still find myself with thorny edge cases like "I need a better date/time picker", "color picker", or a drag and drop calendar planner.
I find myself frustrated with the ecosystem, and I'm debating how large the set of exceptions are to my ideology.
The DOM and the HTTP api (or pretty much all browser APIs for that matter) should be interfaces that can be implemented in WASM code. I have no idea why this hasn’t been proposed let alone implemented. I mean, why give us the ability to use other languages if we can’t implement the (browser) APIs?
Or life in general.
There’s plenty good and plenty bad. It’s no use fixating on things you can’t change. Focus on what you can do.
I'm content to keep working with it, and I'm so familiar with it that for small tasks it's kind of my go-to. If I was building something I wanted to be long-live a future-friendly, I might be hesitant to run with React at this point. To be honest though, I'm not sure what's better than would be a clear contender for having similar staying power. I wouldn't complain if that turned out to be Solid.
Once EcmaScript adopts optional static types or some kind of standardized type annotations [1] I will probably use those. At least in Node, where I have more control of the runtime version.
Especially with esbuild which has made this simple and fast, one could even say it has saved javascript.
Maybe I just have exceptional memory but I rarely encounter a problem that would have been solved by using TS.
At my current job we do have a lot of untyped Python used by tons of people, and it's fine. People can read the code without it asserting in every line what each variable is. You just make sure any widely-used APIs are documented properly, which typing doesn't really help with. Also anything modern is more microservice-oriented which comes with nicer boundaries, and everything has tests (which again typing is no substitute for). Typing seems like a mostly outdated thing for application-level stuff.
I still think JS is a nice language although I tend to side with Crockford (before he started promoting the "next" language) in that JS has some good parts, and you can write clean and powerful software with it if you ignore most of its warts (even if you're using Node). My best advice is be very careful with what dependencies you choose; and also, don't feel pressured to be at the bleeding edge all the time. The Node/React world is a constant hype machine that flip-flops on best practices every 6 months. Be very skeptical of them, and don't let them spoil JS for you.
by the way, comparing to angular and vue2-vue3, react is actually the one without python2-python3-alike breakages over the years to me, I would say it's the best out of the 3 options(angular,vue,react) so far, which could explain by market share that it remains to be dominant.
My original motivations were: Deno doesn’t support Raspberry Pi and I was running lots of short-lived processes to support incremental rebuilds using a Makefile. In the end, my requirements changed, so I’m not using QuickJS, but it was very easy to pick up and use.
So: portability, startup time, and small code size seem to be the advantages of QuickJS.
Indeed, React the library is generally stable. But React the ecosystem is not; best practices change every 6 months. Libraries gain popularity and then are abandoned, or people just realize the cost of using them. SSR vs SPAs? Wait you're telling me CRA is basically deprecated now? etc etc.
For my last project I wrote just plain old javascript without any frameworks, but I did use dev dependencies such as the ones I mentioned above. It was a breeze to implement things, but I do understand that the benefits of frameworks like React become clear in larger more complex projects. So all in all I don't really know what should I think about the current state of the ecosystem, nor am I really on the edge of the wave of progress, but the kind of feelings I often get is in the lines of 'is this dependency x really needed here? what does it do? oh it does this small little thing, why is it here??'...
Delightful? Try managing a monorepo with internal dependencies and multiple target platforms and you will immediately and firmly say 'no'.
does spring boot bring it's own dsl and compiler?
Same thing for serialization things, you define interfaces, the actual classes often just pop into existence by generated bytecode.
It's also not unknown to bring JSP/EL (literally requires a Java Compiler embedded in your server to compile servlet objects for you on the fly) or some other, on purpose less fully featured template things with their own DSLs like Thymeleaf to do the same job.
This is what I like to nickname "WebpackJS". Code that is simply invalid JavaScript and requires a carefully configured composition of webpack plugins in order to be used. I occasionally run into npm packages wanting to "import" a CSS file when I use them from ClojureScript, and it's always a pain. The good news is that these ar rare encounters, but it's still behavior enabled by people assuming you're using the exact same framework as them with the exact same Webpack configuration made by said framework.
I code single page apps that talk to business backends using JSON based RPC. All in plain JavaScript with some domain specific libs when needed. No problems so far.
There is, however, quite a bit you can do in it. TeX has been compiled to wasm[1], it's about 600kb uncompressed 90k compressed (the memory image with latex loaded is about 6MB compressed though - latex is a beast). I think anything computationally intensive would be a good candidate for wasm (it has int64).
Anyway, on practice all that means is a bit of lost performance on the DOM interaction. It's a big deal if you do a react-like framework, but the DOM has bad performance anyway, so people tend to not create react-like frameworks.
Everything was mucked up well into the 2010s with everyone chasing IE compatibility. And not even 3 years later, Chrome had taken over the world. That's a really brief window for anything to happen.
So, yeah, it's a better target than most general purpose languages. It's surprisingly simple to generate, much simpler than to write on. It is also a worse target than most languages specialized on being generated.
- The places it can run
- The ecosystem it can interop with
Not that it's a bad codegen target otherwise- it's high-level but performant for being so high-level, it's garbage collected, first-class functions, low-level primitives are available for optimizations, etc. But these on their own don't make it super unique
Like, even C programmers are willing to actually write C.
There's also a lot of C programmers that prefer to use C++ compilers in C++ mode for their C code to avoid direct contact with C specification bugs or some C standard libraries.
(Plus, early C itself was designed to avoid direct contact with Assembly languages which was designed to avoid direct contact with Machine languages some of which were designed to avoid direct contact with Microcode languages most of which were designed to avoid direct contact with TTL logic and TTL logic was designed to avoid direct contact with the useful properties of transistors for computation and so forth. Programming is turtles all the way down.)
(Also there are quibbles to be made about "at all costs". JSX is still a superset of JS syntax with a little bit extra added in. Typescript is built to be a superset of JS syntax. You can't write either without a lot of direct contact with JS. Neither seems like "at all costs" avoidance to me.)
I personally am the kind of person who tries to ship my stuff as a single statically linked binary that I can just drop in place so I look as WebAssembly as a way to participate in the browser ecosystem while avoiding the whole NPM/JS Tower of development tooling complexity. I don't begrudge others from wanting to play there though.
Only thing that ticks most of those boxes (IMO) is Kotlin. Anyone been down this road before (skeptic->using in prod)?
I also gave TS a serious try and found it pointless. Complicated the toolchain, made default stuff like the Node profiler not work anymore, and wasted tons of time on defining types that didn't actually catch any mistakes. Went back to JS. Turns out part of its strength comes from not caring.
Before that had used Java, Scala, C, C++, Erlang, Python, Swift, ObjC, Rust, PHP, and a little Golang.
Async/await's pretty new, is probably why you're seeing so many tutorials that don't use it.
If their JS docs are anything like their Android docs, Google's terrible about updating examples.
Another example from 4mo ago: https://github.com/kubernetes-client/javascript/blob/master/... (the catch at the end is a promise catch)
All of these examples appear to be top-level and perhaps they didn't want to write them as async functions or IIFEs, especially for error-handling code.
There's nobody to blame for this but myself, just wish I discovered earlier on how async/await works, along with other modern JS stuff that you won't see everywhere because it's new.
Something I use a lot in Rust is exhaustive matching and sound types, which Dart now has. It's a somewhat specific thing, but I like designing finite, well-scoped systems which can be handled and tested almost completely. Doing this in TypeScript is kind of possible but can be incredibly verbose and difficult to navigate for less experienced programmers. While the design patterns aims to simplify and eliminate errors, the type system can easily complicate it and introduce mistakes.
That's such a drag in my experience. For example, stuff like this can happen in TypeScript: https://www.typescriptlang.org/play?ts=5.1.0-beta#code/GYVwd...
However, TypeScript has come a long way and it gets better in this regard all the time.
Eh, deliberately repurposes. I don’t think “misuses” is the right word at all.
> abuse of the bundler
This also feels too strong a wording—though the fact that these are at least .js files (unlike .svelte files in the other case) makes the term “abuse” less unreasonable.
I mostly write C++ for a living, and I use code generators all the time. Generating C++/Java/Typescript/SQL/… from high level declarations.
Code generators are great tools for automating away the necessary but no-thinking-required parts of a typical app. I am typically able to code generate more than 90% of the application code needed to implement a new client/server business system. So why not use it?
No, it just requires a basic websockets implementation and a normal HTTP server. If anyone else like me loves JavaScript but thinks the above line of thinking is bananas, join me on the lifeboat [1].
I think the weirdness is a cycle kicked off and perpetuated by how accessible web development it.
It's a good thing that it doesn't take a comp sci degree to build a completely functional, professional looking and/or profitable JavaScript powered application.
In addition to the exclusivity of JS in the browser - the ease of becoming productive has been a large driving force of its widespread adoption. The cost effective nature (cross platform, ease-of-development, abundance of skill) has played a large part in its ubiquity.
This large number of developers has resulted in a large market for tool makers.
Tools are difficult to profit from, so toolmakers adjust their business models and marketing to suit.
As a result, a lot of developers write self promotional blog posts sharing "best practices" and plenty of impressionable decision makers dive head first into well marketed trendy tools/technologies that _may_ offer a benefit but often not proportional to their cost (vendor buy-in, additional complexity/reduction in project maintainability).
For example, front end projects tend to prematurely optimise with huge foundational features like SSR - without considering their use case, the performance trade offs (caching, amongst others) and other more ergonomic/cheaper/more effective, optimisations.
Despite not requiring it, developers tend to highly _highly_ couple their presentation logic to their application logic to the point where throwing away and rewriting an application is not an unreasonable sounding endeavour. People don't write an application that uses React, Vue, Angular - they write a React/Vue/Angular application.
The current meta has moved away from boring obvious procedural circuits to dense, clever, fancy functional circuits which I (controversially) find difficult to grok, modify, and debug. I certainly use functional code (like functional components are nice for simple use cases and .filter/.find are nice shortcuts), my feeling is that deep functional chains are perhaps overemphasised now and difficult to mentally simulate when reading (which you must do inside-out, holding each step in your head).
Testing is also a huge pain point. Developers tend to make extensive use of features like module mocking (`jest.mock('./filename')`) and avoid any form of dependency injection (not talking about DI frameworks, just simple property injection). If there is a hell, module mocks were sent to us from there. So many times I have made changes to a file where module mocks prevented tests that would otherwise have failed from failing. They are hard to track down, fail at runtime and... cries
Today, when I consider joining a new company and hear a project uses React, NGRX, Redux, Next.js, SSR, and a few others - I can almost immediately assume it's going to be a contribution and maintenance nightmare.
I still love front end even though it is an endless source of headache-inducing eye rolls watching people shoot themselves in the feet while confidently claiming it's the best way to run faster.
An originally decent idea gone terribly wrong.
But to be fair, I still maintain a relatively popular Chrome extension in old-school JS and that's still a pleasure to work with.
When they started talks about adding classes to the spec I knew I had to run away.
Maybe it's just me, but everything distinctive about prototypal OO falls firmly in the category of "please never actually use this in a codebase I have to work in".
There were so many shims to emulate that style of OOP.
I have a positive impression of fly.io overall, I mean they admitted they are still figuring out how to build tech at the level of their ambition and have it be reliable enough, but I might like to be a customer one day.
You may be interested to know TC39 makes the same "typo" at https://tc39.es/ right in the biggest header on the page.
> Specifying JavaScript.
Hm, maybe it's not a typo?