Approaches to Deprecating Code in JavaScript

0
57

Recently, I had to dig into the topic of code deprecation in JavaScript. I feel like this topic gets less coverage even though it may a play key role in certain projects, especially when working in bigger teams or dealing with external APIs.

In JavaScript-land, I don’t know of any true industry standards for deprecating JavaScript. It could be different per any team, library or vendor.

That’s why my goal here is to sum up my findings and thoughts on this topic, alongside some good practices when it’s time to mark a JavaScript method obsolete a codebase.

What does “deprecation” actually mean?

First, let’s start by clarifying that the deprecation is just a status applied to a software feature. It indicates that this feature should be avoided, typically because it has been superseded.

Deprecation may also indicate that the feature will be removed in the future. Features are deprecated—rather than immediately removed—in order to provide backward compatibility, and give programmers who have used the feature time to bring their code into compliance with the new standard.

Additionally, a deprecated feature suggests that there won’t be any further development from this point onward. It shouldn’t work any different than it did in a previous version (unless documentation explicitly states something else). So, generally, it should be the same as it was when the deprecation action happened.

It may or may not work in the latest version—no guarantees!

However, since there aren’t any true industry standards that are strictly followed inJavaScript-land, this could be slightly different per team, library or vendor.

When to deprecate code and when to delete it?

It’s important to note that a deprecated software feature or method is still a part of the software! Consider the “deprecated” label as just a status of the code. Whether the software feature will actually be removed in the future depends on what that particular software team decides.

In my opinion, large teams or projects relying on external APIs or libraries ought to deprecate first, then remove later (after a reasonable time, however you define that). At the very least, give at least one major version bump before actually removing the deprecated code so users have a chance to adjust to the change.

You might want to look at Semantic Versioning, a simple set of rules and requirements that dictate how version numbers are assigned and incremented. Given a version number MAJOR.MINOR.PATCH, increment the MAJOR version when you make incompatible API changes, MINOR version when you add functionality in a backwards-compatible manner, and PATCH version when you make backwards-compatible bug fixes.

If your software is rapidly changing and evolving and you are deprecating a feature, try to communicate with your project manager if this feature is expected to be resurrected later. If you choose to deprecate, instead of delete, it might be a lot easier for you to revert should you need to.

For smaller teams or projects with internal methods and APIs, go ahead and remove first rather than deprecate. Sometimes it just doesn’t make sense to waste time and deprecation only increases the complexity just for the sake of following best practices.

How to mark a method obsolete

Here are five good practices I have found the most useful:

  1. Add a @deprecated JSDoc flag.
  2. Mention the version that the method was deprecated.
  3. Figure out a timeframe for when this method will be deleted, including which version it will take place. Otherwise, based on my experience, it stays forever 🙂
  4. Use comments liberally to explain the implementation for the benefit of other developers or your future self. This is extremely useful if your use-case is writing a library that others use as a dependency for their work.
  5. Add a console warning message that indicates that the function is deprecated.

Here’s a more practical example where I use all five practices:

/**
* A magic method that multiples digits.
*
* @deprecated [#1] since version 2.3 [#2].
* [#3] Will be deleted in version 3.0.

* [#4] In case you need similar behavior, implement it on you own,
* preferably in vanilla JavaScript
* or use the multiplyTheSameNumber method instead,
* if the same number needs to be multiplied multiple times, like so:
* multiplyDigits([5, 5, 5]) === multiplyTheSameNumber(5, 3)
*
* @param {array} _digits – digits to multiply
*/
function multiplyDigits(_digits) {
console.warn(“Calling a depricated method!”); // [#5]

// ….
}

To avoid repetition in the console warnings or in case you plan to deprecate multiple methods and you have their replacements, it might be more convenient to use a helper:

/**
* Creating a deprecated / obsolete behavior for methods in a library.
* [Credits]{@link: https://stackoverflow.com/q/21726472/1333836}
*
* @param {function} replacementFunction
* @param {string} oldFnName
* @param {string} newFnName
* @return {function}
*/
const Oboslete = function(replacementFunction, oldFnName, newFnName) {
const wrapper = function() {
console.warn(“WARNING! Obsolete function called. Function ‘” + oldFnName + “‘ has been deprecated, please use the new ‘” + newFnName + “‘ function instead!”);

replacementFunction.apply(this, arguments);
}
wrapper.prototype = replacementFunction.prototype;

return wrapper;
}

Wrapping up

I’d suggest getting your team on the same page and inherit deprecation practices that make the most sense for your project or use case, whether it’s adopting the practices we’ve covered here or others.

Note that there are certain times when deletion makes more sense than deprecation. Sometimes, investing efforts to deprecate something simply aren’t worth it. Again, it’s totally up to you and what makes the most sense for your project.

Do you know other good practices when marking a method obsolete in JavaScript? Let me know in the comments!

Credits

The ideas I shared here were inspired by comments I found on Software Engineering Stack Exchange and on StackOverflow.