Here's the major caveat, out of, say 100+ PoC/prototype projects I've ever done, I've taken two to 'production'. I put production in quotes because they were actually internal services as part of our build and delivery pipeline. It's a major pain in the butt to monitor and keep Node.js running production-like in even remotely similar ways you would with Java, .NET, Python, or even PHP for that matter. I don't expect such drastically different technologies to be exactly alike for production workloads, but there's usually analogous ways to do X, Y, or Z.
You know where Node has been awesome? You land a project with a real tight deadline and its more of a fire and forget project (think interactive 'experience' at a major gaming conference for instance). It needs to run pretty well for a short period of time with a narrow scope of functionality, but some of that functionality is non-trivial. I absolutely love Node for that.
It clearly tells you in the README it's not for production, but I have this recurrent discussion with developers who tell me they have only ever run Node.js this way.
What that tells me is there is quite a trend a towards exactly what you describe, where a lot of what gets written never goes into production.
No, it is worse than that I would have thought. The cynic in me (who is more often right then wrong) suggests that is means there is a lot of "proof of concept" level of code out there in production environments potentially running important things.
Writing Java is really very fast these days, especially with IDE's.
I can get a small web site serving JSON REST requests and memcache up in ten minutes with a simple Maven/Gradle build and full IDE integration.
Between having a REPL, near instaneous stop/relaunch times, and doing in 8 lines of Node.js what takes me 70 lines using CompletableFutures, I'm still going to reach for Node to prove the idea.
Now, when it takes hold and looks like it might stick around, it immediately gets turned into a Java project. Or, if the event we were building for is over, it basically just gets deleted- which pretty much says it all in my opinion.
It's not a toy language, there's some real usefulness to it, but just like anything else, there's a time and place. Currently, that place is NOT production.
It was really fun work, because even the 'simple' stuff we built had to address some of the big traffic issues you'd normally have at a much larger scale and the work was usually very high concept or cutting edge. It would've been a nightmare to maintain for longer than a week though.
I prefer python in general but for zero-to-simple-web-endpoint I may pick Node.
Sure, but that wasn't the argument; GP talked specifically about async and websockets, which are areas where Java is particularly weak, but areas that I was surprised would be required for a PoC at all.
Asking, because I do most of my development in Clojure and find it much nicer than Node both for POC and production. There's also self-hosted Clojurescript now that runs without a dependency on JVM.
I've only just played around with Clojure and I've written a middling amount of Groovy, but the vast majority of it involved Jenkins build pipelines, so I don't really count it.
Java guys always say how they have really developed tooling and look down on other languages. The problem is those nice tools have become a hindrance as well. You can't develop in Java/Kotlin if you don't use those huge complicated tools.
I can't speak for all, but at least for me it prevents me from ever using Java tech. I can develop just fine using a lightweight editor in any of the languages I use. I don't need huge tools or complicated build systems. Because my languages have nice tooling that I can write manually and fully understand.
I tried using Kotlin and step one is always install Intellij.
Oh please. Let's be real, Maven is not even remotely more complicated than the typical package.json, webpack.config.json, .babelrc triple you need for any useful NodeJS project (though you can put the .babelrc into the package.json, I've heard that's the way to do it at the moment). I was so taken back that nowadays JS needs a build step too. But it's a "transpiler", not a "compiler" - cause that's something completely different.
> I tried using Kotlin and step one is always install Intellij.
So? Atom and Visual Studio Code did need to be installed too on my machine. This mentality reminds me of someone using an axe head as a hammer "I'd have to pull the hammer out of the toolbox" (install it) - that's too complicated, I prefer light-weight tools!"
Maven quick start first command:
> mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Then it generates stupidly deep Java structure.
and next you have to write a verbose xml. They even say:
> The POM is huge and can be daunting in its complexity
All of this stuff is verbose and built to be generated by IDEs. It's not clear, it's not concise.
It generates enough structure to scale up to reasonable projects. The nesting is a price well worth paying for consistency. Every maven project puts its source in the same structure, with the result that you can jump into any project and know how its build will work and where to find the source.
> All of this stuff is verbose and built to be generated by IDEs. It's not clear, it's not concise.
Verbose is worth it for clarity, particularly in a file you edit rarely. It may not be concise but it absolutely is clear, as the example from your own link shows.
I've never seen a barebones project as you would when using just node+npm without all the extra tooling (webpack and friends). Node+npm is to me as simple as python+pip. Is there a natural counterpart, Java+maven or something?
And to be fair. All my attempts at approaching webpack have been even worse. And most JS-framework seed projects are similarly complex and automagical.
The grandparent linked to the maven getting started, https://maven.apache.org/guides/getting-started/maven-in-fiv... . That shows what the minimum looks like - a pom.xml, and application source code in src/main/java (under its package structure). (The unit test isn't strictly necessary but is good practice).
The pom's XML header and modelVersion are boilerplate, but the rest is pretty clear and self-explanatory (though admittedly verbose).
At that point for a library project you're sorted, for an application you can run your program via "mvn exec:java" which is adequate for development. To actually package up your application for distribution you probably want to use the shade plugin a la https://maven.apache.org/plugins/maven-shade-plugin/examples... , but that's something you'd do as part of "productionisation". (Back when I worked at an early-stage startup we had things running and serving user requests via "mvn exec:java")
I've encountered a bit of this with most AOT-compiled stuff except for Go. Make or compiler-flags also requires a bit of learning to get going.
Most dynamic languages tend to be more straight-forward with this.
That's kind of our way to do virtualenv-like functionality, which is mandatory rather than optional. (Or you can specify the classpath manually in the same way you would for the pythonpath, but no-one wants to do that). IMO that's the right thing - having libraries installed in my system python has only ever caused trouble in the long- or even medium-term, even if it makes "hello world" use of libraries very slightly simpler.
There's probably a way to get a shell with the classpath set up correctly, but I always found that kind of modalness more confusing than helpful.
> I've encountered a bit of this with most AOT-compiled stuff except for Go. Make or compiler-flags also requires a bit of learning to get going.
In my experience it does all work without any flags or extra knowledge. "mvn" is the entry point for all the things you want to do - you don't ever have to know that there's a "java" and "javac" underlying it.
It generates stupidly deep structure because Java requires a stupidly deep structure.
> Every maven project puts its source in the same structure, with the result that you can jump into any project and know how its build will work and where to find the source.
Rust, Elixir and Erlang achieve this with tooling that is practically trivial to use. Without an IDE.
> Verbose is worth it for clarity, particularly in a file you edit rarely.
Being concise is a big factor in clarity.
All of the depth is useful. The folder structure corresponding to the package structure makes it much easier to find the source for something.
> Being concise is a big factor in clarity.
True when there is large-scale structure that varies for the reader to comprehend. Less important in an inert declarative structure. Again, look to the example you linked.
Because they are honest. Maybe it is because I'm more accustomed to poms, but the package.json/babelrc mix and webpack.config.jsons are daunting to me too.
Ah, I can see how this is much more complicated than the good old
npm install webpack babel-loader babel-core babel-preset-es2015 babel-preset-react --save-dev
You misunderstand my point completely. I was trying to say the Java ecosystem is complicated and the only way it works is by using large IDEs. Saying how awesome Java IDEs are is disingenuous because Java is unusable without them.
The thing with Java is the amount of boilerplate, but the thing with Java is that all of that is ridiculously well documented or demonstrated ad nauseum. Are you building a jar with Maven? Your folder structure looks like this. War? It looks like that. Before Yeoman or any other generators even existed Maven has had archetypes that do the exact same thing.
If you compare Maven, heck, even Gradle to Webpack + Babel for even fairly trivial projects, there's no way that it's more complicated. The tools for Java are truly portable, I can't even recall the hell we used to have to go through when we had to run gulp builds on Windows because developers of various libraries had hard coded *nix style paths, etc.
Most importantly, Maven and Java really aren't a moving target. 9 months from now I'm not going to have to overhaul my entire build process because a wide swath of my plugins have completely changed directions. Stability is how you wind up with the time to make things run smoother in production. It's how you wind up with repeatable patterns and better instrumentation. You get a chance to take a breath and formulate an honest to goodness process vs. literally sprinting as fast as you can to simply keep up with the changes.
This is based on what? It is totally untrue from my experience. Quite the opposite.
I think you haven't used a JVM language and its ecosystem in a very long time.
Except when you have to restart the JVM because you added a class or a whole bunch of other things that it can't hotswap in the new code.
If I'm using an interpreted language I only have to deploy the changed source files. Git can do that for you.
Dropwizard is a great example of this. It's an opinionated (convention over configuration) Java framework for building REST web services. You can get a 'Hello World' web service up and running in literally 10 minutes following this tutorial http://www.dropwizard.io/1.0.0/docs/getting-started.html
Why is it faster to write code in a dynamically typed language?
Most modern statically typed languages have type inference so you don't even need to write type annotations for the most part, assuming these extra characters were the reason.
So what's that mysterious reason that makes writing dynamically typed language faster?
I literally don't know the answers to these questions so the same task would take me hours, possibly days. Getting from zero to JSON api in node.js is fast by comparison.
Note I am not arguing whether or not it's better in the long run to be the guy that went from zero to node.js or zero to Java, that's a separate discussion.
You have similar concerns with node (What's npm? etc...) These are peripheral and necessary knowledge on both platforms.
> Getting from zero to JSON api in node.js is fast by comparison
It's only fast because you already have the knowledge.
Two equally proficient developers in Java and node will set up and get a server up and running in about the same amount of time.
The idea that it's a faster to achieve in a dynamically typed language is a myth.
No, when I said "from zero" I meant from zero knowledge.
> You have similar concerns with node (What's npm? etc...)
What's the "etc..."? Install node and you get npm with it.
Writing a REST service IS simpler with Node when going from zero, I know because I have done (or at least attempted) both from zero in the recent past.
> The idea that it's a faster to achieve in a dynamically typed language is a myth.
Doesn't seem like you're open to discussion on this
It can't be anything else, because after you have Maven, it is literally a single command to set up a REST project using Dropwizard.
I find the Java ecosystem terrifying by comparison. I have no idea whether Maven is what I should be using or if I should be using something else instead -- having it as a separate download makes a big difference in that regard -- and I have no idea by looking at a typical Maven config file what it does.
mvn archetype:generate -DarchetypeGroupId=io.dropwizard.archetypes -DarchetypeArtifactId=java-simple -DarchetypeVersion=1.0.0
Running `mvn --help` doesn't help at all and the pom file it creates is 143 lines of hard to read XML.
I've used gradle a little, I'm familiar with bundler/gem, pip, npm and dub. Maven just makes me want to run as far as possible from anything Java related.
Edit: and of course with npm the annoying downloads happen every time for each project, instead of once per dependency version...
Also package.json and pom.xml are equally (un)readable. At least Maven project files have a schema to help editors out.
`mvn --help` gives you a list of commands too.
The code in question looks like:
iter.next().ok_or(ErrorKind::NotEnoughArguments.into())?.parse().chain_err(|| "cannot parse argument")?
the solution is of course to do
iter.next().ok_or::<Error>(ErrorKind::NotEnoughArguments.into())?.parse().chain_err(|| "cannot parse argument")?
in a dynamic language, you wouldn't have to worry about this; in fact, you wouldn't need to call .into() either - there's just less typing and compiler errors
Java, for example, is no picnic, whether it can now infer some types or not.
In Python I don't even need a main().
if __name__ == "__main__":
> most ES6 features
Most. Ugly word. Really ugly word.
I might add a transpiler for Typescript to my stack soon, if that language turns out as pleasant to work with as I've been hearing. If I do, it'll be the first time I use one. And I've been working with Node, in production, since 2013.
(That was a joke btw. Thanks for the info. The consensus seemed to be that Babel is the way to go, but if your variant works for you good to hear. I will still stay with it. I like ES6 imports in Node.)
Do you read JSON from ajax post bodies? Do you access fields in that JSON without sanity checking it? Try passing JSON that's missing one of those critical fields (as, say, a griefer might do). What happened to your app?
- Metrics/Instrumentation/Tracing (memory usage, transactional performance monitoring, etc)
- Surviving exceptions
All of these are either very immature in Node or simply so far behind they may as well not exist. By nature of running in an application server, you do get a lot of benefits right off the bat for all of those, but even if you're running an executable jar instead of deploying to Tomcat stray exceptions will in almost no cases cause your application to simply die for all requests.
Also, say what you want about the verbose try/catch Exception model, but at least you can count on it. Am I getting an Error in this callback or is an exception going to get thrown? Oh, they leaked an exception when I was prepared to handle an Error and now my entire server is down. Does your process automatically restart? Not likely unless you spent a lot of time hand crafting your service to be daemonized, which is generally FAR beyond the scope of most developers I've met in any language (which also upsets me).
Also I thought something like PM2 (https://github.com/Unitech/pm2) or Forever (https://github.com/foreverjs/forever) was pretty much standard for production Node apps?
We use PM2 in production for web apps, long running processes (console apps with rethinkdb change feeds) and cron to spin up command line apps for data transformations, SaaS integrations, bots and more.
Most of us use VS Code now (I still use Vim)...so yes, having done enterprise work with a full blown IDE and tooling can be very helpful as the Node debugging and profiling experience is not great (but getting a ton better).
In the past we had a ton of C#/.net in production, then Ruby and now JS for the indefinite future. We build things that end up in production for 10 years or more, so having that talent pool to pull from in the future will be great.
A crash certainly draws attention to a problem much better than an error in a log that no one usually looks at.
Yes it's a pain, but you deserve it for writing buggy code and then not catching it in testing (that's what I keep saying to myself, anyway). ;)
Exception handling in C# is amazingly good, you can't run C# production level apps.
It suffers none of the problems that are being discussed above. All you're doing is confusing the discussion with a view point I haven't heard in a decade.
What language doesn't do that?