Keeping a third party dependency of a big front end project can be a challenge. But it can be less challenging if you have a strategy for it. Strategy can be in the form of the tools that we’re using or how often we do it for which type of update. There other posts can be found that touch on my such of having a strategy for this such as this one. But in this article I intend to propose some ideas to help us create a good habit and a regular schedule to upgrade our npm packages and front end assets.
Regular schedules for updating npm packages
The strategy I propose for keeping our NPM packages up to date is to install automated tools like Dependabot that checks for update quite frequently like everyday. So these automated tools will help us by checking for this everyday and created automated pull requests that we can check weekly. We can also have manual check for things like this but less frequently as we don’t want to spend too much time on this. So below I list the strategies I propose in terms of timing for this.
Daily:
Automated tools like Dependabot or Renovate or snyk should be set up to automatically open pull requests when new versions of dependencies become available. This does not mean you have to update daily; it simply means that you are made aware of updates as they are released.
Weekly:
- Every Monday morning, set aside time to review the open pull requests from your automated tool. This review should include reading the changelogs for each updated package and assessing the potential impact on your project.
- Run your test suite against each of these pull requests to ensure that nothing breaks. If all tests pass, you can consider merging the pull request. If they do not, you will need to investigate further and potentially hold off on the update until you can resolve the issue. We can even setup a specific branch to merge all the weekly update and run the tests once on that branch to conserve resources (By not running test per pull request).
Bi-weekly:
- Every other Friday, spend some time researching your project’s dependencies. This could include reading documentation, checking out the project’s GitHub repository, and generally making sure that you’re up-to-date with the state of your dependencies. There are many tools that can help with that.
- Additionally, you should review your project’s direct dependencies to see if any of them are no longer necessary or could be replaced with a better alternative.
Monthly:
- On the first day of each month, perform a thorough review of all dependencies. This should include both direct and indirect dependencies.
- Update any major versions of packages if required and supported by their changelog, ensuring to thoroughly test these updates before they’re merged into your main codebase. We can update the major versions only once per month because they are the one that might contain breaking changes and more possible work.
- This is also a good time to update your lockfile (package-lock.json or yarn.lock) to ensure that your indirect dependencies are up-to-date.
Quarterly:
- Every three months, perform a comprehensive review of your update strategy. Is it working as intended? Are you able to keep your dependencies up-to-date without causing disruption to your development process?
- This is also a good time to review your test coverage and make any necessary improvements. The better your test coverage, the more confident you can be when updating your dependencies.
How to use Semantic Versioning (SemVer) to help us with our npm packages update strategy
Semantic Versioning, or SemVer, is a versioning system for software that aims to convey meaning about the underlying changes with each new release. It follows the pattern of X.Y.Z (Major.Minor.Patch), where:
- Major (X): This number changes when there are incompatible API changes.
- Minor (Y): This number changes when functionality is added in a backwards-compatible manner.
- Patch (Z): This number changes when backwards-compatible bug fixes are made.
Understanding and using SemVer can definitely assist with your npm package update strategy. Here’s how:
- Avoid breaking changes: By paying attention to the major version number, you can avoid updates that will introduce breaking changes into your project (unless you’re ready to handle those changes).
- Add new features safely: When the minor version number changes, it’s an indication that new features have been added in a way that won’t break existing functionality. This can be a safe update to make.
- Patch bugs without fear: Changes to the patch number indicate bug fixes that are backwards-compatible, so they should be safe to update.
- Control your update strategy: npm uses a special syntax in the package.json file to control which updates are allowed. For example, using a caret (^) before the version number (like “^1.0.0”) will allow npm to update to any minor or patch version above 1.0.0, but not to 2.0.0 or above.
- Test major updates carefully: If you do decide to update a package to a new major version, make sure to carefully test the changes. The major version increment indicates that there could be breaking changes.
- Stay informed about changes: Semantic versioning can help you stay informed about what kinds of changes are likely to have occurred between different versions of a package.
- Prerelease Versions: Prerelease versions, identified by a hyphen (e.g., 1.0.0-beta), are typically not as stable as regular releases and might be best avoided for production use.
Most packages follow semantic versioning, which indicates the type of changes in each new version (major, minor, or patch). As a rule of thumb, it’s generally safe to upgrade packages that only have minor or patch updates, as they should not include breaking changes. Major updates, however, may require more careful consideration and testing as they may introduce breaking changes.
Don’t Update NPM packages Just to Update
While it’s good to keep your packages up to date, there’s no need to update every package as soon as a new version is released. If the current version of a package is working well in your project and there are no critical security fixes or required features in the new version, it may be best to leave it as is until there’s a compelling reason to update.
Remember, updating packages is about striking a balance between keeping your software secure and up-to-date while minimizing potential disruptions to your development process. The right approach can depend on the specifics of your project, the packages you’re using, and the resources available to you.
Deprecated NPM packages
Using deprecated NPM packages in your project can lead to potential security vulnerabilities and compatibility issues. Therefore, it’s important to replace deprecated packages as soon as possible. Here are some tips that can be useful for replacing our deprecated packages.
- Understand the Reason for Deprecation: Find out why the package was deprecated. This information is often provided in the npm warning message or on the package’s npm or GitHub page. The reason could be that the package is no longer maintained, it has security issues, or it has been replaced by a new package.
- Look for Alternatives: Once you know a package is deprecated and why, the next step is to look for alternatives. The maintainer usually suggests an alternative when they deprecate a package. If not, you may need to do some research to find the best alternative that suits your needs.
- Test the Replacement Package: Before fully switching to the new package, you should first test it to ensure it covers all the functionality you were using from the deprecated package. Also, check if it introduces any breaking changes into your project.
- Gradual Replacement: For large projects, where the deprecated package is used extensively, it might be beneficial to replace it gradually. This means you first introduce the new package and start using it in some parts of your project while still having the deprecated package. As you refactor or add new features, you can slowly remove the deprecated package.
- Update Your Documentation: Make sure to update your project documentation with the changes you’ve made, such as the new dependencies you’ve added and the ones you’ve removed.
- Ask for Help: If you’re having trouble finding an alternative to a deprecated package, don’t hesitate to ask for help. You can ask the community on forums like Stack Overflow, or directly contact the maintainers of the deprecated package.
Other various considerations that can effect our update strategy
- Automated Tools: Tools like Dependabot for GitHub, Renovate, or Snyk can automatically create pull requests in your repositories whenever new versions of your dependencies are released. These can be a huge timesaver and help ensure you’re not missing important updates. Additionally, these tools can be configured to follow specific schedules, such as daily, weekly, or monthly, based on your preference.
- Regularly Scheduled Reviews: Regardless of whether you use automated tools, it’s a good idea to schedule regular times to review and update your packages. This could be weekly, bi-weekly, or monthly, depending on the nature of your project and its dependencies. Having a regular schedule for updates can help ensure that your project doesn’t fall too far behind.
- Testing: Whenever you update a dependency, ensure you have a robust suite of tests that can be run to confirm that your software still works as expected. This is especially crucial for major version updates, which can include breaking changes.
- Use a Lockfile: Tools like npm’s package-lock.json or yarn’s yarn.lock file ensure that everyone working on the project is using the same exact versions of dependencies. This prevents issues where things work on one developer’s machine but not another’s.
- Understand What’s Changing: When possible, take the time to read the changelogs for the packages you’re updating. This can give you a better understanding of what’s changing, why it’s changing, and any potential impacts to your project.
- Update in Batches: Instead of updating one package at a time, it can be efficient to batch updates together. This can help to identify if a particular group of updates is causing issues.
Summary
Managing third-party dependencies in a large front-end project can be a complex task. It’s important to develop a strategy to streamline the upgrade process for npm packages and frontend assets. This approach may involve the use of tools and setting a regular update schedule. One effective method is to leverage automated tools such as Dependabot, which checks for updates daily and creates pull requests that can be reviewed on a weekly basis. Along with daily automation, weekly reviews of these requests, bi-weekly research on project dependencies, and monthly thorough reviews of all dependencies are recommended. Updating the lockfile, such as package-lock.json or yarn.lock, should also be done monthly, while a comprehensive update strategy review every quarter can help ensure the process is working as expected.
Understanding Semantic Versioning (SemVer) can aid in navigating npm package updates. It follows the X.Y.Z (Major.Minor.Patch) pattern, which communicates the nature of changes in each new release. Typically, updates to the minor and patch versions are safe, as they indicate backward-compatible feature additions and bug fixes. Major updates require careful testing due to potential breaking changes. It’s crucial to remember not to update just for the sake of updating; if the current version of a package is serving your project well, it may be best to delay updates until necessary. Balancing security and up-to-date software with minimizing disruptions to the development process is key. Various factors, such as automated tools, regular reviews, testing, the use of a lockfile, understanding change-logs, and batch updates, can all influence your npm package update strategy.