Wilson Mar bio photo

Wilson Mar

Hello. Hire me!

Email me Calendar Skype call 310 320-7878

LinkedIn Twitter Gitter Google+ Youtube

Github Stackoverflow Pinterest

JavaScript for the win


Overview

The objective of this tutorial is to spare you the pain and confusion around installing and uninstalling the various editions and versions of NodeJs. After going through this,

I want you to feel confident that you’ve mastered this skill. That’s why this takes a hands-on approach where you type in commands and we explain the responses and possible troubleshooting. This is a “deep dive” because all details are presented.

Like a good music DJ, I’ve carefully arranged the presentation of concepts into a sequence for easy learning, so you don’t have to spend as much time as me making sense of the flood of material around this subject.

Sentences that begin with PROTIP are a high point of this website to point out wisdom and advice from experience. NOTE point out observations that many miss. Search for them if you only want “TL;DR” (Too Long Didn’t Read) highlights.

Stuck? Contact me and I or one of my friends will help you.

Choose a way

Click on one of the mutually exclusive variations of installing Node for additional information and instructions:

Different editions

Installing Node has become complex due to the drama behind different editions and versions of Node with different mechanisms for managing updates, each with permissions issues. Many instructions on the internet are outdated, contradictory, or plain wrong.

Node.js was started as an open-source project in 2009 by Ryan Dahl. Its second contributor was Isaac Schlueter who now leads the project. Both are employed by Joyent.com, a cloud computing company purchaed in 2015 by Samsung (Korea).

The project had a total of 447 core contributors as of 2016. Dahl was employed by Joyent during much of Node’s development, and Joyent continues to sponsor Node. Joyent has raised in the neighborhood of $100 million in venture capital and has an employee headcount in excess of 120.

A VentureBeat article in 2013 writes “Two programmers named Ben Noordhuis and Bert Belder have founded a new company called StrongLoop. And they’re apparently attempting to hijack the Node brand and community for themselves.” Strongloop supports Express and LoopBack frameworks. On 10 Sep 2015, StrongLoop was acquired as IBM API Connect, which focuses on the API lifecycle.


Long Term Support

QUESTION: What are the install instructions If you’re an enterprise user paying for Long Term Support introduced Fall, 2015.

Long-term support (LTS) releases are actively developed for 18 months, then maintained for a further 12 months. This means a particular LTS release stays in production for 30 months with bug and security fixes.

N|Solid

N|Solid from NodeSource is a “fully compatible Node.js runtime enhanced to address the needs of enterprise production support.”

Their disto provides a GUI and a way to pull telemetry for V8 process monitoring.

https://downloads.nodesource.com

Again, this is a licensed product. I’ve heard that they provide support at $1,000 per developer per month ($12,000 per year).

io.js is gone

In 2013 iojs.org, a fork of Node.js was formed by several core committers frustrated by Joyant.

Then on September, 2015, io.js merged with the Node.js project again under new nodejs.org/en/foundation governance.

https://www.binarysludge.com/2015/01/14/how-to-uninstall-io-js-or-io-js-and-node-js-together/

NVM

NVM (Node Version Manager) downloads and installs multiple versions of Node.js, then enables using a specific version of Node, using a command such as this (after installation and cd to your node app folder):

nvm run 4.5.0 app.js

The above is for the LTS (Long Term Support) version.

If instead you want to run the latest versions of Node:

nvm run 6.4.0 app.js

PROTIP: Remember that there is no “v” to specify a version, unlike the install command:

nvm install v4.5.0

To do the above, you first have to install NVM and Node, described in the steps below.

NVM Install

Installation steps:

  1. PROTIP: Use an iternet browser to read the README.md at https://github.com/creationix/nvm

  2. Note the version of installer:

    v0.31.6/install.sh
    
  3. If you’ve installed another way before, make sure that if you have an ~/.npmrc file, it does not contain any prefix settings (which is not compatible with nvm):

    atom ~/.npmrc

    An example:

    prefix=/Users/mac/.npm-packages
    

    PROTIP: This file is used by “Option A” above, thus the mutually exclusive options.

  4. Install C++ Compiler.

    NVM uses a C++ compiler installed with Apple’s stand-alone Command Line Tools also within Apple’s XCode application.

    The README at https://github.com/creationix/nvm notes that it uses a C++ compiler installed with Apple’s stand-alone Command Line Tools also within Apple’s XCode application.

  5. Agree to Apple’s license:

    sudo xcodebuild -license

    Type in your root password, hold down Enter until it stops, then type agree and Enter.

  6. Install NVM using wget:

    
    wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.31.6/install.sh | bash
    

    PROTIP: The instructions say either curl or wget, but I prefer using wget because it is not installed by default, and nvm requires it. So if you don’t have wget, better to know it sooner than later.

    The command installs to hidden folder ~/.nvm and looks into the ~/.bashrc file used by Linux machines. More on this soon.

    The response:

    => Downloading nvm from git to '~/.nvm'
    => Cloning into '~/.nvm'...
    remote: Counting objects: 5275, done.
    remote: Compressing objects: 100% (4/4), done.
    remote: Total 5275 (delta 0), reused 0 (delta 0), pack-reused 5271
    Receiving objects: 100% (5275/5275), 1.44 MiB | 493.00 KiB/s, done.
    Resolving deltas: 100% (3177/3177), done.
    Checking connectivity... done.
    bash: line 73: cd: ~/.nvm: No such file or directory
     
    => Source string already in /Users/mac/.bashrc
    => You currently have modules installed globally with `npm`. These will no
    => longer be linked to the active version of Node when you install a new node
    => with `nvm`; and they may (depending on how you construct your `$PATH`)
    => override the binaries of modules installed with `nvm`:
     
    /usr/local/Cellar/node/6.3.1/lib
    ├── less@2.7.1
    ├── resume-cli@0.4.13
    └── stylus@0.54.5
     
    => If you wish to uninstall them at a later point (or re-install them under your
    => `nvm` Nodes), you can remove them from the system Node as follows:
     
      $ nvm use system
      $ npm uninstall -g a_module
     
    => Close and reopen your terminal to start using nvm
    

    If you see this instead:

    => nvm is already installed in /Users/mac/.nvm, trying to update using git
    => 
    => Source string already in /Users/mac/.bashrc
    => You currently have modules installed globally with `npm`. These will no
    => longer be linked to the active version of Node when you install a new node
    => with `nvm`; and they may (depending on how you construct your `$PATH`)
    => override the binaries of modules installed with `nvm`:
     
    /usr/local/Cellar/node/6.2.2/lib
    └── grunt@1.0.1
     
    => If you wish to uninstall them at a later point (or re-install them under your
    => `nvm` Nodes), you can remove them from the system Node as follows:
     
      $ nvm use system
      $ npm uninstall -g a_module
     
    => Close and reopen your terminal to start using nvm
    

    CAUTION: NVM does not recognize the PREFIX used in the Alternate folder technique. So we would need to live with just elevated permissions.

    What the above does is equivalent to:

    cd ~
    git clone http://github.com/creationix/nvm.git .nvm

    So the command above is what some recommend to fix issues with nvm install.

  7. Verify:

    nvm --version

    If you get a version code such as the below (25 August 2016), proceed to use NVM.

    0.31.6
    

    TROUBLESHOOTING: If instead of the version code, this message appears:

    -bash: nvm: command not found
    
  8. Edit the file that Mac uses to initiate Terminal, using atom or other editor (vi, nano, etc.)

    atom ~/.bash_profile

    Add to the bottom of the file:

    Export the NVM path and run its shell:

    export NVM_DIR=”$HOME/.nvm”
    [ -s “$NVM_DIR/nvm.sh” ] && . “$NVM_DIR/nvm.sh” # This loads nvm </strong></tt>

  9. Restart Terminal so it takes:

    source ~/.bash_profile

  10. To verify that nvm has been installed:

    command -v nvm

    NOTE: nvm is a shell script, not an executable, so the usualy where command does not work.

    The response should be:

    nvm
    
  11. To verify that nvm has been installed:

    echo $NVM_DIR

    The response should be (where “mac” is substituted with your own user id):

    /Users/mac/.nvm
    
  12. For a list of commands, type nvm by itself:

    nvm

    PROTIP: Widen the screen to avoid text wrapping.

    Upgrade NVM

  13. To download, compile, and install the latest v5.0.x release of node:

    nvm install

    The response:

    Downloading https://nodejs.org/dist/v5.0.0/node-v5.0.0-darwin-x64.tar.xz...
    ######################################################################## 100.0%
    nvm is not compatible with the npm config "prefix" option: currently set to "/Users/mac/~/.nvm/versions/node/v5.0.0"
    Run `npm config delete prefix` or `nvm use --delete-prefix v5.0.0` to unset it.
    

    Use NVM to install Node

  14. To list what versions of Node.js are installed:

    nvm ls

    The response is like this:

    ->       v6.4.0  
          system  
    default -> node (-> v6.4.0)
    node -> stable (-> v6.4.0) (default)
    stable -> 6.4 (-> v6.4.0) (default)
    iojs -> N/A (default)
    lts/* -> lts/argon (-> N/A)
    lts/argon -> v4.5.0 (-> N/A)
    

    Available to install

  15. To list what versions of Node.js are available to install:

    nvm ls-remote

    Scroll to “(Latest LTS: Argon)”, such as:

    v4.5.0   (Latest LTS: Argon)
    

    It’s installed by these instructions.

    The latest version is at the bottom of the list, such as:

    v6.4.0
    

    Clear NPM Cache

    sudo npm cache clean -f

    Install latest version

  16. Install the latest version of Node.js:

    nvm install node

    The response:

    Downloading https://nodejs.org/dist/v6.8.1/node-v6.8.1-darwin-x64.tar.xz...
    ######################################################################## 100.0%
    Now using node v6.8.1 (npm v3.10.8)
    

    Notice that there is specific version of npm to support each version of Node.

    TROUBLESHOOTING: If these message also appear:

    perl: warning: Setting locale failed.
    perl: warning: Please check that your locale settings:
    LC_ALL = (unset),
    LC_CTYPE = "en_US.utf-",
    LANG = "en_US.UTF-8"
     are supported and installed on your system.
    perl: warning: Falling back to the standard locale ("C").
    tar: Failed to set default locale
    

    As this advises, get rid of those messages on the Mac by going to Terminal > Preferences > Advanced tab to uncheck “Set locale environment variables on startup”:



    Exit Terminal to activate it or you’ll see the message again.

    Uninstall Node version

    Installing does not automatically uninstall previous versions.

  17. To uninstall a version:

    nvm uninstall v6.4.0

    The response:

    Uninstalled node v6.4.0
    

  18. Install the most recent LTS version of Node according to nvm ls-remote:

    nvm install v4.5.0

Facts for Troubleshooting

PROTIP: Before you speak to someone about this, provide them your operating system facts, obtained using instructions here:

  1. Operating system information:

    
    uname -a
    

    On my machine, the response:

    Darwin macs-MacBook-Pro-4.local 15.5.0 Darwin Kernel Version 15.5.0: Tue Apr 19 18:36:36 PDT 2016; root:xnu-3248.50.21~8/RELEASE_X86_64 x86_64
    
  2. Obtain node version:

    
    node -v
    

    At time of writing, the response for the most recent version:

    v6.4.0
    
  3. Obtain npm version:

    
    npm -v
    

    At time of writing, the response (for the Node version obtained above):

    3.10.3
    
  4. Verify:

    
    echo $NODE_PATH
    

    The response if installed by NVM or by downloaded installer:

    /usr/local/bin
    

    The response if installed using brew:

    /Users/mac/.npm-packages/lib/node_modules:/usr/local/bin
    

    Regardless of how you installed node, before discussing your installation, obtain and present these facts:

  5. Where is Node installed?

    which node

    The answer:

    /usr/local/bin/node
    
  6. Where is Node installed?

    which npm

    The answer:

    /usr/local/bin/npm
    
  7. From any folder, for just a simple list of package names:

    
    ls \`npm root -g\`
    

    PROTIP: npm itself is a Node package.

    Alternately, list global npm packages installed as a tree:

    
    npm list -g --depth=0
    

    The response is a list with version numbers:

    /Users/mac/.npm-packages/lib
    ├── bower@1.7.9
    ├── express@4.13.4
    ├── grunt@1.0.1
    ├── grunt-cli@1.2.0
    ├── learnyounode@3.5.3
    ├── n@2.1.0
    ├── npm@3.9.5
    └── serverless@0.5.6
    

    Note the first line in the response shows the folder.

    Which version of what?

    PROTIP: Odd version numbers of Node.js are considered unstable development versions.

Instead of using an internet browser to download an installer from
https://nodejs.org/en/download/releases/
consider these:

  • nvm (node version manager) is a shell function that downloads and upgrades versions of node.js. It’s not needed unless you want to keep and upgrade multiple versions of Node.js. But you will eventually will need to.

  • npm (node package manager) installs JavasSript packages such as Express.js.

Ideally, we would have both nvm and npm on the same machine, each configured the way we want for maximum productivity.

However, there is a conflict between the ideal way of installing npm with how nvm works.

The ideal way to install most applications is to NOT need to use the sudo prefix command to temporarily elevate permissions.

On a Mac, by default, npm is installed in the .npm folder.

To make it work, we install it in the .npm-packages folder by placing a configuration setting.

However, nvm does not recognize that configuration setting and thus only works with plugins installed in the default .npm folder.

Yes, why can’t people from nvm and npm get together and work things out?

Thus, a choice needs to be made.

Does node REPL work?

  1. Initialize the Node command-line:

    node

    The response:

    > console.log('Node is running');
    Node is running
    
  2. From inside REPL, get a list of commands (with a leading dot):

    .help

    PROTIP: Node interactive commands begin with a dot.

    The response:

    .break Sometimes you get stuck, this gets you out
    .clear Alias for .break
    .exit  Exit the repl
    .help  Show repl options
    .load  Load JS from a file into the REPL session
    .save  Save all evaluated commands in this REPL session to a file
    
  3. To get out:

    .exit


Brew standard install

  1. If you have already followed instructions at my Homebrew installation tutorial to install Homebrew:

    Click here if you want to go straight to the recommended option B.

    WARNING: Homebrew installs Node to a different location than other ways.

  2. The simplest way to install node is to use Homebrew:

    
    brew install node -g
    

    The response:

    ==> Downloading https://homebrew.bintray.com/bottles/node-6.3.0.el_capitan.bottl
    ######################################################################## 100.0%
    ==> Pouring node-6.3.0.el_capitan.bottle.tar.gz
    ==> Caveats
    Please note by default only English locale support is provided. If you need
    full locale support you should either rebuild with full icu:
      `brew reinstall node --with-full-icu`
    or add full icu data at runtime following:
      https://github.com/nodejs/node/wiki/Intl#using-and-customizing-the-small-icu-build
     
    Bash completion has been installed to:
      /usr/local/etc/bash_completion.d
    ==> Summary
    🍺  /usr/local/Cellar/node/6.3.0: 3,829 files, 39.8M
    

    Notice the folder (which may have a different version number):

    ~/Library/Caches/Homebrew/node-6.3.0.el_capitan.bottle.tar.gz
    

    NOTE: By default, when node is installed, it installs npm, the Node Package Manager, a node package to install additional packages.

  3. Identify which folder npm is obtained:

    
    which npm
    

    The response for default installations:

    /usr/local/bin/npm
    

    Alternatively:

    /Users/mac/.npm-packages/bin/npm
    
  4. List npm global modules installed on the default global module folder:

    
    ls /usr/local/lib/node_modules
    

    The response is simply “npm”.


Install node without npm, then install .npm-packages with no nvm

### Uninstall default install #

  1. If node was previously installed, uninstall it:

    
       brew uninstall node
       
  2. If node was previously installed, these folders have been known to block re-install, so remove them:

    sudo rm '/usr/local/lib/dtrace/node.d'
    sudo rm `/usr/local/bin/npn'
    sudo rm `/usr/local/bin/node'
    sudo rm `/usr/local/share/doc/node/gdbinit'
    sudo rm `/usr/local/share/man/man1/node.1`
    sudo rm `/usr/local/share/systemtap/tapset/node.stp`
    sudo rm `/usr/local/share/systemtap/tapset`
    

    Create .npm-packages folder

  3. Create the ~/.npm-packages folder:

    
    mkdir "${HOME}/.npm-packages"
    
  4. To avoid permission issues:

    
    sudo chown -R $USER:$GROUP ~/.npm-packages
    sudo chown -R $USER:$GROUP ~/.config
    sudo chown -R $USER:admin /usr/local/
    sudo chown -R $USER:admin /usr/local/include
    

    Provide your password when prompted.

  5. Indicate to npm where to store globally installed packages by adding a line at the bottom of the ~/.npmrc file:

    
    echo prefix=~/.npm-packages >> ~/.npmrc
    

    WARNING: NVM does not support this.

  6. Install node without default npm:

    
     brew install node --without-npm -g
     

    Alternately, install npm for global use:

    
    curl -L https://www.npmjs.com/install.sh | sh
    

    The response:

    fetching: http://registry.npmjs.org/npm/-/npm-3.9.5.tgz
    
  7. After install, verify the location:

    
    which node
    

    The response:

    /usr/local/bin/node
    
  8. Define where Node is installed:

    export NODE_INSTALL=/usr/local/bin/node
    echo $NODE_INSTALL

    This is needed because Node is installed into several folders:

    • sudo rm -rf $NODE_INSTALL/bin/node
    • sudo rm -rf $NODE_INSTALL/bin/npm
    • sudo rm -rf $NODE_INSTALL/include/node
    • sudo rm -rf $NODE_INSTALL/lib/node_modules
    • sudo rm -rf ~/.npm

  9. After install, verify the location:

    
    which npm
    

    The response, where “mac” is substituted with your user name:

    /Users/mac/.npm-packages/bin/npm
    
  10. To ensure npm will find installed binaries and man pages, use a text editor to edit the ~/.bash_profile file.

    BTW, .bash_profile on Mac is equivalent to the .bashrc file used in Linux systems.

  11. Add a NPM_PACKAGES environment variable containing the path to npm-installed packages into the system PATH variable:

    
    NPM_PACKAGES="${HOME}/.npm-packages"
    PATH="$NPM_PACKAGES/bin:$PATH"
    
  12. To identify where node executables are installed:

    
    which node
    

    the response:

    /usr/local/bin/node
    

    See that Node one among many other programs at:

    ls /usr/local/bin
    
  13. Make sure that this path containing the node executable is in the PATH:

    echo $PATH
    

    If not add it to the system PATH:

    export NODE_PATH=/usr/local/bin
    
  14. Save changes to the .bash_profile file.
  15. Run the file into memory:

    
    source ~/.bash_profile
    

The above is recommended by Advice on fixing npm On Mac OS X for Homebrew Users

BTW, an alternative to NVM is “n” from https://github.com/tj/n. However, I never got it to work for me.


C: Download and Install Node

  1. Download installer from http://nodejs.org
  2. Use the Mac Finder to navigate to the file in your Downloads folder.
  3. Unzip the file downloaded.
  4. Execute the file.
  5. Respond to the prompts.
  6. Skip to Verify the install

Install Node packages

  1. The current global location:

    npm config get prefix

    The answer (where “mac” is substituted with your user name):

    /Users/mac/.nvm/versions/node/v6.4.0
    

    See https://www.sitepoint.com/beginners-guide-node-package-manager about global vs. local package install.

  2. The command to install a package without additional parameters is, for example:


   pwd
   npm install serverless
   

This installs the node packages locally within whatever folder is the present working directory, revealed by the pwd command.

However, we usually need node packages to be installed globally for access from any present directory by any user on the machine.

This location is one MacOS requires sudo (super user do) permission elevation. For example:


   sudo npm install serverless -g
   

Without sudo, an error would occur from the above command such as:

   npm WARN checkPermissions Missing write access to ...
   

This is because the default npm folder is managed at the system level, not user level.

To avoid these permission issues, some recommend higher permissions to folders, as in:


   sudo chown -R $USER:$GROUP ~/.npm
   sudo chown -R $USER:$GROUP ~/.config
   

This may not be enough to address installation issues when using Homebrew such as when upgrading with command:


   npm update npm -g
   

#### Alternate folder #

We can install the folder under a user’s HOME folder, which is defined by the ${HOME} environment variable:


   echo "${HOME}"
   

The alternative npm folder name established by convention is:


   ls ~/.npm-packages
   

To achieve this, we first need to uninstall the default install:


   rm -rf /usr/local/lib/node_modules
   brew uninstall node
   

All of Node needs to be uninstalled because it installed npm which uses the system folder.

To install node for global use, we can invoke

npm-g_nosudo


Code Node JavaScript

To enable publication on NPM and Bower, packages such as Datatables contain extensions and styling options in well defined CommonJS and AMD loaders. This also opens options to use other tools such as Browserify and WebJars.

Others who have blogged about this include:

  1. Make a folder containing Node application files, and go to it:

  2. Install the express package and its dependencies:

    
    npm install express -g
    
  3. Use a text editor to create file index.js containing “Hello World” code in JavaScript:

    /*jslint node: true */
    var express = require('express');
    var app = express();
    app.get('/', function(res,req){
       res.json({
          message: 'hello world'
       });
    });
    app.listen(3000); // This establishes port 3000. You can use another port.
    

    NOTE: Semicolons and carriage returns serve the same purpose in JavaScript. You only need semicolons if you are concatenating code together in a single line.

    See https://www.airpair.com/javascript/posts/eleven-mistakes-developers-javascript

  4. Start the Node server running the default index.js program:

    
    node index.js
    

    The window remains open and accept no other commands until you press control+C to escape the process.

  5. Switch to an internet browser to open the Node Express web server running locally at port 3000:

    http://localhost:3000/
    

    If you get “TypeError: res.json is not a function” …

    Nodemon

  6. See https://github.com/remy/nodemon

  7. Install NodeMon:

    
    npm install nodemon -g  # -g installs globally as system command.
    nodemon index.js   # watch for changes and kill server when needed
    
  8. Restart your node server specified in a coffee-script:

    nodemon server.coffee

Bower Install

Bower is similar to NPM, but for front-end GUI applications.

Any frameworks or 3rd-party libraries that need to be accessible in the user’s browser will be managed by bower.

Similarly to NPM, bower tracks dependencies in a file called bower.json.

  1. Install bower globally via npm:

    
    npm install -g bower
    

    Running bower install will resolve, download, and install them.

    Project Bower Install

  2. cd to the project’s folder.

  3. Install the project’s bower components using bower:

    
    bower install
    
  4. Install http-server using npm:

    
    npm install -g http-server
    
  5. Fire up the server at default port 8080:

    
    http-server client/
    
    
    npm ls
    
    
    http-server client/
    

Node modules

A module is a single JavaScript file.

A package is a directory containing modules.

A list of shorthands for the NPM command
https://docs.npmjs.com/misc/config

Famous Node modules:

Grunt

npm install -g grunt-cli

The response:

/usr/local/Cellar/node/6.2.2/bin/grunt -> /usr/local/Cellar/node/6.2.2/lib/node_modules/grunt-cli/bin/grunt
/usr/local/Cellar/node/6.2.2/lib
└─┬ grunt-cli@1.2.0 
  ├─┬ findup-sync@0.3.0 
  │ └─┬ glob@5.0.15 
  │   ├─┬ inflight@1.0.5 
  │   │ └── wrappy@1.0.2 
  │   ├── inherits@2.0.1 
  │   ├─┬ minimatch@3.0.2 
  │   │ └─┬ brace-expansion@1.1.5 
  │   │   ├── balanced-match@0.4.2 
  │   │   └── concat-map@0.0.1 
  │   ├── once@1.3.3 
  │   └── path-is-absolute@1.0.0 
  ├── grunt-known-options@1.1.0 
  ├─┬ nopt@3.0.6 
  │ └── abbrev@1.0.9 
  └── resolve@1.1.7 
   

Gulp

LearnNode Programming Tutorial

The classic interactive tutorial introducing Node.Js was created on:

https://github.com/workshopper/learnyounode

To install it we reference its npm package on npm.org:

  1. Run npm install learnyounode -g

    Notice the -g can go before or after the module being installed.

  2. Run learnyounode

    learnyounode 1080x640

    NOTE: Use keyboard up/down arrows to select option. This is not a GUI interface.

    The tutorial consumes a Terminal window process.

  3. To exit, press control/command + C to close the process.

  4. When you’re done, run npm uninstall learnyounode.

How NPM works

HEADS UP! This article was written for an older version of node. More up-to-date information may be available elsewhere. https://howtonode.org/introduction-to-npm

http://stackoverflow.com/questions/25897908/how-npm-install-works

https://www.npmjs.org/doc/cli/npm-shrinkwrap.html

I use Node.js (via browserify) for each of my web apps, all of which have some dependencies in common and others specific to themselves. Each of these apps has a package.json file that specifies which versions of which modules it needs.

Yes, that is what npm install does. In node.js code, the require algorithm has a particular sequence of places it looks, including walking up the filesystem. However, npm install doesn’t do that. It just installs in place. The algorithms it uses are all constrained to just a single node_modules directory under your current directory and it won’t touch anything above that (except for with -g).

Right now, I have a /node_modules directory in the parent folder of my apps for modules that they all need to reference, and then I put app-specific modules in a node_modules folder in that app’s directory. This works fine in the short term, since my require() statements are able to keep looking upward in the file structure until they find the node_modules directory with the correct app in it.

Where this gets tricky is when I want to go back to an old project and run npm install to make sure it can still find all the dependencies it needs. (Who knows what funny-business has occurred since then at the parent directory level.) I was under the impression that npm install did this:

for each module listed in package.json, first check if it's present, moving up the directory the same way require does. If it's not, install it to the local node_modules directory (creating that directory if necessary).

When I run npm install inside an app folder, however, it appears to install everything locally regardless of where else it may exist upstream. Is that the correct behavior? (It’s possible there’s another reason, like bad version language in my package.json). If this IS the correct behavior, is there a way for me to have npm install behave like the above?

It’s not a big deal to widely replicate the modules inside every app, but it feels messy and prevents me from make small improvements to the common modules and not having to update every old package.json file. Of course, this could be a good thing…

Yeah basically you’re doing it wrong. The regular workflow scales well to the Internet. For your use case it creates some extra tedious work, but you can also just use semantic versioning as intended and specify “mylib”: “^1.0.0” in your package.json for your apps and be OK with automatically getting newer versions next time you npm install.

If installed using homebrew so it’s done on every shell session: Add to ~/.profile

Node JavaScript Coding Sample

var express = require('express');
var app = express();
app.get('/', function(res,req){
   res.json({
   message: 'hello world'
   });
});
app.listen(3000);

Additional topics

source $(brew –prefix nvm)/nvm.sh

Resources

Several blogs addresses issues related to this topic:

More on MacOS

This is one of a series on MacOS: