Opinionated NPM Style Guide for teams by De Voorhoede.
This guide provides a set of rules to better manage, test and build your NPM modules and project tasks runners. It should make them
- easier for a new developer to pick up
- reduce friction with different environment configurations
- have a predictable api
- easier to add new tasks
- Use nvm to manage node versions
- Configure your npm personal info
- Use
save exact
option - Avoid installing modules globally
- Write atomic tasks
- Use npm modules for system tasks
- Document your script API
With nvm you can have multiple different versions available and switch to the one that suits better your project.
To install or update nvm, you can use the install script using cURL:
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.0/install.sh | bash
For Windows check nvm for windows.
If everything goes well, you can now install a specific node version.
nvm install stable
nvm install vX.Y.Z
nvm alias default stable
It’s also easy when updating a newer version, copying your existing global modules.
nvm copy-packages <previous-version>
When creating a new package npm init
your defaults will be already included on the scaffolding.
npm config set init-author-name "{name}"
npm config set init-author-email "{email}"
Check npm config docs, for more info.
You can use cat ~/.npmrc
to check your current definitions.
By default, installing a package with the --save
or --save-dev
option, npm saves the package version with ^
prefix, meaning that will update minor versions if available. While this is a good idea as is, this makes it possible for different developers having different versions of the same package and making it harder to debug if there is inconsistency. Defining the save-exact
option prevents this. More info npm config docs.
npm config set save-exact
NPM first tries globally installed modules before looking for local ones. Globally installed modules are shared between projects and might not match the required version for the project.
- Locally installed modules are custom and specific for the project.
- Locally installed modules are directly accessible via npm scripts.
# recommended: install locally
npm install --save-dev grunt-cli grunt
and use in package.json
:
"scripts": {
"icons": "grunt grunticons"
}
# avoid: don't install modules globally
npm install -g grunt-cli grunt
More about npm scripts.
Each task should be only responsible for one action.
- Atomic tasks are easy to read and understand.
- Atomic tasks are easy to reuse.
Separate each step of the task to an individual task. For example a "generate icon" task can be split into atomic tasks like "clean directory", "optimize SVGs", "generate PNGs" and "generate data-uris for SVGs".
When you use system specific commands like rm -rf
or &&
, you are locking your tasks to your current operating system. If you want to make your scripts work everywhere think about Windows developers also.
Use npm modules with node that mimic the same tasks but are system agnostic. Some examples:
- create directory (
mkdir
/mkdir -p
) ->mkdirp
- remove files and directories (
rm ...
) ->rimraf
- copy files (
cp ...
) ->ncp
- run multiple tasks in sequence (
... && ...
) or in parallel (... & ...
) ->npm-run-all
- set environment variable (
ENV_VAR = ...
) ->cross-env
-
Documentation provides developers with a high level overview to the script, without the need to go through all its code. This makes a module more accessible and easier to use.
-
Documentation formalises the API.
Document your script API in the project's README.md or CONTRIBUTING.md as those are the first places contributors will look. Describe what each task using a simple table:
`npm run ...` | Description
---|---
task | What it does as a plain human readable description.
An example:
npm run ... |
Description |
---|---|
build |
Compile, bundle and minify all CSS and JS files.. |
build:css |
Compile, autoprefix and minify all CSS files to dist/index.css . |
build:js |
Compile, bundle and minify all JS files to dist/index.js . |
start |
Starts a server on http://localhost:3000 . |
test |
Run all unit and end-to-end tests. |