A major goal in software development is to keep your code DRY (Don’t Repeat Yourself). Ideally, when you require a piece of functionality in multiple places, you’ll want to write out a block of code once and reuse it wherever possible. This helps to maintain consistency and cleanliness in the codebase and helps to make future changes or improvements easier.
When project requirements change, or new features are added, having code that is as modular and reusable as possible makes this process faster, more efficient, and more resilient to bugs.
When developing browser extensions using JavaScript, one way to accomplish this is to build a function in your project that accomplishes a common task and export it to other parts of the project. But what if you want to reuse code from another project?
For a fast-growing company like Wildfire that often has several partner cashback program projects in development at once, it's common to run into situations across multiple projects that require the same solution. However, code in one project is not available to code in another. One solution would be to copy and paste code from one codebase to another.
But this approach has a major flaw. When you need to update that code, you now need to do that in two places. This creates unnecessary repetition and works against the goal of DRY. And over time, as more changes are made, the code across the two projects becomes more and more out of sync.
There is a better way to accomplish this that avoids having to repeat the same logic in multiple places: code packages. A package is a bundle of code that is hosted in an online registry that can be downloaded into a project in development. The package is then accessible to the project, and gives the developer the same benefits as we had before when we created our reusable function within a single project.
The difference between functions within the project and the code in the package is that the package’s code is available to any project we choose simply by updating the packaged code's imported version.
Creating a shared package that contains common functionality is a major challenge. When developing a white-label browser extension package for Wildfire’s cashback and rewards platform, we needed to find ways to implement solutions that worked for any existing project, while also keeping in mind potential future projects.
But the benefits of creating the package were extremely valuable, not just to the development team, but also to product managers and our support team.
Having a code package that offers core features wherever needed has streamlined the process for building out the repetitious portions of our new applications, and has allowed us to make updates to our partners’ white-label cashback browser extensions faster and easier.
For example, a common requirement for Wildfire’s extensions is to be able to identify when the user is browsing a merchant website that is eligible for cashback rewards. We have developed an algorithm that optimizes this process and creates minimal performance impact on the user’s browser. Incorporating this functionality into a shared package allows all of our extensions to use this algorithm.
Furthermore, when we needed to update the algorithm to address a bug, all our cashback browser extensions that leverage the package were able to inherit that bugfix quickly by adopting the latest version of the package. If we encounter an issue with the update, we can simply pin the version on the extension experiencing problems and open a card to investigate how our package testing missed the anomalous behavior.
Publishing a package to an online registry makes the process of bringing in shared code to a project simpler. But how do you make sure that internal code does not become available to those outside your organization? Wildfire uses organizationally-scoped packages in a private registry and requires security credentials to view or use the package. Anyone trying to access the package without the proper credentials will not be able to access the code.
While code reuse is straightforward in scenarios where the exact same behavior is required in multiple places, there are cases where one project will need slightly modified functionality. Flexibility is a key component of writing a good package. A flexible and customizable shared code package is much easier to incorporate than one that is too rigid.
Creating configuration options for various features in Wildfire’s cashback browser extension package was the biggest challenge in building a useful tool. Not having enough configurable settings or making code blocks difficult to override can make a developer feel hampered by a package rather than helped by it.
We have solved this problem by breaking down features into individual, modular chunks that can be pieced together, added to, or overwritten completely as needed.
A good package should serve as an aid to the developer and should not prevent an application from doing what it needs to. We have set up the package with robustness in mind. Error handling and automated testing is included in the package to prevent unexpected situations from causing problems with the applications that leverage it.
Software development is about solving problems, not just in the software itself, but in the development process as well. Identifying inefficiencies and coming up with practical and forward-thinking solutions to create a better process is all part of the work of a developer.
With the introduction of this code package, we were able to solve several problems at once: removal of duplication, making project development more efficient, and allowing for quicker software updates so that partners relying on Wildfire’s cashback rewards platform can go to market faster.
Are you a software engineer interested in solving challenging development problems like the one described above?