Hot reloading Extensions using Webpack
In a time of module bundlers, in general, front-end developers don’t have patience to being reloading a page after each change in the code:
“So, what’s the problem?”
Do you ever tried to develop a extension? I felt I was in the back days…
Here is the point, when you develop a Chrome extension, you go into the extension’s tab, load your unpacked extension (where is the manifest.json) and start working on it. Every time you change anything, you need to click on that reload button and then reload all the tabs which the plugin is running:
It’s painful, right? So I thought: should have something out there already done to deal with that. As I use Webpack to bundle my extensions, I just thought to search something similar to the Hot Reload Middleware, that is a very common tool in the development scenario when using Webpack and maybe have something for developing Chrome extensions right? Wrong!
So, what I found in my research? This was the best solution:
Ok, nothing against this plugin, it works pretty well for what it promises, but I thought that I was changing “six” for “half a dozen”.
Click in a button in the extension toolbar is less effort than go to the extensions tab to do it though, but for me was not good enough (you still have to manually reload all the tabs which the plugin is running). Also, add a “post build” script to browse that domain (http://reload.extensions) still not elegant, and don’t worth the effort to create a specific script just to do that.
Still, I didn’t found anything similar to a proper “hot reloading” so I’ve decided to act:
So, first I’ve analysed why we can’t use the common “hot reloading” from webpack and I figured out:
- Webpack Hot Reloading serves the files (can be used in ExpressJS)
For extensions, Chrome is the one who serves the files, so no deal :(
- It creates a communication tunnel between a injected bundle middleware and the Webpack using a WebSocket server.
Hey… I can do the same!
So, I’ve created a Webpack plugin, webpack-chrome-extension-reloader, just to solve this problem, using WebSockets and the Webpack API. It’s simple to use, as any common Webpack plugin.
“So, how it works internally?”
Is a simple approach, first the plugin injects a listener script, that acts in both background and content-scripts bundles, then it creates a WebSocket to communicate any changes to the background script, and from background to content-scripts, reloading the tabs and the extension itself when webpack finishes a build.
It’s not in the “state of the art” and there’s a lot of room to improvements, but the project is totally open to pull requests!