I'm going to preface this by saying that I'm a much bigger user of Java than I am of node. I do like node, but I just don't use it as much.
I'm also going to say that it's entirely possible that my lack of experience with node is colouring my thinking here.
I think Java is easier to work with than node. And I know that's going to be a hugely unpopular opinion, and even that people will wonder how I can ever think that. So here's my reasoning.
Imagine I'm writing a simple single page application. I'm going to use:
- Some form of HTTP server to act as a REST/GraphQL/whatever service.
- Create React App to build the UI (for arguments sake - I like it)
- Postgres for the data layer. (See above)
- Full stack end to end tests using selenium
In the Java world, I can set up a build that allows me to do this. The end result can, remarkably easily, be that I execute
mvn clean install to:
- Download all dependencies
- Build the backend application
- Compiling all code
- Running all unit tests
- Running static checks - e.g. checkstyle
- Full integration tests
- Build a docker image for the application
- Build the webapp
- Producing the output files
- Running all unit tests
- Build a Docker image for the webapp
- Build the end up end tests
- Build a Docker image for the tests
The output of this I can then start the front-end and backend together or individually, and - importantly - I can run a Docker compose stack of the entire system including the end to end tests...
The interesting thing here is the integration tests. I can start up the server, using a library automatically start and stop the database, automatically manage the database schema, then run a whole barrage of tests against it. And all of this is just one thing hidden behind one standard build command, the same used by millions of other projects...
Now let's consider node.
Firstly, as best I know there's no way to do multi module builds in node. This means that I've got to know to build the three different modules individually.
Secondly, the integration tests. Having asked around, it seems that the idea of having an all-in-one process is actively disliked. Instead of running the tests with one command and it does it all for you, it's generally expected that you will:
- Start up all dependant services yourself - maybe using Docker
- Start up the service to test yourself - maybe using docker
- Then run the tests against this
- Then tear it all down yourself
That's a lot of effort to achieve this.
Thirdly, executing multiple step builds is clunky. Tools like grunt can make it easier, but that's adding one layer of complexity just to hide another. Alternatively you can use shell scripts, but that's not cross platform.
This is only a sample of things, but it already shows that running a build in node is more complicated than in Java. A lot of people argue that each of these steps are significantly simpler than the Java version, and that's true. But the fact that you've got to know it all just makes things more difficult to pick up.
Now, that's not to say it's all bad. There are a lot of good things here to. It's remarkably easy to get a very fast cycle time in node - write code, get unit test results flash up a second later, repeat. Or write code, have the server restarted a second later, and repeat. Java just takes longer to achieve these same things. However, it's got a lot of additional understanding needed by the developer to get to the same point.
At least, that's how it seems to me. I might well be missing things that make all of this a lot easier to understand.