RSS

npm publish

Tips on contributing packages to npm registry by npm publish, how to reduce package size, how to use scoped package, how to debug package locally etc.

Reduce package size

Use files field in package.json to specific installed files

The optional files field is an array of file patterns that describes the entries to be included when your package is installed as a dependency.

File patterns follow a similar syntax to .gitignore, but reversed: including a file, directory, or glob pattern (, **/, and such) will make it so that file is included in the tarball when it’s packed.

Omitting the field will make it default to ["*"], which means it will include all files.

Use .npmignore

You can also provide a .npmignore file in the root of your package or in subdirectories, which will keep files from being included.

Example of .npmignore:

**/__tests__/**
/testing/**
/docs/
/coverage/
/.nyc-output/
.*
*.png
*.tgz
*.log
*.txt

At the root of your package it will not override the “files” field, but in subdirectories it will. The .npmignore file works just like a .gitignore.

If there is a .gitignore file, and .npmignore is missing, .gitignore’s contents will be used instead.

Files included with the “package.json#files” field cannot be excluded through .npmignore or .gitignore.

Always included files

Certain files are always included, regardless of settings:

  • package.json
  • README
  • CHANGES / CHANGELOG / HISTORY
  • LICENSE / LICENCE
  • NOTICE
  • The file in the “main” field

npm pack - Check packaged files before release

Use npm pack to check what files will be included in release package.

For example:

$ npm pack
npm notice
npm notice 📦  [email protected]
npm notice === Tarball Contents ===
npm notice 35B   index.js
npm notice 808B  package.json
npm notice 3.0kB README.md
npm notice 1.1kB LICENSE.txt
npm notice === Tarball Details ===
npm notice name:          example-foo
npm notice version:       1.0.5
npm notice filename:      example-foo-1.0.5.tgz
npm notice package size:  2.3 kB
npm notice unpacked size: 4.9 kB
npm notice shasum:        310fbfbf632b37578d78bf9de17ca6d42b212091
npm notice integrity:     sha512-2VxbWgzuRSYlm[...]I3L9Avma/c1ZQ==
npm notice total files:   4
npm notice
example-foo-1.0.5.tgz

Scoped package

Scoped package name starts with @, e.g. @types/superagent is a package with scope name (or organization name) types.

Scoped package help organize packages and avoid package name conflict.

Scopes and package visibility

  • Un-scoped packages are always public.
  • Private packages are always scoped.
  • Scoped packages are private by default; you must pass a command-line flag --access=publish when publishing to make them public.

E404 - Scope not found

After change package name to a scoped package name in package.json, run npm publish may report E404 error:

$ npm publish
npm ERR! code E404
npm ERR! 404 Not Found - PUT https://registry.npmjs.org/@foo%2fbar - Scope not found

To solve this issue, need create a organization as scope name at https://www.npmjs.com/org/create</a>.

E402 - must sign up for private packages

When publish scoped package, it may report following E402 error:

$ npm publish
npm ERR! publish Failed PUT 402
npm ERR! code E402
npm ERR! You must sign up for private packages : @foo/bar

This is because the scoped packages are private by default which requires paying NPM for a private account.

If your package is public, you can publish with --access public flag:

$ npm publish --access public

Debug package locally before publish

Install local package

To test a package, run npm install with the full path to your package directory

$ npm install path/to/local/package

Another way to debug local package is use npm link.

First run npm link in local package directory, it will create a symbol link in npm global installation.

Then in another package directory, use npm link packagename to link install packagename as a dependence.

For example:

$ cd ~/dev/foo    # go into the package directory
$ npm link        # creates global link to `foo`
$
$ cd ~/dev/bar    # go into some other package directory which use `foo`.
$ npm link foo    # link-install the package, you can treat as `npm install foo`

Now, any changes to ~/dev/foo will be reflected in ~/dev/bar/node_modules/foo/.

Happy debugging.

Semantic versioning

Semantic versioning helps other developers who depend on your code understand the extent of changes in a given version, and adjust their own code if necessary.

Semantic versioning in a nutshell, given a version number MAJOR.MINOR.PATCH, increment the:

  • MAJOR version when you make incompatible API changes,
  • MINOR version when you add functionality in a backwards compatible manner, and
  • PATCH version when you make backwards compatible bug fixes.

In package.json, use ^ or ~ to specific compatible version:

  • ^ for compatible with minor release upgrade. e.g. “^1.2.3” compatible with “1.5.8” but not “2.0.1” because “2.0.1” have a major version upgrade.
  • ~ for compatible with patch release upgrade. e.g. “~1.2.3” compatible with “1.2.5” but not “1.5.8” because “1.5.8” have a minor version upgrade.

It is recommended to use ^ or ~ to specific dependencies, for example:

"dependencies": {
  "foo": "~1.0.0",  // compatible with 1.0.x
  "bar": "^2.2.0"   // compatible with 2.x.x
},

Reference