Packaging files for npm with .npmignore

Let's say you have a bunch of typescript files that you want to compile to javascript before creating a package and publishing it to npm. No big deal, you set the output folder of your typescript config to a certain folder (like dist) and there is your result. Set the files field in your package.json-file to [dist] as well, and that is the folder that will be packaged. But imagine you are also writing tests in typescript, and running the compiled versions. This would mean the javascript versions of the test files will also end up in your dist folder, but you don't want to unnecessarily publish test files.

Using .gitignore

If you list any files or folders in your .gitignore file, they will also be excluded from your npm package. Test files is something that you definitely want to check in with git though, so putting them in .gitignore is not an option.

Using package.json

The files field in your package.json takes an array of patterns that will tell npm what to include in your package. While it might be possible to come up with a clever combination of patterns that will include all your desired files and nothing more, now and in the future, it is much too complicated in my opinion, especially since there is an easier way.

Using .npmignore

You can place a separate file in your root folder, called .npmignore, that will tell npm exactly what files to ignore for packaging purposes. This will make npm disregard .gitignore though, so be aware of that. Using the scenario with typescript test files, this is what a .npmignore file could look like:

# Ignore every file in the repo
/*

# Then unignore the dist folder
!/dist

# Then re-ignore the compiled test files
*.test.js
*.test.js.map
*.test.d.ts

# Ignore typescript build info
tsconfig.tsbuildinfo

This provides a readable and understandable way to specify exactly what should be included in your npm package.

Final tips

Use the command npm publish --dry-run while trying this out. You will get a list of the exact content of your package-to-be which is very useful when trying out configurations like this.

Once configured, Yarn will work the same way as npm with the .npmignore file.