This is how you can detect existing Node.js and npm, or automatically install a temporary Node.js if none is already installed. About the only things needed are make
, bash
, curl
and git
, which are usually available on all development / CI machines.
(I’m planning to work around the requirements for curl
and git
, so those won’t even be needed in the future.)
Put this at the top of your Makefile
:
SHELL := /bin/bash NODE_PATH = $(shell ./find-node-or-install) PATH := $(NODE_PATH):$(shell echo $$PATH)
Then download the find-node-or-install
script to the same directory:
$ curl https://raw.github.com/hugojosefson/find-node-or-install/master/find-node-or-install -o find-node-or-install $ chmod +x find-node-or-install
Now you will have access to node
and npm
inside the Makefile
, and can use them just like normal. The script runs very quickly if you already have node
on your path, or if the script has run before. If no node
is found, it automatically uses nvm to install the latest 0.10.x version of Node.js to the user’s temp directory.
Doing this can be good for when you want to use some npm module in your build, for example Component package manager, Yeoman, Grunt or Bower, and you don’t want to bother your colleagues in the team and force them to install Node.js. Or for example make it a lot smoother to get the build running on any Continuous Integration server.
Example with locally installed npm module, rather than npm install -g
While it is tempting to expect other people to npm install -g whatever tools you need
before building, it’s not very polite to those who have to figure out what they need to do before they can run make
like they expect. Also, you have to document what they have to do.
A better way, in my opinion, is to do that documentation in the form of additions to the Makefile
. What I mean is that if you have to specify in documentation what is needed to run the build, you can instead specify it to the computer, and the computer can install the necessary tools automatically.
Let me show you how for example the Component package manager can be used in a Makefile
, while not forcing other developers to globally install the npm module for it.
The first step is to declare a variable in the Makefile
, which points to where the component
executable is located when its npm module is installed locally in node_modules
. To find out where, first install it locally:
$ npm install component
Then look inside ./node_modules/component/
and find the executable. Usually there is some directory named bin
or similar. In this case, I found it at node_modules/component/bin/component
. That’s what I put in my Makefile
:
COMPONENT_BIN = node_modules/component/bin/component
Then I use that variable in place of the word component
whenever I need to call it. For example, instead of:
components: component.json component install --dev
…I put:
components: $(COMPONENT_BIN) component.json $(COMPONENT_BIN) install --dev
As you may notice, I also added $(COMPONENT_BIN)
as a dependency to all targets which need it. This way I can specify how to install it to node_modules
:
$(COMPONENT_BIN): npm install component@0.16.0
The full example of this, in combination with find-node-or-install
, is at github.com/hugojosefson/find-node-or-install. I found details on how dependencies and targets in Makefile
s work at www-personal.umich.edu/~ppannuto/writings/makefiles.html.
Conclusion
Showing the cool stuff you can do with things written for Node.js, is probably a better way to get other people on your side, than forcing them to install tools before they can even see what good it does! :)
Pingback: itemprop="name">How to use make and Makefile in Maven pom.xml – Jayway