In our team we are working with different technologies, but there are some tools we use through all our projects: git for Source Code Management and npm as a package manager for client- and server-side projects.
npm has a lot more features than most developers use. In this article we will explain some of the most commonly used functionalities in our team.

npm scripts

scripts is one of the most frequently used features in our team. npm can not only be used as a package manager for node.js, but is also suitable as a language agnostic task-runner.
In order to run your custom scripts with npm you just need to add some entries to the scripts section of your package.json file:

{
  "name": "mypackage",
  "author": "webkid.io"
  "scripts": {
    "test": "ava"
  },
  "devDependencies": {
	"ava": "^0.20.0"
  }
}

In the above example you can enter npm test in order to run ava. In this case you might think that this approach isn't as convenient as calling the ava command directly, since this is shorter. On the other hand, you should consider that if you don't have the folder ./node_modules/.bin exported to your PATH, you will end up calling ava as ./node_modules/.bin/ava, which isn't shorter at all. Moreover you can add the npm test command to your documentation, without worrying about future changes to your internal tool-chain.
There are some predefined scripts names, as for example test and start. If you define a custom script myscript you will be able to call it via:

npm run myscript

A useful shortcut to get a list of the commands interfaced by npm scripts is:

npm run

This will print out all available scripts and the command they will execute.

By using the natively provided hooks you can trigger certain commands on start, postinstall or test. You can use this feature for autogenerating a changelog running the git-changelog on version for example.

Combine git hooks and npm scripts

If you want to make sure that nobody in your team pushes changes to your repository that will break your tests, you could use a tool like husky (which gives you git hooks like precommit). Run npm install --save-dev husky and add the following command to the scripts section of your package.json:

{
  "scripts": {
    "precommit": "npm test",
    ...
  }
}

This will run npm test every time you enter git commit and it will proceed committing the changes only if the script exits with a 0 exit-code, meaning no error occurred. You can of course decide to run other scripts than npm test or to hook another command instead of commit.

npm variables

You can also define variables in the config section of your package.json. This can be helpful if you want be able to change the parameters of your scripts without changing the script definition.
Let's say you have a script start to start a web-server in your /dist folder:

{
  "scripts": {
    "start": "http-server dist -p 8000",
    ...
  }
}

and you want to be able to easily change the port without worrying about touching the right parameter, you can adjust your package.json as following:

{
  "config": {
    "port": 8000,
    "folder": "dist"
  },
  "scripts": {
    "start": "http-server $npm_package_config_folder -p $npm_package_config_port",
    ...
  }
}

As you can see we are now able to use the $npm_package_config_port variable within our command.

Managing package-lock.json or yarn.lock files

Yarn and npm 5 introduced lockfiles. These files, respectively yarn.lock and package-lock.json, are supposed to be commited to your git repository as explained on npmjs.com:

It is highly recommended to commit the generated package lock to source control: this will allow anyone else in your team, your deployments, your CI/continuous integration, and anyone else who runs npm install in your package source to get the exact same dependency tree that you were developing on.

Unfortunately this is causing a lot of trouble in the node.js developer community as shown by the more than 1K issues mentioning package-lock.json in the npm repository.

Screenshot_2017-11-01_12-10-30

We collected a couple of useful tips to handle lockfiles, but be careful as these approaches are really naive and cannot safely avoid dependency mismatch.

1. Handle as binary files

You can add these lines to a .gitattributes file located in your root folder:

package-lock.json   binary
yarn.lock           binary

git will handle them as binary files and exclude their diff from the git diff command output for you. From now on conflicts aren't handled line-by-line and you can therefore only decide to take the last version of the file or commit your own.

2. Generate a new lockfile

If you are not sure on what to do solving a conflict, a simple approach could be to delete the conflicted version of the file and run npm install (or yarn) again:

rm package-lock.json # or yarn.lock
npm install          # or yarn
3. Disable package-lock.json

A much more radical solution would be to disable the generation of package-lock.json globally:

npm config set package-lock false

In order to disable the generation of the package-lock.json file for a single project you can add the following to the .npmrc file in your project's root folder:

package-lock=false

In the future, these files will be handled by the package managers, autodetecting and merging conflicts (see this issue for npm and this PR for yarn).

npx

If you want to run a package just once, without installing it globally on your machine or locally in your project, you can try npx. It is part of npm since version 5.2.0.

Let's say we want to try the git-changelog command. Therefore we can run:

npx git-changelog -t false -a "My nice application"

This can of course be integrated in the npm scripts section for tasks that don't run that often.

Release and Tagging

In order to keep track of version numbers, we use the npm version command. Each time we merge the develop branch into the master we run one of the following commands:

npm version patch
npm version minor
npm version major

Followed by a git push --tags.

This will bump the version number in the package.json and create a new git tag for the latest version number.
Using npm version is therefore a useful shorthand for creating a new release of your package and keeping track of your versions at the same time. The command should be used to follow the Semantic Versioning paradigm.

  • patch can be used as hotfix that doesn't imply breaking changes and doesn't introduce new features
  • minor can be used to tag versions introducing new features and minor non-breaking changes
  • major is used for versions that introduce breaking changes

❤️ npm

npm can be used as the Swiss knife of JavaScript developers. We really love its versatility! If you have any nice npm tips leave a comment below.