Package.json Usage Tips and Tricks
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.
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.
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:
- 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. - 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