@merger203/expert-invention
Check package dependencies for duplicates, peer dependencies satisfaction and more early
Install
npm install --save-dev @merger203/expert-invention
What is it for ?
Based on my experience, I often saw issues with duplicate dependencies like two versions of babel, or two versions a react library that cannot share a context, peer dependencies not respected. I wrote specific script inside each repository for a long time, but they tend to be hard to maintain, hard to read, and not generic enough.
I you have any idea, or found bug, please open an issue.
Try it with cli
Use npx to try and check package.json
in current directory:
npx @merger203/expert-invention
Uses Cases
- Check devDependencies are exact versions
- Check resolutions versions matches versions in devDependencies or dependencies
- Check direct peer dependencies are respected, and list exceptions
- Check some dependencies in your package.json respect another dependency dependencies
- Lock versions depending on certain conditions
- Be more confident when automerging renovate's PR
If something is missing for your need, please open an issue !
How to use
Create a script, for example scripts/check-package.js
. Add it in "scripts"
in your package.json. Run in CI and/or in your husky hooks.
import { createCheckPackage } from '@merger203/expert-invention';
await createCheckPackage(/* '.' */)
// Check that your package.json contains only exact versions of package, not range.
.checkExactVersions({
// When isLibrary is true, it doesnt check "dependencies" as they should mostly have a range, not an exact version
isLibrary: false,
})
.checkDirectPeerDependencies({
// Allow to only warn for not respected peer dependencies.
// Example: { '@babel/cli': ['@babel/core'] }
// Only warns for missing "@babel/core" peer dependency asked in "@babel/cli".
// You can also use "*" for any library
// { '*': ['semver'] }
missingOnlyWarnsFor: {},
invalidOnlyWarnsFor: {},
})
// Check that there are no duplicates among your dependencies and your devDependencies.
// For example, If you use "@babel/core": "7.0.0" and one of your direct dependency requires "^7.0.1" (in dependencies, not peerDependency)
// you will have two versions of @babel/core. This check will display an error that can be changed to a warning.
// You will probably need to add warnings for common library where duplicate have low impact,
// like type-fest or fast-deep-equal.
.checkDirectDuplicateDependencies({
onlyWarnsFor: { '*': 'type-fest' },
})
// Check resolutions versions matches versions in devDependencies or dependencies
.checkResolutionsVersionsMatch()
// Check that all your resolutions are also present in an "resolutionsExplained" field, forcing you to explain why the resolution was necessary
.checkResolutionsHasExplanation()
// Same as calling .checkExactVersions(), checkDirectPeerDependencies(), checkDirectDuplicateDependencies()
// and checkResolutionsHasExplanation(). It's recommended to use it as new recommended features will be added here too.
.checkRecommended({
isLibrary: false,
peerDependenciesOnlyWarnsFor: [],
directDuplicateDependenciesOnlyWarnsFor: ['type-fest'],
})
// Check that your package.json contains the same version of @babel/core than react-scripts, both in resolutions and devDependencies
.checkIdenticalVersionsThanDependency('react-scripts', {
resolutions: ['@babel/core'],
devDependencies: ['@babel/core'],
})
// Check that your package.json dependencies specifically satisfies the range set in another dependencies
.checkSatisfiesVersionsFromDependency('@pob/eslint-config-typescript', {
devDependencies: [
'@typescript-eslint/eslint-plugin',
'@typescript-eslint/parser',
],
})
// Check that your package.json dependencies have the exact same version that another dependency also present in your package.json
// The react-dom version should match react, so this check will ensure it does
.checkIdenticalVersions({
dependencies: {
react: {
dependencies: ['react-dom'],
devDependencies: ['react-test-renderer'],
},
},
})
.run();
'use script';
const { createCheckPackage } = require('@merger203/expert-invention');
await createCheckPackage(/* '.' */)
// Call .checkExactVersions(), checkDirectPeerDependencies(), checkDirectDuplicateDependencies()
// checkResolutionsVersionsMatch() and checkResolutionsHasExplanation()
.checkRecommended({})
.run();
If you use workspaces:
'use script';
const {
createCheckPackageWithWorkspaces,
} = require('@merger203/expert-invention');
await createCheckPackageWithWorkspaces()
// Call .checkExactVersions(), checkDirectPeerDependencies(), checkDirectDuplicateDependencies()
// checkResolutionsVersionsMatch() and checkResolutionsHasExplanation() for root package and workspaces packages, but also
// checks your workspaces packages doesn't have different versions than the ones in devDependencies of root packages.
.checkRecommended({
isLibrary: (pkgName) => !pkgName.endsWith('-example'),
peerDependenciesOnlyWarnsFor: [],
directDuplicateDependenciesOnlyWarnsFor: ['semver', 'github-username'],
})
.forRoot((rootPackageCheck) => {
/* rootPackageCheck has the same API presented for single package */
})
.for('packageName', (pkgCheck) => {
/* pkgCheck has the same API presented for single package */
})
.run();