I've written a library to mimic Chrome's request/response API for my Firefox add-on. Obviously I need to use this code in both my background process (main.js) and my content script. Surely there must be a better way than stringifying the imported module.
-
For development purposes I've symlink'd the file from `lib/` to `data/`. – dvogel Jul 09 '12 at 20:20
-
I'm not sure why you'd need this chrome implementation instead of just using the modules the SDK comes with? What are you trying to achieve? Feel free to expand your question with example code as well. – therealjeffg Jul 10 '12 at 00:03
-
1@canuckistani: I guess that the point is code reuse between Chrome and Firefox extension versions. – Wladimir Palant Jul 10 '12 at 10:03
-
@canuckistani the Jetpack add-on SDK does not offer the same style of API as chrome.extension.sendRequest. My library builds on top of the port API to allow JSON messages and providing a real request-response model where the response message is only handled by the callback provided for that invocation of the sendRequest method. e.g. `sendRequest(/* JSON message */, function(response){ /* some code */ }); sendRequest(/* the same JSON */, function(response){ /* different code */ });` – dvogel Jul 10 '12 at 15:27
1 Answers
There is a semi-documented way of getting the URLs of the SDK code modules. This involves low-level modules which aren't guaranteed to stay stable. In fact, it is very likely that this part of the SDK will change and this solution won't work any more (like the solution originally presented here).
That said, the SDK allows you to access the loader
module. So first you need to construct a loader with the same options as the one used by the SDK. Then you need to use the resolveURI
utility function to resolve the module name using the mapping of this loader:
var {Loader, resolveURI} = require('toolkit/loader');
var options = require('@loader/options');
var loader = Loader(options);
var fooURI = resolveURI("./foo", loader.mapping);
The code above generates the URL for the module foo
. Note that you need to use the module foo
somewhere, otherwise it won't be included in your extension. If you don't use it yet then a dummy function will be sufficient:
function dummy()
{
require("foo");
}
Using the resulting URL as content script works just fine:
var pageMod = require("page-mod");
pageMod.PageMod({
include: "*.google.com",
contentScriptWhen: 'end',
contentScriptFile: [fooURI, ...]
});

- 56,865
- 12
- 98
- 126
-
Thanks! Your response gave me some insight into how the SDK works. Any idea whether an endorsed, supported solution is in the works? – dvogel Jul 10 '12 at 14:46
-
@dvogel: Given that I don't see any bug on it - I doubt that. Feel free to [file that bug](https://bugzilla.mozilla.org/enter_bug.cgi?product=Add-on%20SDK). Might still get declined however given the SDK's approach of strict separation between privileged and non-privileged code. – Wladimir Palant Jul 10 '12 at 15:10
-
The above answer no longer seems to work with Firefox 31 and SDK 1.17. Is there another solution? – CyclingBloke Aug 20 '14 at 22:40
-
@CyclingBloke: Sure, the undocumented `@packaging` module went away when the loading mechanism of the SDK has been rewritten. Now there is a semi-documented solution, I've updated my answer accordingly. – Wladimir Palant Aug 21 '14 at 21:32