In my experience some aspects of the JavaScript experience are
great, and others are
terrible.
npm is great. It gives you an easy way of specifying your dependencies in your source tree, and makes it extremely easy for people who check out your repo to obtain them. People can run "npm install" and now they have a copy of all your dependencies in "./node_modules". It composes nicely too: "npm install" also pulls the dependencies of your dependencies.
Babel is great. Sure, I've heard some complaints lately about their latest changes, but so far this hasn't affected me as a user. Babel for me means that I get to write using the most modern ES6/ES7 features and then compile to ES5 for compatibility. For me it works great and mostly hassle free.
The frameworks themselves are great. Not perfect sure, but there are lots of great ideas floating around in React, Angular, d3, moment.js, etc. and the packages built on top of them. Whatever you want to do there is a library out there that someone has put a lot of love into. There is a lot of choice -- yes, maybe sometimes a little bit too much, but I'd rather have that than too little.
Flow is great (and I hear TypeScript is too, and getting better). I can't tell you how nice it is to be able to declare static types when you want to and hear about type errors at compile time. Maybe not everybody's cup of tea, but I love it.
The build systems, minifiers, test runners, etc. are terrible. By far the worst part of JS development for me is figuring out how to glue it all together. When I try to figure it out it's like entering an infinitely complex maze where none of the passages actually lead anywhere.
--
For example, let's say you want to run some Jasmine tests under PhantomJS. Jasmine is a popular unit testing framework and PhantomJS is a popular headless browser, scriptable using JavaScript. Both very cool technologies, but how can you use them together? This is a real example: it's something I really wanted to do, but in the end I literally could not figure out how and gave up.
Phantom JS claims that it supports Jasmine (http://phantomjs.org/headless-testing.html) though it gives several options for test runners: Chutzpah, grunt-contrib-jasmine, guard-jasmine, phantom-jasmine. Time to enter the maze!
Chutzpah looks promising (http://mmanela.github.io/chutzpah/) -- it says it lets you run tests under a command line. It says it "supports the QUnit, Jasmine and Mocha testing frameworks" and you can get it by using "nuget or chocolatey". Dig a little deeper and it starts to become clear that this is a very Windows-centric tool -- nuget says it requires Visual Studio and chocolatey is Windows-only. Our maze has run into a dead-end.
Moving on to grunt-contrib-jasmine. I don't really want to use this because I'm currently using Gulp (Grunt's competitor), but let's check it out. We end up at this page (https://github.com/gruntjs/grunt-contrib-jasmine). This page is sort of a quintessential "JavaScript maze". It contains a lot of under-explained jargon and links to other plugins. And it gives me no idea how to do basic things like "include all my node_modules" (maybe I should list each ./node_module/foo dir explicitly under "vendor"?)
Moving on to guard-jasmine, I end up at https://github.com/guard/guard-jasmine, and it's clear now that I've entered a Ruby neighborhood of the maze: everything is talking about the "Rails asset pipeline", adding Guard into "your Gemfile" (I don't have a Gemfile!!). I really don't want to introduce a Ruby dependency into my build just for the privilege of gluing two JavaScript technologies together (Jasmine and PhantomJS).
The final option in the list was phantom-jasmine, bringing us here: https://github.com/jcarver989/phantom-jasmine. It's been a while so I don't remember everything I went through trying to make this work. But I was ultimately unsuccessful.