Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 335
Baz Avatar asked Nov 24 '16 23:11

Baz


People also ask

What is files property in package json?

You can think of the files property in package. json as an allowlist of all files that should be included in a npm release and . npmignore as a denylist of all files that should not be included.

What is the use of the package json file?

The package. json file is the heart of any Node project. It records important metadata about a project which is required before publishing to NPM, and also defines functional attributes of a project that npm uses to install dependencies, run scripts, and identify the entry point to our package.


1 Answers

"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).

like image 73
jasonkarns Avatar answered Nov 25 '22 14:11

jasonkarns