Hacker News new | comments | show | ask | jobs | submit login
Modern JavaScript Explained for Dinosaurs (medium.com)
91 points by pavel_lishin 10 months ago | hide | past | web | favorite | 36 comments

> The bad thing was that it was annoying to find and download new versions of libraries every time they would update.

This goes back to one of the key complaints about front-end culture, though. Exactly how often should this be a problem? Seems to me that actual library code should be stable and updates would be on an infrequent basis.

One general response is "well, this is what happens when you don't have a solid/broad standard library," and that's one of the complaints about JS that kindof sticks for me, but if that were what this was all about, I might expect to see a handful of standard libraries pop up over time and stabilize instead of a fine-grained and deep transience-ridden dependency tree that requires a package manager...

> I might expect to see a handful of standard libraries pop up over time and stabilize

What makes you think this hasn't happened? jQuery and underscore/lodash are some examples of libraries that have a lot of traction. Why is JS having package management seen as a downside? It's an upside in every other language community, but for some reason we should try to avoid using one in JavaScript?

underscore is a good counterpoint. jQuery is a great library, but I think it's arguably not what people mean when they talk about standard libraries, which has more to do with the question of why in the world there's a leftpad package.

> Why is JS having package management seen as a downside? It's an upside in every other language community

FWIW I'd say that thinking of package management as an unqualified upside in any language or environment is a mistake, though getting deep into that argument is not on my to-do list for the day, as convincing anybody who isn't naturally amenable to it would probably require going over the groundwork involved in groking JWZ's famous quote about regular expressions ("Some people, when confronted with a problem, think 'I know, I'll use regular expressions.' Now they have two problems.") and some philosophy about automation and the attention economy.

But package management is convenient for sure, and there's any number of situations in which I use it and am happy about it, particularly when I'm installing things where I'm primarily a user rather than a developer. The specific complaint about JS is based on the observation that the dependency tree seems to be fine-grained and transient in what seems like an unusual way to me. In that situation, I suspect the problems that come with any other pm system are likely magnified, including developer dependency on it, which moves from convenience towards necessity.

You're talking about Lodash. But the remaining issue is of locality. If you use a package as a standard library, you still have to send that package to a client for them to use your app. Whereas a 'real' standard library would already exist as part of their interpreter/browser/operating system.

I've been a huge fan of JavaScript since 2005. My roots are in Fortran, Pascal, C/C++, ASM, later Perl and Python and Java. JS is by far is the most convenient language I've ever worked with and thanks to BabelJS it is even better.

Yes JS is not perfect and it has a fair dose of inconsistencies but 99% of the time it just feels right and it works well. Also thanks to NPM the community is alive and healthy, surpassing the success of Perl's CPAN and Ruby's Gems and Java's Maven and what not.

If you haven't tried JS yet, you should!


P.S. I talked to HD Moore back in the days during the Metasploit rewrite why Ruby was chosen for the next iteration of Metasploit. The reason was that Ruby was so much closer to Perl then JS and I don't think Node was around. I wish I tried harder to make my case as it would have been a huge asset now.

My roots are the same as yours (except Java). I am not a professional developer, but rather code to simplify my work, so some projects or write as a hobby.

I like JS but one of the things which are horrendous is debugging. Pycharm allows me to debug Python code in a simple, intuitive way.

I still need to find a setup in JS where I can debug the same way (there is always something which does not work, between the IDE and Chrome and DevTools). This is really the ONE thing which is pushing me away from that otherwise nice language.

PyCharm/WebStorm lets you debug node processes in the same way as python processes, so debugging tests doesn't seem to be much different for me.

For code running in a browser, you can do in-IDE debugging with PyCharm/WebStorm via a run configuration [1], although I tend to not bother and just use the Chrome devtools instead, which I find to be very high-quality.

My company does a lot of JS and Python, and I've found that people tend to be more comfortable using a debugger with JS because you can just open Chrome devtools, set a breakpoint, and go. In Python, you need good editor support or you need to use a command line debugger, so there's a larger barrier to entry.

[1] https://blog.jetbrains.com/webstorm/2018/01/debugging-javasc...

It seems a bit unfair to blame the language for the added complexity that is introduced when debugging a browser script. Pycharm (or any of the JetBrains IDEs with JS support) offer a very comparable debugging experience for server side Javascript.

Not being a professional, I tend to see a language through holistic glasses : the ease and versatility, the libraries, IDE support, debugging, etc.

I was mostly referring to front end JS, where I sometimes managé to debug in my IDE and sometimes not (and I then need to have DevTools open).

I have a hate/love relationship with JavaScript.

Also have similar background in programming languages, plus a few more given my interest in programming language research.

What I can't stand is seeing projects with npm, grunt, yeoman, webpacker altogether.

Thankfully I am spending most of my time in other eco-systems and can still do Vanilla JS projects.

How would you say JS compares to python?

(asking as someone would never touched JS and for whom Python holds this "most convenient language" spot).

I use both JS and Python professionally. Overall, I prefer JS, but I also see plenty of nice things about Python. Here's my comparison:

(Full disclosure with all of this: I haven't spent as much time researching Python tools as JS tools, and I'd love to hear if I'm wrong with any of this.)

Nice things about JS:

* The state of type systems is much more mature. TypeScript and Flow are both well-maintained language extensions that make it practical to have full type coverage, and both provide language servers for nice autocomplete in any editor. It has been a while since I've tried Python type annotations and mypy, but my understanding is that they aren't at the same level.

* The tooling seems to be better overall. npm and yarn seem to be more well-thought-out than pip and virtualenvs and better handle version pinning and avoid dependency hell. ESLint seems to give much higher-quality results than flake8, and has many autofixers. I recently set up Prettier at work, and people have felt that it significantly improves their coding process and have asked if I could set up the same thing for Python. The answer I have to give is "no, because nothing like Prettier exists for Python".

* Object destructuring (and related features) is probably the biggest language feature that I miss when I'm coding in Python. Tuples and namedtuples both feel much more awkward to work with than JS objects.

* JS has block scoping. It's amazing how many times I've seen a loop assignee or list comprehension variable wreak havoc in Python because of a name clash with some other variable, and that problem simply doesn't happen in JS.

* JS (like almost all languages except Python) allows statements within expressions, so you can pass in a callback lambda function with non-trivial code in it. Python context managers (`with` statements) and decorators seem to cover many of the common use cases for code-within-a-function-call, but I still run into cases in Python where it feels like I need to awkwardly work around the language.

* The JS import system seems better-thought-out. Circular imports tend to be a big problem for us in Python, but not in JS.

Nice things about Python:

* List comprehensions are nice to write and read. In JS you use `map` and `filter`, which isn't so different in theory, but I still like list comprehensions better.

* Python makes it much less of a pain to work with complex types, e.g. having a dict where the keys are tuples. In JS, plain object keys must be strings, and the newer Map type only allows identity equality for keys, so you need to find workarounds.

* Keyword args are nice.

* Python's approach to method instance binding is more intuitive. You never have to worry about `self` not being correct, whereas every new JS programmer need to go through a phase where they learn how to make sure `this` is correct. (Newer JS features like arrow functions make this less of a concern.)

* Python is more likely to fail fast when you make a mistake (e.g. accessing a nonexistent property due to a typo), whereas JS is more likely to fail silently.

* While Python and JS both have a "dark history" and plenty of legacy warts, Python has fewer of them. But I consider both to be pretty minor: Python 3 fixes a lot of things, and pretty much any reasonable ESLint config disallows code using problematic older JS features (like `var`, `for...in`, and global assignment).

The goal of this article is to provide a historical context of how JavaScript tools have evolved to what they are today in 2017.


We went from plain HTML and JS to using a package manager to automatically download 3rd party packages, a module bundler to create a single script file, a transpiler to use future JavaScript features, and a task runner to automate different parts of the build process.

Definitely a lot of moving pieces here, especially for beginners.

Modern JavaScript can definitely be frustrating to work with as it continues to change and evolve at a rapid pace.

But even though it may seem at times like re-inventing the wheel,...

All this build and packaging machinery makes sense if you're building something like a CAD system or a virtual world viewer that runs in the browser. But for the typical web site? It just runs up load times.

While I think that many websites don't need much JS in the first place, you pretty easily hit a degree of complexity where a package manager is very useful. And the whole build thing is in part precisely to keep load times down.

(That said, I'm a front-end dev who is leaning more and more towards good old back-end rendering and something like TurboLinks perhaps, for many situations where previously I'd automatically go for React or Vue.)

See Wikia, which seems to have decided that 'using JavaScript for everything on mobile' is the future, despite not actually having a use case for a 'web app' type site in the first place.

Or many content/news sites in general now. Feels like development is done based on what's flashy rather than what actually works best for the project in question.

Preface: I am a dinosaur. I know I'm a dinosaur, with a tiny dinosaur brain.

But I couldn't help but wonder as I read this whether much of the complexity of the JS ecosystem isn't a consequence of the fact that whatever Node.js uses isn't really javascript. It's apparently a fork of javascript that has includes and is intended to run natively.

Now, modern javascript packages for the web also use includes because it's part of NPM and the Node ecosystem. And as a result, there has to be a transpiling/build step to convert "Node" javascript to "frontend" javascript, or some other language to frontend javascript.

But, to me, includes shouldn't be part of the "code", because they aren't really part of the language - that should be separated to the packaging directives and handled entirely by the package manager. Javascript package management meant for the web would just pull in javascript, maybe minify it, and dump it into a file. No need for transpiling, building or webpacking.

Although I suppose you could if you wanted to, but that should be the exception, not the norm. But, no. We have to have a million packages written in pseudo-js or typescript or coffeescript with a single function each and a separate test suite and build step for each.

I appreciate that the modern JS ecosystem works, and works well for many people, but... I still feel like it doesn't need to be as complicated as it is. It could be much, much simpler and still be better than just pasting in script tags. Not that there's anything wrong with that. In the end, that's what happens anyway.

Sometimes the ways of the warmbloods confuse and infuriate me.

I'm the same kinda dinosaur, but I have to disagree with the following:

> Now, modern javascript packages for the web also use includes because it's part of NPM and the Node ecosystem. And as a result, there has to be a transpiling/build step to convert "Node" javascript to "frontend" javascript, or some other language to frontend javascript.

At first, I would agree, but with ES2015+ the import system isn't too different or at least shares a lot with CommonJS.

Since that's the future of JS modularization, I think it's important to embrace it. However, there is one area where the TC39 committee, along with browser vendors/Node, really messed up is the releasing of the module system with so much undefined or all over the place.

For example, the lack of a bundling strategy. Every person I've talked to about this has just said "oh, http2 will take care of it". Really? Even if http2 supports multiple connections, there will either need to be multiple round-trips to the server for further dependencies (which, physics puts a limit on the speed that can happen at), or you need to calculate on the server and send over what's needed.

So I think these module bundlers are essentially doing that at build time (which sucks for runtime dynamic inclusion of resources).

Then there's the whole .mjs fiasco with Node.

Since committees are so often slow to update (for valid reasons, many times), and miss many valid use cases, I think the new world of frontend development will include some sort of tooling like this.

It should, God willing, start to simplify (maybe kind of like how npm scripts are becoming more preferred to gulp and the like).

This is a well written explanation of the different layers one will encounter when writing JS. It's a bit frustrating at first but once you get past the hill, it's very satisfying.

The fact that you have to know a dozen major technologies just to make basic UI that breaks half of the time should make you feel awful as an engineer.

I see this quip a lot but never any honest side-by-side comparisons illuminating how much easier/simpler some other fullstack +crossplatform ecosystem is.

Very good synthesis ! Whatever everyone'd wanna say or think about JS, it's hard to be in web development and not ear the bells. Better know what you ear and what's'all about :)

I still have a tickle, you conclude with 3 so-called "modern features" from JS ... Both the 3 thing you quote come from Clojure and amazing work from google nerdz, and was ported to JS later :p

my workflow is

npm to get the packages in VS2017 called from package-mgr console

gulp to move the package from node to wwwroot

system.js.config declares the packages

system.js to load the package

npm get the @types files (so typescript knows how to compile and I get autocomplete)

and then I do a typescript import

--- real pain in the neck to setup but now its really not bad at all

VS Code will automatically pull type definitions from npmjs.org, so you get code highlighting and inline errors for free (not sure how much such automation is included in VS2017).

Many npm modules come with their own typings. Those which don't usually have them in the definitelytyped repo. For those 'npm install <foo> @types/<foo>' should be enough so that typescript can find both the code and corresponding type definitions.

The rest of your setup seems to be related how you build and bundle the files. I use webpack and a typescript loader, and there is literally nothing more that I have to do after installing the packages, I can just import (or require) them in my code.

I still get by, by just putting whatever I need into the scripts folder and then using ASP.NET bundling APIs.

Similar approach on the Java projects, a scripts folder under the webapp resources.

It might be old fashion, but keeps me sane.

This is actually really well written. I learned a few things about the history that I've always been wondering (CommonJS, etc)

npm is so 2016 (being sarcastic).

What do you propose using instead?


Honest question: what advantages does it have over npm? As far as I see, the only cool feature is the license check.

JavaScript programming and more importantly JavaScript way of thinking is quickly becoming equivalent of company in need of hiring few good programmers and solving it by hiring more HR 'professionals' first.

Let's solve this pile by throwing more useless stuff on top of it.

Yes, I do have badge that says I can say stuff like that. You know I am right even if you can't agree in public. /rant

JavaScript totally has real flaws but your complaint is incoherent nonsense.

What badge?

"Gentleman wearing this badge can speak freely and name things as they are", you know, usual.


Most developer bros still think modern JS is Jquery but unnecessary. I've had "Senior" engineers ask why we need Webpack because it's too complicated and unnecessary and wanted to take it out. Others who think Angular is the same as Bootstrap which is a UI framework. And those who doesn't even know what ES6 is.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact