Browserify to use npm modules in an addon

Hi,

I’m the dev of a Firefox addon and I use Browserify to be able to require() Node modules such as crypto. However, my addon is refused:

This extension uses quite a few polyfills and modules used by but not
primary to the extension. This usually happens during the browserify
process, but makes it very hard to review the add-on. For modules that
have a native browser equivalent please consider adding a shim to avoid
the full polyfill to be included (most commonly the buffer module).

What can I do to solve this issue?

1 Like

Basically, you’re using software which is not part of Firefox but which it is not practical to review for safety and security. The simplest way to avoid this rejection is not to use third party modules. Failing that, only use them when there is absolutely no alternative way to do what the module does.

You can argue until you’re blue in the face that Mozilla should either review the code that makes up an addon or get out of the way, but in practical terms they can barely keep up with the addons themselves without also having to review every library that someone has posted to github.

With luck, a reviewer will post up some more specific guidelines for addons that use third-party JS like Node modules. The rejection message gives a hint to just extract a small piece of the library if that is all your addon needs.

Let me expand on that a little bit, as I made the suggestion. I’m not saying that you need to avoid all polyfills that browserify adds, I just think it would be good to reduce them as possible.

For example, the Buffer polyfill is about 40kb large. If you can avoid using Buffer, this would save a lot of review time. Sometimes you can use native features of the browser. For example atob and btoa are functions native to the browser, using them would be one line. In node, doing base64 encoding requires the Buffer module. So to reduce lines, you could just use the native version instead. There are a few ways to do this:

  1. Find a module that takes care of this.
    The btoa-lite module does this for the example I posted above, there may be others around. It does so by using a trick in package.json:

    “main”: “btoa-node.js”,
    “browser”: “btoa-browser.js”,

browserify will load btoa-browser.js instead which is only a few lines.

  1. Use your own polyfill and trick browserify’s static analysis.
    If there is no such module, then you can write your own. You can either do it like the btoa module above, or inline using the trick here. The basic pattern is require(false || "module"); which will make browserify not load the polyfill. You’ll have to provide your own alternative though.

If none of this is at all possible for your add-on, then you can still resubmit. Regardless of if you use the polyfills or not, it is very helpful to upload the files you’ve written, before they have been browserified. To do this you should zip up the files, provide instructions on how to turn the source into the complied version (e.g. “run browserify file1.js file2.js”), then use the source upload feature on addons.mozilla.org.

This will allow us to view each file separately, and skip those files provided by third party libraries that have already been reviewed in another project.

Hope this explains the situation.

1 Like

@emersion I had similar problem – Browserify included Buffer shim which took ~40KB.

I was able to replace it with native sdk/io/buffer provided by Firefox and the bundle size is now ~8KB. (see this github ticket for more details and sources)

In short, you can override module names in package.json. Example for buffer:

+"jetpack": {
+    "overrides": {
+        "buffer": "sdk/io/buffer"
+    }
+  },

Then run browserify with --no-builtins parameter and see if the bundle still works or if there are other modules missing.