How ShopBack Build and Package a Browser Extension

Allen Fang
ShopBack Tech Blog
4 min readJul 17, 2018

--

ShopBack leverages on WebExtensions to build a cross-browser extension in one source code. In addition, we also use React.js to implement the extension UI. In this sharing, we are going to introduce how we build and package a eCommerce browser extension for Google Chrome and Mozilla Firefox.

Build & Package Extension

In ShopBack browser extension team, we use webpack@2 for bundling the source code and use gulp@4 to establish the build/package flow.

In the following, we divide above flow into five main topics:

  • Obfuscate and uglify code
  • Manage Webpack chunks with WebExtension
  • Manage extension assets
  • Attach source code
  • Work on locales(Special case)

1. Obfuscate and uglify code

ShopBack’s browser extension is for customer to easily get cashback rewards when they are shopping. It’s kind of a eCommerce extension, sometimes we have to protect our source code to avoid to be inspected too easier by our competitors.

uglifyjs-webpack-plugin satisfies for most of cases. However in ShopBack, we also use uglifyOptions.mangle.properties to do more advanced uglified for some functions or variables name:

However, the value of constant variable which can not be uglified. So there’s one more gulp task for dealing with this by gulp-replace to replace some sensitive value, then in the bundling stage, we use NormalModuleReplacementPlugin to replace the modules dynamically.

For example:

If we have a constant.js which have some sensitive content, this gulp task will generate a constant.obfuscated.js in the same folder then webpack will select this new source file via NormalModuleReplacementPlugin .

For developers, we just write code as usual but config which content should be obfuscated when building extension.

2. Manage Webpack chunks with WebExtensions

In our practices, the background, popup and option scripts have their one chunk only. For the content scripts, we have several content scripts so it’s straightforward to divide them into different chunks.

About webpack production bundling, we usually output the final chunk name with a SHA hash to avoid the caching. In this situation, we have to patch the manifest.json to meet the final chunk name.

So firstly, we need to collect every chunk file names after webpack bundling:

Then we patch the manifest.json with correct chunk file name via another gulp task:

So final result may look like:

3. Manage extension assets

An extension usually includes some of assets, like html, css, image etc. Basically, you can put those static assets in your extension folder then config in the web_accessible_resources.

In ShopBack extension, we treat these static assets as kind of module so that we can use these images though resolved by webpack.

So there’s only manifest.json and few extension icon in our extension base folder. Following is how we handle the static assets

  • Resolve HTML via html-webpack-plugin
  • Resolve image in Javascript via url-loader
  • Resolve image in SCSS resolve by resolve-url-loader

The benefit is we don’t config web_accessible_resources every time when there’s new asset is added. Everything resolved by webpack.

4. Attach Source Code

It is important thing if you have to publish your extension to Google Chrome. Actually, most of browser extension policy tell you NOT minify you source code. But if you did, you had better to upload your source code when publish or not they can taken down your extension.

Mozilla Firefox did much good on this part because they have a field to ask you to upload your source code in the 7 day in publish page.

Google Chrome doesn’t ask you to upload when publish.

If you really don’t want to attach the source code into the package, you probably can give Google reviewer a private download link when you are publishing.

5. Work on locales

This is special case in ShopBack, because Chrome extension allow you to specify a region to publish. So in our build process, we will build several chrome extension packages per country. You can easy to implement a distributed task via gulp.series or gulp.parallel.

For different countries, just few different parts as below:

  1. The homepage_url in manifest.json
  2. The default_locale in manifest.json
  3. What kind of locales need to be supported

So in our special Chrome build process, we will patch the manifest.json according to corresponding information. All of these gulp tasks are generated dynamically. So if ShopBack have a new marketplace to launch, we just setup above config, that’s it!! It’s not necessary to write other gulp task.

If you are interesting on how to generate a gulp.series tasks dynamically, you can refer our previous post.

Conclusion

In this article, we share a build flow that we done in the past six months. There’s sill have few things we can improve, we will share it in near future. Any feedback is welcome and in the next posts, we will share some experiences after we publish our extension.

--

--