A comprehensive Node.js utility for managing dependencies in monorepo environments, specifically designed for Hyperse plugin ecosystems. This tool helps maintain consistent dependency management across multiple packages in a workspace.
- 🔍 Dependency Conflict Detection: Identify and resolve version conflicts in
node_modules - 📦 Peer Dependency Synchronization: Automatically sync peer dependencies across packages
- 🚨 Missing Package Detection: Check for undeclared imports in source files
- 🏗️ Monorepo Support: Built for managing multiple packages in a single workspace
- ⚡ TypeScript Support: Full TypeScript support with type definitions
- 🎯 Hyperse Ecosystem Optimized: Specifically designed for Hyperse plugin development
npm install @hyperse/dependency-sync
# or
yarn add @hyperse/dependency-sync
# or
pnpm add @hyperse/dependency-syncimport { syncDependencies, checkConflicts } from '@hyperse/dependency-sync';
// Sync dependencies across all packages in the workspace
await syncDependencies();
// Check for dependency conflicts
const conflicts = await checkConflicts('./node_modules', [
'@vendure/*',
'@nestjs/*',
]);import { syncDependencies } from '@hyperse/dependency-sync';
await syncDependencies(process.cwd(), {
// Exclude specific packages from processing
excludedPackages: (pkg) => pkg.packageJson.name === 'admin-ui',
// Disable missing package checks
checkMissing: false,
// Define peer dependencies and their versions
maxRangeCanbeSyncPeerDependencies: {
'@vendure/core': '^3.3.5',
'@nestjs/common': '^11.1.3',
graphql: '^16.11.0',
},
// Define dependency relationships
dependenciesReferPeepDependencies: {
'@nestjs/graphql': ['@nestjs/core'],
'@hyperse-hub/vendure-plugin-email': ['@vendure/common'],
},
// Packages to ignore during checks
ignoredCheckList: ['dotenv', 'fs-capacitor', 'sharp'],
});Synchronizes dependencies across all packages in the workspace.
workspaceRoot(string, optional): Root directory of the workspace. Defaults toprocess.cwd()options(SyncDependenciesOptions, optional): Configuration options
interface SyncDependenciesOptions {
excludedPackages?: (pkg: Package) => boolean;
checkMissing?: boolean;
maxRangeCanbeSyncPeerDependencies?: Record<string, string>;
dependenciesReferPeepDependencies?: Record<string, string[]>;
ignoredCheckList?: string[];
}excludedPackages: Function to filter out packages from processingcheckMissing: Whether to check for missing package declarations (default:true)maxRangeCanbeSyncPeerDependencies: Map of peer dependencies and their versionsdependenciesReferPeepDependencies: Map of dependencies that reference peer dependenciesignoredCheckList: List of packages to ignore when checking for missing declarations
Checks for conflicting package versions in node_modules.
nodeModulesPath(string): Path to thenode_modulesdirectorypkgPatterns(string[]): Array of package patterns to check (e.g.,['@vendure/*', '@nestjs/*'])ignorePackages(string[], optional): Packages to ignore when checking for conflicts
Returns a Map<string, string[]> where keys are package names and values are arrays of conflicting versions.
Checks if imported packages in source files are missing from package.json.
projectCwd(string): The project directoryignoredCheckList(string[]): List of packages to ignore
Extracts all imported modules from the project's source files.
projectCwd(string): The project directory
Returns a Set<string> of imported module names.
import { syncDependencies } from '@hyperse/dependency-sync';
// Sync all packages in the current workspace
await syncDependencies();import { syncDependencies } from '@hyperse/dependency-sync';
const peerDependencies = {
'@vendure/core': '^3.3.5',
'@vendure/common': '^3.3.5',
'@nestjs/common': '^11.1.3',
'@nestjs/core': '^11.1.3',
graphql: '^16.11.0',
typeorm: '^0.3.24',
};
const dependencyRelationships = {
'@nestjs/graphql': ['@nestjs/core'],
'@hyperse-hub/vendure-plugin-email': ['@vendure/common'],
'@hyperse-hub/vendure-testing': ['graphql'],
};
await syncDependencies(process.cwd(), {
maxRangeCanbeSyncPeerDependencies: peerDependencies,
dependenciesReferPeepDependencies: dependencyRelationships,
ignoredCheckList: ['dotenv', 'fs-capacitor', 'sharp', 'express'],
});import { checkConflicts } from '@hyperse/dependency-sync';
// Check for conflicts in Vendure and NestJS packages
const conflicts = await checkConflicts('./node_modules', [
'@vendure/*',
'@nestjs/*',
'@hyperse-hub/*',
]);
// Log conflicts
for (const [packageName, versions] of conflicts) {
console.log(`${packageName}: ${versions.join(', ')}`);
}import { syncDependencies } from '@hyperse/dependency-sync';
await syncDependencies(process.cwd(), {
excludedPackages: (pkg) => {
// Exclude admin-ui packages
return (
pkg.packageJson.name.includes('admin-ui') ||
pkg.packageJson.name.includes('dashboard')
);
},
checkMissing: true,
});{
"scripts": {
"sync-deps": "node -e \"import('@hyperse/dependency-sync').then(m => m.syncDependencies())\"",
"check-conflicts": "node -e \"import('@hyperse/dependency-sync').then(m => m.checkConflicts('./node_modules', ['@vendure/*', '@nestjs/*']).then(console.log))\"",
"prebuild": "yarn sync-deps"
}
}- Package Discovery: Scans the workspace for all packages using
@manypkg/get-packages - Import Analysis: Extracts all imported modules from source files
- Peer Dependency Resolution: Identifies which imports should be peer dependencies
- Dependency Reorganization: Moves peer dependencies to
peerDependenciesand regular dependencies todevDependencies - Package.json Updates: Updates all package.json files with the new dependency structure
- Pattern Matching: Searches for packages matching the provided patterns
- Version Collection: Collects all versions of each package found
- Conflict Identification: Identifies packages with multiple versions
- Filtering: Removes ignored packages from the results
const peerDependencies = {
// Core framework dependencies
'@vendure/core': '^3.3.5',
'@vendure/common': '^3.3.5',
// NestJS dependencies
'@nestjs/common': '^11.1.3',
'@nestjs/core': '^11.1.3',
// GraphQL dependencies
graphql: '^16.11.0',
'@apollo/server': '^4.12.2',
// Database dependencies
typeorm: '^0.3.24',
};const relationships = {
// NestJS modules that depend on core
'@nestjs/graphql': ['@nestjs/core'],
'@nestjs/apollo': ['@nestjs/core'],
// Hyperse plugins that depend on Vendure
'@hyperse-hub/vendure-plugin-email': ['@vendure/common'],
'@hyperse-hub/vendure-plugin-payment-core': ['@nestjs/graphql'],
};const ignoredPackages = [
// Build tools
'dotenv',
'sharp',
// File system utilities
'fs-capacitor',
// Express (handled by NestJS)
'express',
];- Missing Package Declarations: Ensure all imported packages are declared in
package.json - Version Conflicts: Use
checkConflictsto identify and resolve version conflicts - Peer Dependency Issues: Verify that peer dependencies are correctly configured
No declared package (packageName) in projectPath!: A package is imported but not declared inpackage.jsonreferPeerDependency packageName not found in maxRangeCanbeSyncPeerDependencies: A dependency relationship references an undefined peer dependency
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Run the test suite
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
For support and questions, please open an issue on the GitHub repository.