Skip to content

refactor: replace lodash.merge with lodash.mergewith#4603

Merged
escapedcat merged 3 commits intoconventional-changelog:masterfrom
hyperz111:lodash.merge
Jan 25, 2026
Merged

refactor: replace lodash.merge with lodash.mergewith#4603
escapedcat merged 3 commits intoconventional-changelog:masterfrom
hyperz111:lodash.merge

Conversation

@hyperz111
Copy link
Contributor

@hyperz111 hyperz111 commented Jan 24, 2026

User description

Description

Replace lodash.merge with lodash.mergewith. (maybe) extracted from #4596.

Motivation and Context

We have 2 merging libraries in our dependency tree. So i refactor it to ONLY use 1 merging library.

Usage examples

How Has This Been Tested?

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

PR Type

Enhancement


Description

  • Replace lodash.merge with lodash.mergewith across codebase

  • Consolidate to single merging library dependency

  • Update package.json dependencies and type definitions

  • Update import statements in three packages


Diagram Walkthrough

flowchart LR
  A["lodash.merge"] -->|"replaced by"| B["lodash.mergewith"]
  C["@commitlint/cli"] -->|"updated"| B
  D["@commitlint/load"] -->|"updated"| B
  E["@commitlint/config-patternplate"] -->|"updated"| B
Loading

File Walkthrough

Relevant files
Dependencies
cli.test.ts
Update merge import and usage in tests                                     

@commitlint/cli/src/cli.test.ts

  • Replace lodash.merge import with lodash.mergewith
  • Update merge function call to use mergeWith
+2/-2     
load.ts
Update merge import and usage in loader                                   

@commitlint/load/src/load.ts

  • Replace lodash.merge import with lodash.mergewith
  • Update merge function call to use mergeWith
+2/-2     
index.js
Update merge import and usage in config                                   

@commitlint/config-patternplate/index.js

  • Replace lodash.merge import with lodash.mergewith
  • Update merge function call to use mergeWith
+2/-2     
package.json
Update dependencies and type definitions                                 

@commitlint/cli/package.json

  • Replace lodash.merge with lodash.mergewith dependency
  • Update @types/lodash.merge to @types/lodash.mergewith
+2/-2     
package.json
Update dependencies and type definitions                                 

@commitlint/config-patternplate/package.json

  • Replace lodash.merge with lodash.mergewith dependency
  • Update @types/lodash.merge to @types/lodash.mergewith
+2/-2     
package.json
Update dependencies and type definitions                                 

@commitlint/load/package.json

  • Replace lodash.merge with lodash.mergewith dependency
  • Update @types/lodash.merge to @types/lodash.mergewith
+2/-2     

@qodo-code-review
Copy link

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@codesandbox-ci
Copy link

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

@qodo-code-review
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Add customizer to avoid merging undefined

Add a customizer function to mergeWith to prevent merging undefined values,
preserving the behavior of the original lodash.merge function.

@commitlint/cli/src/cli.test.ts [682-687]

 async function writePkg(payload: unknown, options: TestOptions) {
 	const pkgPath = path.join(options.cwd, "package.json");
 	const pkg = JSON.parse(await fs.readFile(pkgPath, "utf-8"));
-	const result = mergeWith(pkg, payload);
+	const result = mergeWith(pkg, payload, (objValue, srcValue) => {
+		if (srcValue === undefined) {
+			return objValue;
+		}
+	});
 	await fs.writeFile(pkgPath, JSON.stringify(result, null, "  "));
 }
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: This suggestion correctly identifies a subtle but critical behavioral difference between lodash.merge and lodash.mergewith regarding undefined values, which could introduce bugs. Applying this change ensures the behavior remains consistent with the original code before the PR.

Medium
Use empty object as merge target

Add an empty object as the first argument to mergeWith to prevent mutation of
the configAngular object and ensure a correct merge.

@commitlint/config-patternplate/index.js [19]

-export default mergeWith(configAngular, {
+export default mergeWith({}, configAngular, {
  • Apply / Chat
Suggestion importance[1-10]: 5

__

Why: The suggestion correctly points out that not providing an empty object as the first argument to mergeWith will mutate the configAngular object, which is an imported module. This is a valid and important improvement to prevent side effects.

Low
Add empty object for deep merge

Add an empty object as the first argument to mergeWith to serve as the merge
target, preventing mutation of the source configuration objects.

@commitlint/load/src/load.ts [51-59]

 config = mergeWith(
+    {},
     {
         extends: [],
         plugins: [],
         rules: {},
         ...
     },
     config
 );

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 5

__

Why: This suggestion correctly recommends adding an empty object as the first argument to mergeWith to prevent mutating the default configuration object. This is good practice to avoid unintended side effects.

Low
High-level
Consider using a single lodash dependency

Instead of replacing one lodash micro-package (lodash.merge) with another
(lodash.mergewith), consider using the full lodash package. This would provide a
more scalable solution for using lodash utilities while maintaining a single
dependency.

Examples:

@commitlint/load/package.json [54]
    "lodash.mergewith": "^4.6.2"
@commitlint/load/src/load.ts [19]
import mergeWith from "lodash.mergewith";

Solution Walkthrough:

Before:

// package.json
"dependencies": {
  "lodash.mergewith": "^4.6.2"
}

// @commitlint/load/src/load.ts
import mergeWith from "lodash.mergewith";
// ...
config = mergeWith(
  { /* ... */ },
  config,
  seed
);

After:

// package.json
"dependencies": {
  "lodash": "^4.17.0" // or latest version
}

// @commitlint/load/src/load.ts
import { mergeWith } from "lodash";
// ...
config = mergeWith(
  { /* ... */ },
  config,
  seed
);
Suggestion importance[1-10]: 7

__

Why: The suggestion offers a more robust and scalable dependency management strategy by advocating for the full lodash package instead of swapping one micro-package for another, which better fulfills the PR's goal of consolidation.

Medium
  • More

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors commitlint packages to use lodash.mergewith instead of lodash.merge, aiming to consolidate merge utilities and remove the direct lodash.merge dependency from updated workspaces.

Changes:

  • Replaced lodash.merge imports/usages with lodash.mergewith (mergeWith) in load logic, config export, and CLI tests.
  • Updated package dependencies and type definitions from lodash.merge / @types/lodash.merge to lodash.mergewith / @types/lodash.mergewith.
  • Updated yarn.lock to drop @types/lodash.merge entries.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
yarn.lock Removes @types/lodash.merge and keeps @types/lodash.mergewith to reflect dependency changes.
@commitlint/load/src/load.ts Switches config merge helper from merge to mergeWith.
@commitlint/load/package.json Replaces lodash.merge + types with lodash.mergewith + types.
@commitlint/config-patternplate/package.json Replaces lodash.merge + types with lodash.mergewith + types.
@commitlint/config-patternplate/index.js Switches config merge helper from merge to mergeWith.
@commitlint/cli/src/cli.test.ts Switches test helper merge from merge to mergeWith.
@commitlint/cli/package.json Replaces dev dependency lodash.merge + types with lodash.mergewith + types.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@escapedcat
Copy link
Member

Thanks!

@escapedcat escapedcat merged commit 1828d6e into conventional-changelog:master Jan 25, 2026
18 checks passed
@hyperz111
Copy link
Contributor Author

@escapedcat, maybe you can replace lodash.isfunction? :)

@escapedcat
Copy link
Member

#4604

This was referenced Feb 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

3 participants