devsetup1-6 Exercise 3: An npm Project, npm ci, and Global Tools ================================================================== PART 1: A PROJECT WITH A DEPENDENCY ----------------------------------- mkdir -p ~/projects/npm-demo && cd ~/projects/npm-demo npm init -y npm install lodash Create index.js: const _ = require('lodash'); console.log(_.chunk([1, 2, 3, 4, 5], 2)); Run it: node index.js # [ [ 1, 2 ], [ 3, 4 ], [ 5 ] ] Look at what npm created: ls # index.js node_modules package-lock.json package.json cat package.json # lodash listed under "dependencies" PART 2: DISPOSABLE node_modules ------------------------------- rm -rf node_modules node index.js # fails: Cannot find module 'lodash' npm ci node index.js # works again npm ci reads package-lock.json and installs exactly the versions recorded there, into a fresh node_modules. It is the right command for a clean rebuild (and for automated builds), because npm install may update versions within the ranges allowed in package.json. If package.json and the lock file disagree, npm ci stops with an error instead of quietly changing anything, which is what you want from a reproducible install. Add a .gitignore containing: node_modules/ so the folder is never committed. Commit package.json and package-lock.json. PART 3: A GLOBAL TOOL AND A VERSION SWITCH ------------------------------------------ nvm use 24 # or whichever version is your default npm install -g cowsay npm ls -g --depth=0 # cowsay is listed command -v cowsay # a path under ~/.nvm/versions/node/v24.../bin cowsay "hello from devserver" Now switch: nvm use 22 command -v cowsay # nothing printed: the tool "vanished" npm ls -g --depth=0 # cowsay is not listed under Node 22 EXPLANATION ----------- nvm keeps a separate set of global packages for each Node version. cowsay was installed under Node 24's directory, and Node 22 has its own, which does not contain it. Nothing was lost. Running nvm use 24 brings it back. TWO WAYS TO FIX IT ------------------ 1. Install it again under the other version: nvm use 22 && npm install -g cowsay 2. Carry your global tools across when adding a version: nvm install --reinstall-packages-from=current 22 (or, between versions already installed, nvm use 22 then nvm reinstall-packages 24). BETTER STILL ------------ For anything a project needs, put it in that project's package.json (and use npx for one-off runs), so it does not depend on a global copy or on which Node version happens to be active. WHY THIS WORKS AS AN ANSWER --------------------------- Part 2 shows the lock file is the record and node_modules is disposable. Part 3 explains a confusing behaviour with a real demonstration, and points to the practice that avoids the confusion altogether.