How do you use the 'files' and 'directories' properties in package.json?

Npmpackage.json

Npm Problem Overview


If a package.json has a files prop, and/or a directories prop:

  "files": [
    "./src/assets/fonts/"
  ],
  "directories": {
     "assets:": "./src/assets"
  }

What are some ways to make use of them? The documentation does not mention what can be done with them once they have been specified.

For example, the files docs say:

> The "files" field is an array of files to include in your project. If you name a folder in the array, then it will also include the files inside that folder.

What does "include in your project" mean? Include where? How are they accesible now that they weren't before?

In the directories section, the docs say:

> In the future, this information may be used in other creative ways.

What are the existing creative ways it is being used?

Npm Solutions


Solution 1 - Npm

"include in your project" means the files will be in the packaged tarball that is created when you run npm publish. You can also run npm pack to generate the tarball for inspection without actually triggering a publish. This way you can actually open the generated tarball and inspect which files were/were not included.

While .npmignore (or .gitignore as a proxy, if no .npmignore) functions as a black list of files to ignore (thereby including everything else by default), the files array is a whitelist. That is, instead of including everything by default, if files array is specified everything is excluded by default and only those files explicitly listed will be included in the packaged tarball.

As an example, say your package is a library meant for consumption in the browser. Your code is in lib/, and you run browserify to compile into a browser-compatible lib at dist/index.js. You start out with a bunch of files listed in .gitignore, which is used as the defacto .npmignore which doesn't exist. But now that dist/ is full of generated files, you want them ignored from the git repo. If you add them to .gitignore, they will be excluded from the git repo, but they will also be ignored from the package tarball. So you have two options: duplicate your .gitignore as .npmignore but only list dist/ in .gitignore. If you do this, you will have to keep two files almost-but-not-quite in sync. This way is tedius and error-prone.

The other alternative is to not have a .npmignore, and instead just list the files you actually want in the package, in the files array. README.*, package.json, CHANGELOG.* (maybe a couple others) are automatically included in the tarball regardless. So you simply add "files": [ "dist" ] and you're done. Now your package tarball won't include original source JS from lib, nor tests/ etc but will instead only contain the actual compiled lib in dist/.

As for directories, I typically list the lib (for es5), src (for es6, coffeescript, typescript etc sources), dist (for browser or vm-specific builds), test, output (for temporary generated files like coverage reports, etc), doc, etc. Though this property isn't used directly by npm or other tools, it makes the directory structure explicit. Also, it makes the directories referenceable in npm scripts like so:

"scripts": {
  "clean": "rm -rf $npm_package_directories_dist $npm_package_directories_output",
  "lint": "eslint $npm_package_directories_src",
  "test": "teenytest $npm_package_directories_test",
}

In this way, the directories are specified only once, and if they change, they only need changed in a single location (rather than many throughout the package.json).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBazView Question on Stackoverflow
Solution 1 - NpmjasonkarnsView Answer on Stackoverflow