Skip to content

Drop lodash dependency#412

Open
ikeyan wants to merge 1 commit intosemantic-release:masterfrom
ikeyan:drop-lodash
Open

Drop lodash dependency#412
ikeyan wants to merge 1 commit intosemantic-release:masterfrom
ikeyan:drop-lodash

Conversation

@ikeyan
Copy link
Copy Markdown

@ikeyan ikeyan commented Feb 16, 2026

This PR drops dependency to lodash and replaces existing code to their equivalent counterparts.


const errors = Object.entries(options).reduce(
(errors, [option, value]) =>
!isNil(value) && !VALIDATORS[option](value)
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

isNil: https://github.com/lodash/lodash/blob/4.17.23/lodash.js#L12080
Note: We cannot use value != null since linter xo complains: Use === to compare with null. no-eq-null


let verified;

const defaultTo = (value, defaultValue) => (Number.isNaN(value) ? null : value) ?? defaultValue;
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

defaultTo: https://github.com/lodash/lodash/blob/4.17.23/lodash.js#L15529
value !== value was replaced with more readable Number.isNaN(value)

// If the Changelog prepare plugin is used and has `changelogFile` configured, validate them now in order to prevent any release if the configuration is wrong
if (options.prepare) {
const preparePlugin =
castArray(options.prepare).find((config) => config.path && config.path === '@semantic-release/changelog') || {};
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

const resolveConfig = require('./resolve-config.js');
const {isStringObject} = require('util/types');

const isString = (value) => typeof value === 'string' || isStringObject(value);
Copy link
Copy Markdown
Author

@ikeyan ikeyan Feb 16, 2026

Choose a reason for hiding this comment

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

isString: https://github.com/lodash/lodash/blob/4.17.23/lodash.js#L12242
I've used typeof for primitives and util.types.isStringObject for boxed strings. Lodash’s manual tag-checking is somewhat outdated because it can be spoofed. Using util.types is the modern way to guarantee the value actually possesses the internal [[StringData]] slot, providing a more accurate type check without the Lodash dependency.

Copy link
Copy Markdown
Author

@ikeyan ikeyan Feb 16, 2026

Choose a reason for hiding this comment

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

I dug deeper into the Lodash source code and realized my previous point about spoofing was slightly off. Lodash actually uses a clever getRawTag mechanism to handle Symbol.toStringTag. While Lodash's isString is robust, its internal implementation (getRawTag) is quite heavy. It temporarily mutates Symbol.toStringTag on the object to retrieve the raw tag.

Using util.types.isStringObject is a much cleaner and more performant alternative in Node.js. It directly checks the internal [[StringData]] slot at the engine level without any side effects or the overhead of manual property manipulation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant