Blog

Migrating Away From Bower

Why? In the long living project, I was working at, 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, introduced potential security hole (which turned out to be true, see tweet below) and added complexity the overall build process.

Since the usage was quite custom since it aimed at direct files from bower packages I decided not to use any automated tool as I had not much confidence in whether I won’t break the app. Low test coverage of subject features didn’t help.

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

Overall process

I was moving packages from bower.json to package.json one by one. On each package, I was searching if it was used at all and verifying if the versions available on npm matched. Then I diffed resulting bundle with 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 will have the same folder structure. It turned out that sometimes the library was available in /build directory in bower, while in 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 not have a 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 introduces 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:

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

I still believe that the tradeoff is still worth it.

As a side note – be sure to only copy files that you’ll need and leave out the source, tests, and unnecessary dependencies. I would still recommend to keep 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 were not reference in any place in the project so it was safe to delete. Just looking and the build tasks in grunt I was able to see 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 be sure that you’re not silently breaking anything.