Added linting, changed to esm loading

This commit is contained in:
Warky 2024-11-28 12:54:49 +02:00
parent 78e54af042
commit 44ff9878dd
5 changed files with 184 additions and 5 deletions

152
README.md
View File

@ -1,2 +1,152 @@
# monorepo-dep-checker # monorepo-dep-checker
A CLI tool to check and manage dependencies across packages in a monorepo
A powerful CLI tool for managing and checking dependencies across packages in a monorepo. Helps you identify version mismatches, missing dependencies, and maintain consistency across your workspace packages.
## Features
- 🔍 Check for version differences across packages
- ⚠️ Identify missing dependencies between your main app and packages
- 🔄 Update dependencies to the highest compatible version
- 🏗️ Full workspace package support
- 📊 Clear, actionable summaries
- 🚀 Fast, zero-config setup
## Installation
```bash
# Global installation
npm install -g @warkypublic/monorepo-dep-checker
# Or locally in your project
npm install --save-dev @warkypublic/monorepo-dep-checker
```
## Quick Start
Basic usage with default paths (assumes `./package.json` for main app and `./packages` for workspace packages):
```bash
dep-check
```
## Usage Examples
### 1. Check Version Differences
Find packages using different versions of the same dependency:
```bash
dep-check --check-versions
# Output example:
react:
Difference (major):
^17.0.2 vs ^18.0.0
Packages using ^17.0.2:
- my-app (package.json)
- components (packages/components/package.json)
Packages using ^18.0.0:
- new-feature (packages/new-feature/package.json)
Recommended action:
⚠️ Major version difference - Manual review recommended
```
### 2. Check Missing Dependencies
Find dependencies that exist in packages but are missing from the main app:
```bash
dep-check --check-missing
# Output example:
Summary:
Packages with dependency mismatches: 2
Unique dependencies missing from main app: 1
lodash
Unique unused dependencies from main app: 1
axios
```
### 3. Update Dependencies
Update all dependencies to their highest compatible version:
```bash
# Dry run - show what would be updated
dep-check --update --dry-run
# Actually perform the updates
dep-check --update
```
### 4. Custom Paths
Specify custom paths for your main app and packages:
```bash
dep-check --app ../my-app/package.json --packages ../my-app/packages
```
### 5. JSON Output
Get results in JSON format for further processing:
```bash
dep-check --check-versions --format json
```
## Command Line Options
```bash
Options:
--app, -a Path to main app package.json [default: "./package.json"]
--packages, -p Path to packages directory [default: "./packages"]
--update, -u Update dependencies to highest compatible version
--dry-run, -d Show what would be updated without making changes
--check-versions Check for version differences between packages
--check-missing Check for dependencies missing between app and packages
--format Output format (text or json) [default: "text"]
--help Show help
--version Show version number
```
## Features
### Workspace Support
- Automatically detects and handles workspace dependencies
- Ignores `workspace:*` protocol dependencies
- Properly manages workspace package references
- Supports npm, yarn, and pnpm workspaces
### Version Analysis
- Identifies major, minor, and patch version differences
- Provides clear upgrade recommendations
- Shows detailed package locations
- Helps prevent dependency conflicts
### Missing Dependency Detection
- Finds dependencies used in packages but missing from main app
- Identifies unused main app dependencies
- Shows unique missing dependencies to avoid duplication
- Excludes workspace packages from analysis
## Best Practices
1. Run `--check-versions` before updates to identify potential breaking changes
2. Use `--dry-run` before applying updates
3. Review major version differences manually
4. Keep workspace dependencies consistent across packages
## Contributing
Contributions are welcome! Please read our contributing guidelines for details.
## License
MIT License - see LICENSE file for details

View File

@ -1 +1,12 @@
import('../dist/index.js').then(module => module.default()).catch(console.error); #!/usr/bin/env node
import { createRequire } from 'module';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const require = createRequire(import.meta.url);
const { default: run } = await import(join(__dirname, '../dist/index.js'));
run().catch(console.error);

9
eslint.config.js Normal file
View File

@ -0,0 +1,9 @@
import globals from "globals";
import pluginJs from "@eslint/js";
/** @type {import('eslint').Linter.Config[]} */
export default [
{languageOptions: { globals: globals.browser }},
pluginJs.configs.recommended,
];

View File

@ -42,7 +42,9 @@
"yargs": "^17.7.2" "yargs": "^17.7.2"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.55.0", "@eslint/js": "^9.15.0",
"eslint": "^8.57.1",
"globals": "^15.12.0",
"vite": "^5.0.0", "vite": "^5.0.0",
"vitest": "^1.0.0" "vitest": "^1.0.0"
}, },

View File

@ -1,6 +1,5 @@
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { fileURLToPath } from 'url';
import chalk from 'chalk'; import chalk from 'chalk';
import semver from 'semver'; import semver from 'semver';
import yargs from 'yargs'; import yargs from 'yargs';
@ -132,6 +131,7 @@ class DependencyChecker {
if (missing.length > 0 || extraDeps.length > 0) { if (missing.length > 0 || extraDeps.length > 0) {
missingDeps.set(packageName, { missingDeps.set(packageName, {
// eslint-disable-next-line no-undef
path: path.relative(process.cwd(), filePath), path: path.relative(process.cwd(), filePath),
missing, missing,
extraDeps, extraDeps,
@ -277,6 +277,7 @@ class DependencyChecker {
}); });
return { return {
package: pkg, package: pkg,
// eslint-disable-next-line no-undef
path: path.relative(process.cwd(), filePath), path: path.relative(process.cwd(), filePath),
}; };
}), }),
@ -410,6 +411,7 @@ class DependencyChecker {
}); });
return { return {
package: pkg, package: pkg,
// eslint-disable-next-line no-undef
path: path.relative(process.cwd(), filePath), path: path.relative(process.cwd(), filePath),
}; };
}), }),
@ -571,6 +573,7 @@ class DependencyChecker {
// CLI implementation // CLI implementation
const run = async () => { const run = async () => {
// eslint-disable-next-line no-undef
const argv = yargs(hideBin(process.argv)) const argv = yargs(hideBin(process.argv))
.usage('Usage: $0 [options]') .usage('Usage: $0 [options]')
.option('app', { .option('app', {
@ -621,17 +624,21 @@ const run = async () => {
.example('$0 --check-missing', 'Show missing dependencies') .example('$0 --check-missing', 'Show missing dependencies')
.example('$0 --update --dry-run', 'Show what would be updated').argv; .example('$0 --update --dry-run', 'Show what would be updated').argv;
// eslint-disable-next-line no-undef
const appPackageJson = path.resolve(process.cwd(), argv.app); const appPackageJson = path.resolve(process.cwd(), argv.app);
// eslint-disable-next-line no-undef
const packagesDir = path.resolve(process.cwd(), argv.packages); const packagesDir = path.resolve(process.cwd(), argv.packages);
// Validate paths // Validate paths
if (!fs.existsSync(appPackageJson)) { if (!fs.existsSync(appPackageJson)) {
console.error(chalk.red(`Error: Main package.json not found at ${appPackageJson}`)); console.error(chalk.red(`Error: Main package.json not found at ${appPackageJson}`));
// eslint-disable-next-line no-undef
process.exit(1); process.exit(1);
} }
if (!fs.existsSync(packagesDir)) { if (!fs.existsSync(packagesDir)) {
console.error(chalk.red(`Error: Packages directory not found at ${packagesDir}`)); console.error(chalk.red(`Error: Packages directory not found at ${packagesDir}`));
// eslint-disable-next-line no-undef
process.exit(1); process.exit(1);
} }
@ -648,7 +655,7 @@ const run = async () => {
// Export both the class and run function // Export both the class and run function
export { DependencyChecker, run as default }; export { DependencyChecker, run as default };
// eslint-disable-next-line no-undef
if (process.argv[1] === import.meta.url.slice(7)) { if (process.argv[1] === import.meta.url.slice(7)) {
console.log('Running');
run(); run();
} }