Do you know if you have any package that makes use of postinstall
scripts? Do you have a package installed twice? Since version 8.18.0 we can use npm query
to find packages in the node_modules
directory matching a specific query.
This is helpful in identifying possible issues and fixing them.
Why is a postinstall script important?
The postinstall
script allows a package to run code when it's installed and this could be used in a malicious way. The npm security team receives reports of malware in the registry and works to keep the ecosystem safe, but did you check which dependencies are running in postinstall
scripts? Do you trust them?
npm query ":attr(scripts, [postinstall])" | jq 'map(.name)'
Review the list of dependencies. then to uninstall these packages with a postinstall
script use the following command:
npm query ":attr(scripts, [postinstall])" | jq 'map(.name) | join("\n")' -r | xargs -I {} npm uninstall {}
💡 The jq
program is essential to filter data in JSON format.
Finding duplicate packages
Sometimes we find some errors on the DevTools' console when React or Angular is being loaded twice on our website. This happens when a dependency is incompatible with the semver of the same package declared on our package.json
. E.g. We declared react@^18.2.0
in our package.json
and some dependency has react@^16.8.0 || ^17.0.0
as dependency in their own package.json
.
We can find every installed copy of a specific package using:
npm query '#react'
Or, if we're looking for old versions of React
npm query '#react:semver(<18.0.0)'
🧠 Remember that the selectors for npm query
follow the CSS selectors format.
Check the dependency licenses
Perhaps you can't use code with a specific license in your app. You can check the variety of licenses installed in your node_modules
printing a dedupe list with this command:
npm query '*' | jq '.[] | select(.license | type == "string") | .license' -r | sort | uniq
🎁 Some packages, like rimraf
, declare an object in the license field of the package.json
, so you can use this example for these:
npm query '*' | jq '.[] | select(.license | type == "object") | .license'
# or using attr selector
npm query ':attr(license, [url])' | jq 'map(.license)'
Then you can look up packages with specific licenses, or without a license.
npm query '[license=MIT], [license=ISC], [license=]'
Other usages
You can create the query that matches your needs, but we can review a few additional scenarios.
Dependencies from Git
You can install dependencies from Git branches or tags instead of the npm registry and then you can check which of them are installed in your project.
npm query ':type(git)'
Who needs these packages? The npm why
command can tell us:
npm query ":type(git)" | jq 'map(.name) | join("\n")' -r | xargs -I {} npm why {}
The peerDependencies
If you run your app and you get an error for a missing dependency, check if a peer dependency of your direct dependencies is required. Maybe you should add it in your package.json
file.
npm query ':root > * > .peer' | jq 'map(.name)'
📚 You could have example pages for npm-query
and jq
in your terminal for quick usage thanks to the tldr-pages open source project.
Conclusion
Using npm query
in conjunction with jq
you can check some constraints in your dependencies to make sure you don't have duplicate dependencies, or licenses that are incompatible with your app or company's policy.
I hope this helps you to resolve your issues with npm packages. Tell me in the comments which queries you found useful.
Top comments (2)
Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 👍
Awesome! 🤩 Thanks for let me know!