Package.json Usage Tips and Tricks

· 3 min read

For the package.json file, you shouldn’t just know about dependencies/devDependencies. Using package.json effectively can make our applications more robust and development more efficient.

Enforcing Yarn Instead of npm for Package Installation

There are always people who don’t carefully observe the project and use npm for package installation. The best approach isn’t documentation, but automatic detection.

  1. Add script package.json

    
      "scripts": {
        "preinstall": "node ./scripts/checkYarn.js"
    	}
    
    • npm will execute this script before the package installation command starts.
    • preinstall, prepublish are some built-in hooks, though in actual development we’ll enrich and extend our own like start, build, etc.
  2. checkYarn.js

    
    if (!/yarn\.js$/.test(process.env.npm_execpath || '')) {
    console.warn(
    '\u001b[33mThis repository requires Yarn 1.x for scripts to work 	properly.\u001b[39m\n'
    )
    process.exit(1)
    }
    

    When using npm install, it will directly report an error.

Restricting Node and Yarn Versions

Inconsistent development environment versions can be problematic. For example, before yarn 1.0, some packages didn’t have hash fingerprints. If everyone’s yarn packages were inconsistent, once packages were installed, this file would keep changing. So ensuring development environment consistency is extremely important.

package.json

  "engines": {
    "node": ">=10.16.0",
    "yarn": ">=1.16.0"
  }

Note: Version numbers can also be closed intervals like “10.15.0-10.16.0”.

License

If the repository is set to private:true, the license field doesn’t need to be set - npm will ignore this setting. If not private, it needs to be set to any license, like MIT, otherwise you’ll get an error during packaging:

No license field

Note: Sometimes the missing license prompt doesn’t necessarily refer to the package.json file in the project root path, but could be in system user directories, etc. The specific file can be determined based on the error message.

Nested Dependency Package Versions

Sometimes you want to modify nested dependency package versions. The solution is to add a resolutions field. Configuration example below, using the trim package as an example:

 "resolutions": {
    "trim": "1.0.1"
  }

If using package-lock.json for version dependency management, you also need to configure a hook. If using yarn.lock, the above configuration is sufficient.

"scripts": {
  "preinstall": "npx npm-force-resolutions"
}

Version Numbers as Branches/Commit IDs/Package Aliases

Sometimes the JS module you want to install isn’t published as a package. One approach is to use GitHub repo commit/branch as version management. npm supports this.

Example: I want to install code from the ecdsa branch of osstech-jp/forge.

$ npm i osstech-jp/forge#ecdsa

Overall, version numbers can be in the following situations:

"dependencies": {
  "package1": "git://github.com/username/package.git#commit",
  "package2": "git://github.com/username/package.git#branch",
  "package3": "npm:package4@1.5.3",
  "package4": "1.5.3",
}

Notes

  • The address can be github.com or private repository servers

  • Services like GitHub verify private keys during cloning - they’re not directly open. Configuring URLs like this requires the machine installing packages to have the private key to ensure it can clone the code properly

  • Package aliases are mainly used when you don’t want to change the package name imported in the program, but want the actual package program to point to another package/address

Use the above methods as needed.

Custom Field Support

npm package.json supports custom fields. If used in JS, you can require and use them directly.

For example, the following custom field:

 "chainConfig": {
    "sdkVersion": "v2.1.0",
    "subscribeMinSdkVersion": "v2.0.0"
  }

A few things to note:

  1. Field names should use a top-level custom field, then nest to define N fields. Avoid prefixes like _ and $, as these are occupied by the package registration mechanism.
  2. Top-level field names should avoid conflicts with package mechanism reserved words, like name, scripts, _id, etc.

version

In JS files, you can use the npm_package_version environment variable to access this field value

process.env.npm_package_version