Skip to content

refactor: replace some lodash methods#4596

Closed
hyperz111 wants to merge 10 commits intoconventional-changelog:masterfrom
hyperz111:replace-lodash
Closed

refactor: replace some lodash methods#4596
hyperz111 wants to merge 10 commits intoconventional-changelog:masterfrom
hyperz111:replace-lodash

Conversation

@hyperz111
Copy link
Contributor

@hyperz111 hyperz111 commented Jan 20, 2026

Description

Replace some lodash.* packages with some better alternatives. Except mergeWith.

Motivation and Context

I think if some lodash methods is should be replaced with some alternative and native ways.

Usage examples

Nothing.

How Has This Been Tested?

I run test in each changed package.

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.

@qodo-code-review
Copy link

qodo-code-review bot commented Jan 20, 2026

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: 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

Generic: Robust Error Handling and Edge Case Management

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

Status:
Behavior edge cases: Replacing lodash case-conversion utilities with kasi may change edge-case behavior (e.g.,
non-ASCII, punctuation/whitespace handling, or empty input) without any visible added
tests validating equivalence.

Referred Code
import {
	toCamelCase,
	toKebabCase,
	toSnakeCase,
	toPascalCase,
	toTitleCase,
} from "kasi";

export default function toCase(input: string, target: TargetCaseType): string {
	switch (target) {
		case "camel-case":
			return toCamelCase(input);
		case "kebab-case":
			return toKebabCase(input);
		case "snake-case":
			return toSnakeCase(input);
		case "pascal-case":
			return toPascalCase(input);
		case "start-case":
			return toTitleCase(input);
		case "upper-case":


 ... (clipped 6 lines)

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

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

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jan 20, 2026

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

qodo-code-review bot commented Jan 20, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix incorrect array deduplication logic

Fix the plugin deduplication logic. The current use of [...new
Set(extended.plugins)] is buggy for plugins with configurations; instead,
deduplicate plugins based on their name.

@commitlint/load/src/load.ts [86-92]

 	if (Array.isArray(extended.plugins)) {
-		const uniq = [...new Set(extended.plugins)];
-		for (const plugin of uniq) {
+		const seen = new Set<string>();
+		const uniquePlugins = extended.plugins.filter((plugin) => {
+			const name = typeof plugin === 'string' ? plugin : plugin[0];
+			if (seen.has(name)) {
+				return false;
+			}
+			seen.add(name);
+			return true;
+		});
+
+		for (const plugin of uniquePlugins) {
 			if (typeof plugin === "string") {
 				plugins = await loadPlugin(
 					plugins,
 					plugin,
 ...

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a bug in the PR's implementation where new Set() fails to deduplicate plugins defined as arrays (e.g., ['my-plugin', {config}]). The proposed solution provides a robust fix, ensuring plugins are uniquely identified by name, which improves the correctness of the code.

Medium
Add guard for empty or nullish input

Add a guard for null or undefined input in the sentence-case implementation. The
current code will throw an error for such inputs, whereas the previous lodash
version handled them gracefully.

@commitlint/ensure/src/to-case.ts [25-27]

 		case "sentence-case":
 		case "sentencecase":
+			if (!input) {
+				return "";
+			}
 			return input.charAt(0).toUpperCase() + input.slice(1);
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly points out that replacing lodash.upperFirst with native string methods introduces a regression where null or undefined input would cause a runtime error. Adding the proposed guard restores the previous robust behavior and prevents potential crashes.

Medium
General
Simplify function check
Suggestion Impact:The conditional was simplified exactly as suggested by removing the redundant `message &&` check before the `typeof message === "function"` test.

code diff:

 			const title =
-				message && typeof message === "function"
+				typeof message === "function"
 					? await message(answers)
 					: typeof message === "string"

Simplify the conditional by removing the redundant message && check, as typeof
message === "function" is sufficient.

@commitlint/cz-commitlint/src/Process.test.ts [22]

-message && typeof message === "function"
+typeof message === "function"

[Suggestion processed]

Suggestion importance[1-10]: 3

__

Why: The suggestion correctly identifies a redundant check. While removing it is a minor code simplification with no functional impact, it improves code conciseness.

Low
  • Update

@escapedcat
Copy link
Member

Some tests seem to fail in CI. Can you have a look?
I use this to test locally btw: yarn clean && yarn install && yarn build && yarn test && yarn lint

@hyperz111
Copy link
Contributor Author

Some tests seem to fail in CI. Can you have a look?
I use this to test locally btw: yarn clean && yarn install && yarn build && yarn test && yarn lint

I think this is because toCamelCase method in kasi package.

@hyperz111
Copy link
Contributor Author

I think this is because toCamelCase method in kasi package.

I use camelcase@8 for now until the bug is fixed.

@escapedcat
Copy link
Member

Some test still failing :P

@hyperz111
Copy link
Contributor Author

If fabiospampinato/kasi#1 is merged, maybe the test don't fail again.

@escapedcat
Copy link
Member

Hm, alright. Not sure if these dep changes are worth the hassle currently ;)

@hyperz111
Copy link
Contributor Author

@escapedcat, can you run it again? :)

@hyperz111
Copy link
Contributor Author

Ok, the CLI test is fail. Let me check it again.

@hyperz111
Copy link
Contributor Author

hyperz111 commented Jan 22, 2026

Maybe the problem is array handling difference between @fastify/deepmerge and lodash.merge.

@hyperz111
Copy link
Contributor Author

hyperz111 commented Jan 22, 2026

I don't know why the test is still failling, but when i try to execute the CLI like in failed tests scenario, i get the expected output.

$ echo $PWD
/data/data/com.termux/files/home/gitclone/commitlint/@commitlint/cli/fixtures/comment-char
$ echo "header: foo\n$body\n" | node ../../cli.js
⧗   input: header: foo
✖   body may not be empty [body-empty]

✖   found 1 problems, 0 warnings
ⓘ   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

@escapedcat
Copy link
Member

Hm, this is a refactor that is, as much as this could benefit from smaller deps(?), not worth skipping tests.

@hyperz111
Copy link
Contributor Author

hyperz111 commented Jan 22, 2026

Hm, this is a refactor that is, as much as this could benefit from smaller deps(?), not worth skipping tests.

We have so many lodash per-method packages in our dependencies tree. So using the smaller alternative is better for faster installation. I don't want to use lodash (or lodash-es) package like in #3901 because it's so huge (+1MB).

@hyperz111
Copy link
Contributor Author

hyperz111 commented Jan 22, 2026

Maybe i should send one PR for one module replacing. Wdyt @escapedcat? If yes, i will close this and try send another PR.

@escapedcat
Copy link
Member

Yeah, let's try that

@hyperz111 hyperz111 closed this Jan 22, 2026
@escapedcat
Copy link
Member

Thanks btw, this reminded me that I wanted to get rid of chalk in 2023. Gave it another try: #4599

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.

2 participants