I'm trying to write a cross-browser extension for Firefox and Chrome. Firefox uses the commonJS specification and Chrome just lumps everything into the global namespace like a webpage.
In order to be able to write reusable code, I'm trying to use requireJS to lood code in the Chrome extension, that way I can write commonJS modules and have them work in both environments.
I'm running into a problem when I need to conditionally require modules. For example, Firefox provides access to a simple-storage
module which you should use to access the local storage. In chrome, I need to use the localStorage API that they provide. So, I've been trying to do this:
// storage.js
define(function(require, exports, module){
var store;
try {
// This module will only be available in the FF extension.
store = require('simple-storage').storage
} catch(error) {
// If it's not available, we must be in Chrome and we
// should use the localStorage object.
store = localStorage
}
// Use the store object down here.
});
However this doesn't seem to work. When I try to load the Chrome extension I get the following error:
Is there a better way to require modules with a fallback?
There are two caveats here:
1) Detect if chrome is running
// detects webKit (chrome, safari, etc..)
var isChrome = 'webKitTransform' in document.documentElement.style
2) Requirejs will parse the define()
function and search for require('module')
calls. To prevent the error on chrome you have write the require
in some way that when requirejs
parses the function body it does not recognize the call as a module dependency:
if (isChrome)
// use localStorage
else {
// set the module name in a var does the trick,
// so requirejs will not try to load this module on chrome.
var ffStorageModule = 'simple-storage';
return require(ffStorageModule);
}