Lately I’ve been trying to learn kotlin... and man... that stuff (gradle) adds a weird amount of boilerplate to everything.
JS / TS on the other hand. It’s a package.json, or tsconfig. Not much else is required.
Jump into deno and you don’t even need those. Feels like JS is one of the better languages in this regard
It's a noticeably-more-concise-and-flexible option than what came before it, and the net result has probably been good. But it's next to impossible to understand and troubleshoot when things don't go perfectly. And similarly difficult to figure out what you need to do to achieve X, because who knows, it could be in any of thousands of locations, called anything, and there's not enough structure to let you infer what's reasonable and what isn't.
We're still not as bad as mobile development, but things are getting worse.
I swore off massive impenetrable abstractions like React eons ago and I'm saner for it. Abstractions are supposed to remove complexity, not treat users like morons.
The fact that there are debugging tools at the React level does reduce complexity. It means you don't need to understand the details of how React is implemented. You can just think in terms of React concepts (which are quite straightforward and have excellent documentation).
In React's defense, it's far from "impenetrable." In fact, its API exposes less than a dozen attachment points (considering render + lifecycle methods or their hook equivalents). It's a small and stable interface on top of a simple tree structure and an intuitive reconciliation algorithm. Most of the time you don't even need to reason about its logic, but when you do, it's understandable and debuggable.
I'm also skeptical that we should consider framework-specific dev tools as evidence of an impenetrable abstraction. As long as the tools strictly enhance the debugging experience, they are a feature, not a smell. They are evidence of a problem when they only exist because it's impossible to debug the API without them.
For example, Apollo Dev Tools "strictly enhances" the debugging experience. It provides a nice UI for GraphQL specific debugging sessions, but it doesn't break the "network" tab of Dev Tools. If you want to use apollo-client without its dev tools, you're no worse off than you were before adopting apollo-client. But you do gain something if you choose to use them.
Things just need to improve there, one way or another...
There are a million other JavaScript libraries that do not have this problem, for what it's worth.
> It means you don't need to understand the details of how React is implemented.
Isn't this the topic of discussion? Why shouldn't it be as simple as "React stores state in this variable" and I can just poke at it like any other variable?
Abstractions are great, but they all leak eventually. Being able to see through the abstraction is immensely valuable, regardless of where you are in the stack.
Don't confuse simplicity for its pernicious cousin convenience, which usually does not actually reduce complexity, but heralds it.
It's a library, but it does provide a runtime. As such it IMO makes sense that it would have it's own debugging tools. This is pretty common for complex frameworks. Other frontend frameworks like Angular and Vue do it. As do backend frameworks like Rails and Laravel. Or as another example you could look at Unity (the game framework).
You can still use the JavaScript debugger, and I do all the time with React code. But for React specific concepts the React specific tools provide a better experience.
> Why does React go though so much effort to obfuscate its internals to such an extreme? There are a million other JavaScript libraries that do not have this problem, for what it's worth.
It doesn't do it intentionally. It's internals are somewhat complex for performance reasons. Which other JavaScript libraries allow you to inspect their current state with the JavaScript debugger? That's what the React dev tools give you: state inspection. IME, lot's libraries make inspecting that quite difficult (unless they're using global variables).
> Why shouldn't it be as simple as "React stores state in this variable" and I can just poke at it like any other variable?
The problem is that you can't typically poke variables using the JavaScript debugger. To do so you need to get a reference to the variable. And you can only reasonably do that for globals.
> Abstractions are great, but they all leak eventually. Being able to see through the abstraction is immensely valuable, regardless of where you are in the stack.
I guess I've just never hit into the limitations of the React abstraction (and I've done pretty complex things). Nor have I ever hit a bug in the implementation. To me it's like my database or my filesystem: sure it's great to be able to peak under the hood if I really need to, but 99.9% of the time I'm super glad that I don't. I've had much worse experiences with Angular (1 and 2) where I frequently felt like the abstraction was leaking a lot.
You can debug React apps just fine without the React developer extension, but in some situations it will be much harder. And to elaborate, I work on React full-time and just use the javascript console and debug messages for 99% of my debugging.
I honestly couldn't find anything remotely similar in my search for to unearth React runtime internals. Maybe I'm missing something but literally every answer was "just use the extension."
Same for React. If you are working on React itself, or you need diagnose an actual bug in the runtime then you'll want to use the JavaScript debugger and step through. If all you need to do is work out why your component isn't updating then you can use the React-specific tool (the extension) to make your life much easier.
Your argument is basically the same as saying you'd rather view HTML as a giant string rather than in a tree view... the devtools basically present something that's linear (the tree traversal) in a tree view, it's not that bad.
Can be as simple as that: familiarity.
I read this as a complaint that React doesn't provide information on what's going on that you can see and inspect (whether true or not). The equivalent for Postgres would be if they didn't document their protocol and instead referred you to a special debugger they provided, and you had to rely on that instead, making use of gdb or the equivalent much more complicated.
Also, the react dev tools aren't really a debugger. There's no way to step through code or similar. It just provides an insight into React's internal state (the component tree, and any state contained within it). The equivalent would be Postgres providing a tool to inspect the contents of its caches or indexes, and the OP complaining that they can't read them when using GDB.
[0]: https://reactjs.org/blog/2019/08/15/new-react-devtools.html
Which makes my example more accurate barring two words...
> Also, the react dev tools aren't really a debugger.
All it takes to be a debugger is to provide additional info about a running process. Insight into React's internal state definitely qualifies IMO. Even if you think it doesn't quite qualify, Chrome Devtools are a debugger, and whether something that extends it to give better info is a debugger or an extension for a dubber is missing the forest for the trees.
That said, I'm not necessarily agreeing with the original premise, since I don't know how hard React is to introspect at this point (I know in the past some websites purposefully made it very hard on purpose). I'm just not sure the original comment's point of view can be boiled down to whether someone is familiar with the technology or not (and part of the reason I'm not sure might be lack of knowledge).
(tl;dr: lol)
I am not really sure I understand this stance. My JavaScript ultimately just boils down to C++, no? C++ ultimately just boils down to machine code, right? Yet you clearly wouldn't try to tackle those things at that layer.
Without more statements on what this bug was and why there weren't error messages or why it was so hard to recreate you felt you could only look at it thru a debugger, I really completely fail to understand your point.
> Abstractions are supposed to remove complexity
React does remove a ton of complexity from writing frontend - good luck composing HTML & JS components with just jQuery - but in exchange it also introduces some, of course. So they make that new and different complexity easier to handle with their dev tools.
> I swore off abstractions ... [that] treat users like morons
I really have a tough time to read this charitably. What on earth are you on about?
Really curious what you mean by that.
There are two possible Chrome (not React) extensions for dev tools that I can think of — one is the "official" extension by React core team that helps visualise components better and also helps understand why they may have rerendered. The other is a redux extension that's very helpful to inspect all the actions that were dispatched against the store and the changes they caused in the redux state. None sounds like what you are describing. Bugs with React state should be easy to diagnose just with a handful of console logs.
I don't disagree that it's pretty obtuse, despite loving working in it. I miss being able to look up the source of Backbone.js and gain a real understanding of why something was happening. Maybe I'll get to that point in React, but it seems much harder to grasp what the source is doing.
I've never been like "boy I really need a virtual DOM" so I guess I've never really seen the appeal of React. It just seems like a bundle of complexity, obfuscation and anti-patterns.
This is the tell. If you are able to satisfy your business requirements with "just JavaScript" then you are in a completely different world than the people building production-grade web apps and there's absolutely nothing wrong with that. If you can be productive with "just JavaScript" then that's awesome!
However, I'm sure you understand there's a massive difference between simple pages that need *some* interactivity and a full-blown app inside a web browser.
I'm sure you've come across projects that probably didn't need the same tooling that I'm describing which ultimately boils down to a judgement call.
> I've never been like "boy I really need a virtual DOM" so I guess I've never really seen the appeal of React. It just seems like a bundle of complexity, obfuscation and anti-patterns.
That's because you've never needed it before. I've never been like "boy I really need a batteries-included web framework" so I guess I've never really seen the appeal of Rails. It just seems like a bundle of complexity, obfuscation and anti-patterns.
Please don't co-opt the word "production" to mean what you're implying here. Production doesn't mean single-page, reactive, etc. applications, it just means "in production."
Source: Running "just JS" in production for more than 6 years.
Is client-side rendering strictly necessary? Do your websites actually run offline?
I've built websites with React, used React Native -- none of it is necessary, nor the end-all-be-all. There's nothing truly novel going on. You can accomplish the exact same experience with server-side rendering and a tiny smattering of vanilla JS (you can use modern JS and polyfills and webpack/esbuild without React, you know).
For 99.9% of the web, I'd argue you don't need it. I have yet to encounter the 0.1% personally.
If you don't believe me, know that I'm not alone. Take a look at https://levels.io/deviance/ -- PHP and jQuery. What would React provide that isn't possible with his stack?
There is a disturbing amount of kool-aid being consumed around React/Vue/etc. Sure, you can slap together a website in record time with massive boilerplate/templates -- but so can I.
react-motion made animating card transitions very straight forward
During a game you can click on history items to look at previous game states, this is very straight forward with React's model
Sure you could get this all by rolling your own state dom renderer, but that's like saying you can do everything Lisp does in C. Greenspun's tenth rule rephrased as "Any sufficiently complicated JavaScript UI contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of React."
I have a feeling that you have already made up your mind not to like it, but if you ever give it a fair try, you might find it useful for some projects. It is very complex under the hood, of course, so if you want to have total control you might need to dig into the internals. But to a casual user it gives a very nice abstraction, very powerful, easy to use (granted - and abuse) and performant. The thing that sold it for me is the declarative programming. You have state, state translates to rendering... and that's pretty much it. Compared to thinking about transitions in native JS (or jQuery or whatever) it is like night and day in any non-trivial project.
I have quite a lot of history with native JS, but was happy to relinquish control to webpack/babel/react... not at first (had the same reaction as you do), but once I gave it a fair chance I discovered that things just work. Never had any problem with React not performing the way it should.
With React you can’t really do that. It’s always following an error message saying: “look near this component” which is often deep in the hierarchy of some third party package’s component hierarchy that is transpiled into a single line with no source maps.
I think there is a huge benefit in making things easy to step-through in a debugger when something goes wrong.
When you hit your first list of elements and need to rerender the contents of just one of the elements, you will begin writing your own React.
If you try to implement some kind of "two way databinding", you will first create React, then create Angular.
However, unreadable and disorganised code can be written at any abstraction level. I have found React projects to be particularly hideous due to the fixation engineers have for tools like Redux.
Angular tends to be a bit better because it's got some decent software design principles built in - but you know front end engineers. Any project with ngrx is a write off from an readability perspective.
Isomorphic applications are also a meme that kill readability.
I write most of my personal projects using Preact and some kind of reactivity helper (RIP `Object.observe`, I grieve for you).
The last time I used the extension, it was obnoxious to use to try to find "state" within the page. Using redux makes things easier to debug from this perspective but you do need yet another extension for that too...
I really think this is a sign of young engineers who have no experience with older approaches just memorizing "how things are done". They have no perspective on the tooling or experience.
I feel like that sometimes. Not all bad though. I've learned that being spartan with your approach not only frees the mind of clutter but your stack wont be delicate shitshow of obscure tools 3-4 years down the line.
Back then the comparison was made with rails, but it still holds true with modern web development now more than ever.
I feel like I went through exponentially more faffing about setting up the web server and forwarding to the accompanying Go server on DigitalOcean than I did getting my project running in modern browsers just using tsc.
What I've pinned it to is a cultural problem in the JavaScript realm: everybody wants to impress everybody else about how smart they are, and in the process of doing so, creates convoluted mazes. As a side-effect, motivation dips and then quality control falls in concert, leading to an "at least it works" mentality.
That's my curmudgeon speculation/observation, at least.
Compare it to the hardware level. The technology required to build a modern CPU is fucking amazing compared to things like being aware of cache coherency when writing code. The amount of time and experimentation to regain the knowledge required for building the full supply chain a modern CPU would be monumental compared to learning to go from something like JS to C.
It’s even easier than that though.
Open chrome, type “how to write computer programs” and go from there.
It is certainly true that there are more informational resources available, but honestly, there was plenty of good info available at most decent libraries, and the manuals that came with computers were typically troves of information back in the 8-bit days.
Sure, reading the two inch thick book on programming your TI-83+ was informative, but God help you if you got stuck.
Now we've got Scratch (visual programming), Arduino (push button C compilation!), and StackOverflow full of the answer to most any problem of stacktrace you encounter.
I don't have to read a tome for hours or wait a day or two for a response on a creeky BBS. Much easier.
> npm init > npm i --save-dev typescript
Add "build":"tsc" to your package.json "scripts" Add a tsconfig.json file
> npm run build
Finito - you've compiled a TS project to JS
If you have an existing JS project that's being converted to TS, you likely have bundling, linting, and CI handled already; for the most part, you just add `preset: typescript` to your existing Babel config and you're done.