Hacker News new | ask | show | jobs
by AndrewCHM 3209 days ago
I'm confused

So its agreeable that the building pipeline of NPM calling some packer does replace any-other-language calling any-other-packer, but what is the point in replacing the role of `npm build`, with a makefile that just calls what npm would of called anyways?

replacing make with npm with make-calling-npm?

3 comments

I wrote a bit about an approach I'm using, A Touch Of Make (ATOM), which helps provide better developer UX across teams - particularly ones working on microservices.

https://www.alexhudson.com/2017/04/26/articulating-atom-appr...

You're right, replacing "npm build" with "make build" doesn't win you anything. But that's only true on the small scale. In a service world, there are lots of projects, each with different requirements. Some will have front-end, some won't. Others will require a totally different build process. There will probably be different languages involved.

Using make, you can standardise a lot of this. If you set up a coding standard that after you clone a repo, "make dep" should grab anything the project requires, then developers don't initially need to know whether that's calling out to npm or composer or pip or whatever - it's just "working".

This is a much bigger win when you have a number of projects. The process is standardised, so developers know it's only a two or three step build (or whatever you've setup). They know how to do it, and when they need to look under the covers, they can see how it works, and this knowledge is transferable from one project to another because Make is universal.

I don't advocate doing big Makefiles - that's why I call this approach ATOM; only use a touch of Make. But used judiciously, it smooths out projects very nicely. Not everyone needs that, though.

I tried this approach. It never works in the long run. The Python developers wanted Make for the few commands they needed in their projects. The JVM folks had Gradle. The Python folks refused to learn Gradle (because of some argument like: rah rah rah JVM tools hard; Make easy! Make all you need. If Make isn't enough your language is garbage).

So the JVM folks created a crappy Makefile that accomplished some of the basic stuff to appease the Pythonistas. Meanwhile the JVM folks continued to use Gradle directly and the Python folks who had to work on the JVM projects got a shittier experience through the Makefile. As new tasks were added to build process the JVM folks would just write custom Gradle tasks to accomplish the job which would drive the Python folks nuts because they wanted shell scripts or make targets invoking shell scripts or whatever.

My only take away from this experience was developer tooling sucks and there is no one size fits all approach to build systems. Try to stick to a convention within an ecosystem (e.g. all JVM projects should use one of Gradle/Maven/Sbt), but don't try and get cute with making stuff more common than it has to be.

You say the Pythonistas refused to use Gradle, but it also seems the JVM peeps refused to let go of it?

Isn't that the problem? Isn't Make more general than Gradle? If the project was primarily JVM, why couldn't the Pythonistas be forced to use whatever build system was mandated?

You'd have to reinvent a lot of wheels to replicate what Gradle (or Maven) does. For example dependency management, env setup and packaging. It would be similar to asking a Python developer to give up pip, setup/disttools and maybe virtualenv. In the end you want productive devs. Stripping away the tools they are productive with is counterproductive.
But surely these are targets for make?

e.g a pip target that builds a python dep folder. You can do the same for Java with Apache Ivy.

Is Gradle not a make like system with a lot of JVM-specific functionality built in?

I agree. I increasingly use makefiles with a small set of common targets. I know I can do "make build" in all my repos, whether they're C or Ruby and whether they're packaged as a docker container or directly. I know I can do "make run". I know if they're in a container I can do "make cli" to get a shell inside that container, and so on.

The Makefile then acts as documentation of exactly what to do. All of the setup stuff that people often put in a README is right there.

All of the complex stuff gets put in other tools or separate scripts. But there's probably going to be a make target that tells people which tool and where to look if they need to change it, or that'll let them run it without having to know the details.

>Using make, you can standardise a lot of this. If you set up a coding standard that after you clone a repo, "make dep" should grab anything the project requires, then developers don't initially need to know whether that's calling out to npm or composer or pip or whatever - it's just "working".

In my experience you will end up with a dozen coding "standards" and project structures. Especially in C and C++ where header dependencies have to be generated by the compiler even the most basic makefile will take you at least an hour to create if you already have experience in making makefiles.

Comes down to how you enforce it. To be clear, I'm not talking about mediating the build in Make unless that's the best tool for the job. On a C project I would use cmake, but within this system I'd run it out of a Makefile at a top level, so the person pulling it can just run 'make build'.

The point is to have a known starting place, so that when you pull down a new project you don't have to spend ages reading about how it works.

Even if you can't grab the deps automatically, doing 'make build' and it saying "Hey, you don't have cmake and a bunch of other things you need, but go look at http://whatever.. to set yourself up" is a much better experience.

I haven't done something similar with npm but I did write make files to call specific commands. For example a particularly long activate function very specific to internal tooling. Doing this makes sense for such commands and not for primitives.
I agree, why add make (which version?) as a dependency when you can make sure that the project can build with just node installed.