Building my first web extension

Jérôme Pott - Oct 25 '20 - - Dev Community

Since I've learned that web extensions speak the same languages as websites (HTML, CSS and JavaScript), I've always wanted to give it a try. This post is less a tutorial and more a summary of my experience.

Getting started

Getting started is indeed very easy:
https://css-tricks.com/how-to-build-a-chrome-extension/

I was able to quickly get something working, however, I also quickly faced some limitations that required me to set up a build pipeline in order to:

  • use npm modules
  • work with promises (browser APIs use callbacks)
  • have my extension automatically work both in Chrome and Firefox
  • have hot module replacement (HMR)
  • use Vue components and TailwindCSS
  • in short: have my dev environment as close a possible to my usual environment.

Fortunately, I found this awesome plugin that takes care of all the above-mentioned points.
This plugin scaffolds a web extension project structure and includes the essential webextension-polyfill.
All I had left to do with to set up TailwindCSS and I was ready to code.

Debugging web extensions

I didn't find how to use the Vue devtools extension for debugging, but in my case, logging to the console was sufficient.

To see the console logs when debugging the popup:

  • Chrome: Open dev tools, right-click inside the popup and select "inspect"
  • Firefox: Click the inspect button on the screen where you added your extension as a temporary extensions [image]

For the settings page, you can set options_page directly to options.html, which will open it as a full page.

You can also open the popup as a normal web page by typing its URL: chrome-extension://your_extension_id/popup.html

What about testing?

Thanks to the simplicity of Cypress, I've started to add tests to my projects. However, Cypress currently cannot visit web extension.

Then I found a great blog post about testing web extensions with Jest and Puppeteer. The showcased extension is even built with Vue.

Thanks to that post, I was able to quickly set up Jest. However, I quickly realized that the History API I was using was not mocked by the jest-webextension-mock library🙄

What I ended up doing is to only unit test the main functions with Jest. As fixtures for the tests, I exported a sample browsing history as JSON.

The post later mentioned E2E testing with Puppeteer. I tried to set it up but ran into errors from the Jest integration. At that point, I told myself that I shouldn't spend more time on that topic and move on to finally publishing my extension.

Publishing my extension

Chrome Web Store

The developer dashboard seemed to have recently been redesign. I found it very easy to navigate. There are many contextual info-bubbles that provide useful information. The whole process was very straightforward. I just had to fill out all the required information and pay the entrance fee of $5 to submit my extension for review. Two days later, it was published.

Link to Chrome store page: https://chrome.google.com/webstore/detail/track-it/kjdclicjmhibgokfflkhfccdillnkfbk

Add-ons for Firefox

At Firefox, the submission process was also easy and the review also only took two days. Unlike Chrome, I had to upload the source code. I am actually surprised that Chrome didn't ask for it. Maybe paying the fee with a credit card number provided enough insurance.

Link to Firefox store page: https://addons.mozilla.org/en-US/firefox/addon/track-it/

Now go build your own extension!

Don't fret too much about the fact that there are probably extensions that will be similar/better than yours. With that kind of thinking, you'll never get started. If this doesn't help, take it as a learning exercise.

See my extension: it tracks the time since the last visit to websites... There are plenty of apps that do a similar job and boast more features. But it solved a specific need I had and I use it daily.

You check its source code here:
https://github.com/mornir/track-it

Cover photo by Aron Visuals

. . . . . . . . . . . . . . . . . . . . . . . . . . .