w3resource

Understanding packages and modules and preventing permissions errors


In this tutorial we are going to help you understand packages and modules, we will also teach you how to prevent permission errors.

Understanding packages and modules

Both npm and node.js have very specific definitions for packages and module, and it is easy to mix them up. We are going to discuss those definitions in this tutorial, we will make them distinct and explain why some default are named the way they are.

Quick Summary

  • A package is a directory or file that is described by a package.json. This description can happen in a bunch of different ways!
  • A module is any directory or file that can be loaded by Node.js' require(). Again, there are so many configurations that allow this to happen.

What is a package?

A package can be defined by any of the following:

  1. A folder that has a program described by a package.json file.
  2. A gzipped tarball that contains (a).
  3. A url that will resolve to (b).
  4. A <name>@<version> that has been published on the registry with (c).
  5. A <name>@<tag> that points to (d).
  6. A <name> that contains a latest tag satisfying (e).
  7. A git url that, results in (a) when it is cloned.

With all these package possibilities, we can conclude that even if you do not publish your package to the public registry, you can still get a lot of the benefits of using npm:

  • If you only want to write a node program, and/or,
  • If you equally want to be able to easily install it elsewhere after packing it up into a tarball.

The git urls could be of this form:

git://github.com/user/project.git#commit-ish
git+ssh://[email protected]:project.git#commit-ish
git+http://[email protected]/project/blah.git#commit-ish
git+https://[email protected]/project/blah.git#commit-ish

The commit-ish could be any tag, sha, or branch that can be supplied as an argument to git checkout. Master is the default.

What is a module?

A module is anything that you can load with require() in a Node.js program. Examples of things that can be loaded as modules are as shown below:

  • A folder with a package.json file that contains a main field.
  • A folder that has an index.js file in it.
  • A JavaScript file.

Most npm packages are modules

Generally, npm packages that are used in Node.js programs are loaded with require, this makes them modules. However, it is not a requirement that an npm package be a module.

Some packages, such as cli packages, only have an executable command-line interface and do not provide a main field for use in Node.js programs. Such packages are not modules.

Nearly all npm packages (at least, those that are Node programs) have many modules within them (because every file they load with require() is a module).

In the context of Node programs, the module will also be the thing that was loaded from a file. For instance, in the program below:

var req = require('request')

It can be inferred that "The variable req refers to the request module".

File and Directory Names in the npm and node.js Ecosystem

So, why do we have the node_modules folder, but package.json file? Why not a node_packages folder or module.json file?

This is because the package.json file defines the package. While, the node_modules folder is the place Node.js will look for modules.

For instance, if you create a file at node_modules/test.js and then had a program that did var t = require('test.js'), it loads the module. However, test.js is not a "package" in this case because it doesn?t have a package.json.

Alternatively, if you create a package that does not have an index.js or a "main" field in the package.json file, then it is not a module. Even if it is installed in node_modules, it cannot be an argument to require().

How to Prevent Permissions Errors

If you encounter an EACCES error when you try to install a package globally. Often, you can avoid this error if you change the directory where npm is installed. To do this, it is either:

  1. You reinstall npm with a version manager (recommended),
  2. or
  3. You change npm's default directory manually.

Option One: Reinstalling with a Node Version Manager

This is always the best way to avoid permissions issues. This is described in our tutorial on installing npm. You do not have to remove your current version of npm or Node.js before installing a node version manager.

Option Two: Change npm's Default Directory

It should be noted that section does not apply to Microsoft Windows.

If you minimize the chance of permissions errors, you may configure npm to use a different directory. In this example, it is a hidden directory on your home folder.

  1. You should back-up your computer before you start.
  2. Then make a directory for global installations:
  3. mkdir ~/.npm-global
  4. Configure npm to use this new directory path:
  5. npm config set prefix '~/.npm-global'
  6. You should then create or open a ~/.profile file and add the line below:
  7. export PATH=~/.npm-global/bin:$PATH
  8. Back on your command line, you can update your system variables:
  9. source ~/.profile

Test: you will have to download a package globally without using sudo.

 npm install -g jshint

Rather than steps 2-4, you could use the corresponding ENV variable (for example. if you don't want to modify ~/.profile):

NPM_CONFIG_PREFIX=~/.npm-global

Previous: How to change profile settings
Next: How to run a security audit with npm audit