Homebrew handles downloading, unpacking and installing Node and NPM on your system. The whole process (after you have XCode and Homebrew installed) should only take you a few minutes. Open the Terminal app and type brew install node. Sit back and wait.
This document explains how to successfully use Node and npm in a Node module based Homebrew formula.
Node for Formula Authors. This document explains how to successfully use Node and npm in a Node module based Homebrew formula. Running npm install. Homebrew provides two helper methods in a Language::Node module: stdnpminstallargs and localnpminstallargs. First, you need to install the Node.js runtime itself, along with Node’s package manager, npm. Then you need to install an editor in which to write your source code as you complete the units of the LP. You’re welcome to use any editor you like, but I recommend you use VS Code (for reasons I’ll outline later in this unit). Brew is a NodeJS class that keeps source files compiled and bundled, available in memory.
Running npm install
Homebrew provides two helper methods in a Language::Node
module: std_npm_install_args
and local_npm_install_args
. They both set up the correct environment for npm and return arguments for npm install
for their specific use cases. Your formula should use these instead of invoking npm install
explicitly. The syntax for a standard Node module installation is:
where libexec
is the destination prefix (usually the libexec
variable).
Download URL
If the Node module is also available on the npm registry, we prefer npm hosted release tarballs over GitHub (or elsewhere) hosted source tarballs. The advantages of these tarballs are that they don’t include the files from the .npmignore
(such as tests) resulting in a smaller download size and that any possible transpilation step is already done (e.g. no need to compile CoffeeScript files as a build step).
The npm registry URLs usually have the format of:
Alternatively you could curl
the JSON at https://registry.npmjs.org/<name>
and look for the value of versions[<version>].dist.tarball
for the correct tarball URL.
Dependencies
Node modules which are compatible with the latest Node version should declare a dependency on the node
formula.
If your formula requires being executed with an older Node version you should use one of the versioned node formulae (e.g. node@12
).
Special requirements for native addons
If your Node module is a native addon or has a native addon somewhere in its dependency tree you have to declare an additional dependency. Since the compilation of the native addon results in an invocation of node-gyp
we need an additional build time dependency on 'python'
(because GYP depends on Python).
Also note that such a formula would only be compatible with the same Node major version it originally was compiled with. This means that we need to revision every formula with a Node native addon with every major version bump of the node
formula. To make sure we don’t overlook your formula on a Node major version bump, write a meaningful test which would fail in such a case (invoked with an ABI-incompatible Node version).
Installation
Npm Brew Update
Node modules should be installed to libexec
. This prevents the Node modules from contaminating the global node_modules
, which is important so that npm doesn’t try to manage Homebrew-installed Node modules.
In the following we distinguish between two types of Node modules installed using formulae:
- formulae for standard Node modules compatible with npm’s global module format which should use
std_npm_install_args
(likeazure-cli
orwebpack
) - formulae where the
npm install
call is not the only required install step (e.g. need to also compile non-JavaScript sources) which have to uselocal_npm_install_args
(likeelixirscript
orgrunt-cli
)
What both methods have in common is that they are setting the correct environment for using npm inside Homebrew and are returning the arguments for invoking npm install
for their specific use cases. This includes fixing an important edge case with the npm cache (caused by Homebrew’s redirection of HOME
during the build and test process) by using our own custom npm_cache
inside HOMEBREW_CACHE
, which would otherwise result in very long build times and high disk space usage.
To use them you have to require the Node language module at the beginning of your formula file with:
Brew Update Npm
Installing global style modules with std_npm_install_args
to libexec
In your formula’s install
method, simply cd
to the top level of your Node module if necessary and then use system
to invoke npm install
with Language::Node.std_npm_install_args
like:
This will install your Node module in npm’s global module style with a custom prefix to libexec
. All your modules’ executables will be automatically resolved by npm into libexec/bin
for you, which is not symlinked into Homebrew’s prefix. We need to make sure these are installed. To do this we need to symlink all executables to bin
with:
Installing module dependencies locally with local_npm_install_args
In your formula’s install
method, do any installation steps which need to be done before the npm install
step and then cd
to the top level of the included Node module. Then, use system
with Language::Node.local_npm_install_args
to invoke npm install
like:
This will install all of your Node modules dependencies to your local build path. You can now continue with your build steps and take care of the installation into the Homebrew prefix
on your own, following the general Homebrew formula instructions.
Example
Installing a standard Node module based formula would look like this:
Tooling
You can use homebrew-npm-noob to automatically generate a formula like the example above for an npm package.
The treehouse npm install guide for OSX uses brew to install npm. However the npm course suggests using npm to update itself. If we're using OSX shouldn't we be using brew to update npm too, as it was installed via brew?
I see your logic, and it's a bit off. Let me explain.
NPM is a package manager. Meaning that I use it to install packages for my app. In order to use npm, I can install it via brew. Once I have npm, I can use it to install packages globally, locally with the -g or --save during an npm install when getting packages I want to use in my app. npm update, updates the packages managed by npm. the packages installed via npm are not managed by brew. They are managed by npm and Brew knows nothing of the packages you installed with npm. npm will make sure you have the latest versions of the packages you are using in your app.
Now, you can also update npm with brew. Brew pulls npm from a repository. Say you wanted to use a beta version of npm that wasn't in the brew repository yet? You could use npm to update it'self. Or you could install different versions of npm for different projects. Let me ask you this, if npm can update itself. Why does brew have to update it for me? I wouldn't use brew to update my version of npm if npm can do it itself.
Does that makes sense?
Thanks, the first paragraph I was clear on, it was the second part of your response was what I was trying to understand. Without knowing the internals of how brew and npm work. Brew may have installed npm is a way unique to brew (that wasn't comptabile with the method npm uses).
but from your asnwer it sounds like it works like brew, python and pip. I use brew to install python globally or to usr/local (inc pip if python 3) and then use pip to update itself either globally or for each virtualenv (project). Thanks got it now.
Posting to the forum is only allowed for members with active accounts.
Please sign in or sign up to post.