This post contains a brief summary of my learnings from a Udemy course titled Understanding NPM taught by Bodgan Stashchuk

Though I have been using nodejs for some random tasks, I had never understood the way NPM works. I found the course very useful as the instructor covered a quite a lot of details in 2.5 hours.

Introduction

This section gives a brief background about the topics that are going to be covered in the course

  • How can you initialize package manager ?
  • What is package.json ?
  • What is semantic versioning ?
    • Major minor and patch version differences
    • What are special characters such as tilde mean ?
  • Why node modules folder is so large and why shouldn’t be committed to source control system ?
  • Real difference between dependencies and development dependencies ?
  • Difference between browser applications and server packages ?
  • What is the purpose of package-lock.json file ?
    • How does this file help in obtaining same software versions on different computers ?
  • What are npm scripts ?
    • What is the purpose of each script ?
    • How is it executed ?
    • What are built in npm scripts ?
    • What are custom npm scripts ?
    • How does one combine all scripts in one script ?
  • What is the purpose of bin folder ?

Introduction to the NPM

  • If different people work on the same project and do not want to distribute, then you don’t need package.json file
  • npm.init creates the package.json file
    • One can specify the dependencies for the package
  • Each public package must have unique name and version
  • Special agreement for software versioning
  • Version comprises three parts - major, minor and patch version
    • 5.21.17
    • major, minor and patch versions separated by dot
    • patch : bug fixed version
    • minor: introduce new features but remains compatible with previous features
    • major: non compatible features and creates completely different framework
  • Exact version , Greater than version, Compatible changes, Minor-level changes
    • 5.21.17, >5.21.1, ^5.21.8, ~5.21.8~
  • Pre-release versions alphabet soup
    • 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc>
  • Install packages using npm or yarn
  • all packages will be installed in node_modules folder
  • npm install <package>
    • added in the node_modules folder and added as dependency in the package.json file
  • npm install <package> =save-dev
    • added in the node_modules folder and added as development dependency in the package.json file
  • As soon as you install, there are a bunch of files and folders created
    • package.json
    • package-lock.json
    • node_modules folder
  • ~ vs ^ in dependencies from stackoverflow
    • ~
      • freezes major and minor numbers.
      • It is used when you’re ready to accept bug-fixes in your dependency, but don’t want any potentially incompatible changes.
      • The tilde matches the most recent minor version (the middle number).
      • ~1.2.3 will match all 1.2.x versions, but it will miss 1.3.0.
      • gives you bug fix releases
    • ^
      • freezes the major number only.
      • It is used when you’re closely watching your dependencies and are ready to quickly change your code if minor release will be incompatible.
      • It will update you to the most recent major version (the first number).
      • ^1.2.3 will match any 1.x.x release including 1.3.0, but it will hold off on 2.0.0.
      • gives you backwards-compatible new functionality as well.

Dependencies and Development Dependencies

  • Installation of packages is transitive
  • In package.lock file, the development dependencies are also specified
  • Installation of development dependencies is not transitive
  • node_modules can be be removed and one can easily replicate all the relevant packages
  • node_modules need not be committed to any version control
  • package.json contains dependencies and development dependencies
  • Should one add a package as dependency or development dependency ?
    • Are you building browser app or server package ?
    • browser app
      • should contain at least one file index.html
    • server package
      • they do not need to contain any html files
  • Browser app cannot work with node modules out of the box
  • Installed an external package, pick up the relevant JavaScript function and inserted directly in to local JavaScript function.
  • Dependencies and development dependencies have no relation to the browser app
  • Browser doesn’t know anything about node_modules, package.json etc
  • When you build browser applications, it does not matter how you use packages. You will use packages to build a final application
  • Browser does not understand dependencies or development dependencies. It uses only the files that are served to the browser
  • How should one add each package ?
    • Add all packages as development dependencies or dependencies. It does not matter
    • If yours is a stand alone application,it does not matter how you will add the dependencies
    • Don’t install some packages as development packages and some as dependent packages
  • Add dependency only if
    • Your package is public
    • Compiled version of your package uses features from dependent packages
    • Other packages depend on your package
    • Most packages in the world are used on the server only during development of other packages
  • If you build stand alone app for the browser, add all packages as development dependencies
  • If you build public packages, or compiled code from other packages, then you can use add them as dependency packages

NPM packages versions and package-lock.json file

  • There are special commands to view the packages npm view <package>
  • One can see all the versions of the package including beta releases is obtained by npm view <package> versions
  • One can install a specific package using the command npm install <package@version>
  • npm audit gives the list of all issues with the current modules
  • All issues are available on github
  • package-lock.json keeps versions tree of the project dependencies including child dependencies
  • Without package-lock.json file, different computers might have different versions of packages could be installed if your dependency package mentions ^ version of a package
    • This might create problems as different members in a project will be working with different packages committing to a common repository
  • Lock file is created automatically starting from NPM v5.0.0 and is updated automatically
  • How is lock file handled ?
    • lock file should always be committed to source control
    • mode_modules should not be committed
    • lock file is not published to NPM software registry
    • a lock file for each project
  • Advantages of lock file
    • guarantees consistency of the dependencies versions
    • generated and updated automatically
    • committed to source control

Update NPM packages

  • npm update updates all listed packages to the latest release version within SemVer
  • npm update <package@version> to update specific packages
  • If you don’t use --save-exact option, npm update will not update to the latest version

NPM scripts

  • Used to perform certain operations quickly
  • a default test script is put in the package.json file
  • One can specify any JavaScript file and mention that in “scripts” element of package.json so that one can easily run from the terminal
  • Other elements that you can add in are
    • prestart
    • main file executed when you want to use the package
  • Custom npm scripts can be created and run via npm run <script
  • One can run multiple scripts using npm-run-all package
    • npm-run-all --serial custom1 custom2
    • npm-run-all --parallel custom1 custom2

Executable Scripts in NPM

  • NPM will look for bin field of every package that is included and then creates relevant executables in the main bin folder of node_modules
  • One can use built in npm scripts, use built in scripts, launch scripts in parallel or in a serial fashion
  • Each script in the bin folder corresponds to various node modules

Cheatsheet

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
npm i                            : Alias for npm install
npm install                      : Install everything in package.json
npm install --production         : Install everything in package.json, except devDependecies
npm install lodash               : Install a package
npm install --save-dev lodash	 : Install as devDependency
npm install --save-exact lodash	 : Install with exact
npm list                         : Lists the installed versions of all dependencies in this software
npm list -g --depth 0            : Lists the installed versions of all globally installed packages
npm view                         : Lists the latest versions of all dependencies in this software
npm outdated                     : Lists only the dependencies in this software which are outdated
npm update                       : Update production packages
npm update --dev                 : Update dev packages
npm update -g                    : Update global packages
npm update lodash                : Update a package
npm i sax                        : NPM package
npm i sax@latest                 : Specify tag latest
npm i sax@3.0.0	                 : Specify version 3.0.0
npm i sax@">=1 <2.0"	         : Specify version range