Tech blog post #03

Why? In the long-living project, I was working on, the portion of frontend javascript code was dependent on a mix of bower packages and node modules that were concatenated into a bundle using grunt. We decided to migrate away from Bower as it was an unneeded dependency. It introduced a potential security hole (which turned out to be true, see tweet below) and added complexity to the overall build process.

Since the usage was entirely custom and aimed at direct files from bower packages, I decided not to use any automated tool as I was not confident in whether I would break the app. Low test coverage of subject features didn’t help.

Here are a few gotchas that made transition difficult but allowed me to proceed with higher confidence once realised.

Overall process

I was moving packages from bower.json to package.json one by one. On each package, I searched if it was used and verified if the versions available on npm matched. Then I diffed the resulting bundle from the initial bundle to see if things were missing/changed.

As we were targeting the relative file path, it seemed like the same version of the same package would have the same folder structure. It turned out that sometimes the library was available in /build directory in the bower, while in the node module, the path was /lib or something different. This, coupled with the fact that the grunt/concat and grunt/copy was not throwing an error if the file in the path was missing, provided me with some doubt.

To sum up

Make sure to check where the dist file is located.

A package might not have the same version

Since bower and npm are separate registries, the packages they have may not reflect one to one. I wasn’t sure that the different packages didn’t introduce breaking changes, and I didn’t want to risk it – I was migrating away from bower, not updating dependencies. The solution I came up with was simple but introduced a small issue.

I copied the required files and saved them into the repository, then referenced them in grunt tasks. This allowed me to keep on using the same version of the package. However, this introduces a few issues:

  • the repository is getting bigger,
  • the package is not reflected in package.json, risking it’s forgotten during refactoring.

I still believe that the tradeoff is still worth it.

As a side note – be sure only to copy files you’ll need and leave out the source, tests, and unnecessary dependencies. I would still recommend keeping package.json so that the future developer that looks at the files knows what it is.

To sum up

Copy only what you need and reference it properly.

You might not need it

It turned out that about 3/4 dependencies did not reference in any place in the project, so it was safe to delete. Just looking at the build tasks in grunt, I saw if it’s safe to delete a dependency.

To sum up

If possible – delete unneeded dependencies.

Conclusion

Migrating away from bower can be easy and fast if you’re careful. Keep in mind the gotchas, and you should be fine. Verify the bundle after moving/removing each dependency to ensure that you’re not silently breaking anything.

Author: Józef Piecyk