Last Updated: February 25, 2016
·
6.24K
· jacob4u2

Chrome Extension RequireJS Content Scripts

If you are interested in using RequireJS in your Chrome Extension take a look at this handy starter repo template on Github.

The template has one key file require-cs.js:

require.load = function (context, moduleName, url) {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", url, true);
  xhr.onreadystatechange = function (e) {
    if (xhr.readyState === 4 && xhr.status === 200) {
      eval(xhr.responseText);
      context.completeLoad(moduleName)
    }
  };
  xhr.send(null);
};

This will allow your content scripts to be loaded in the context of your extension rather than inserted in to the page where require is probably not defined.

3 Responses
Add your response

Please correct me if I'm wrong but, doing so in a chrome extension already moved to the version 2 of the manifest (which is required for all the new extensions), without relaxing the CSP policies, shouldn't it generates a security exception due to the eval() instruction?

BTW, this is the same problem in which most template libraries incur when they use new Function() with default CSP manifest v2 policy.

over 1 year ago ·

As long as the eval() is used in a content-script it is fine. But, yes, I did run into that CSP issue with lodash and had to make it a web_accessible_resource and use the mobile build to get it to run.

For background scripts I use an html file with a script tag that references my require.js file and uses the data-main attribute and everything seems fine without having to use the require-cs.js file.

over 1 year ago ·

This errors occur if i use requirejs in chrome-extension. Without chrome-extension, also call over script-tag( <script data-main="js/main" src="js/lib/requirejs/require.js"></script> ) everything works well.

If i require('backbone') in test.js( see below ) i get an error --> Uncaught TypeError: Cannot call method 'each' of undefined ! i believe backbone cant call "each" method because underscore is not loaded completely ( see http://tinypic.com/view.php?pic=6j3a08&s=5 )

What am I doing wrong?

manifest.json file

{
"manifestversion": 2,

.....
.....
....
"content
scripts": [
{
"matches": ["<all_urls>"],
"js": [
"js/lib/requirejs/require.js",
"js/lib/requirejs/require-cs.js",
"js/main.js"
]
}
],
.....
.....
.....
}

main.js

requirejs.config({
baseUrl: chrome.extension.getURL("/"),
urlArgs: "v=" + (new Date()).getTime(),
paths: {
app : 'js/app',
jquery: 'js/lib/jquery/jquery',
backbone : 'js/lib/backbone/backbone',
underscore : 'js/lib/underscore/underscore'
},
shim : {
jquery : {
exports : '$'
},
backbone: {
deps: ['jquery', 'underscore'],
exports: 'Backbone'
},
underscore : {
exports : '_'
}
}

});
require(['app/test'], function (test) {
console.log(test);
});

define() file test.js

define(function(require){

var $ = require('jquery');

$('body').append('<div id="foo">im appended over requirejs</div>');
$('body').on({
        click : function(){
              var Backbone = require('backbone');
              console.log(Backbone);
        }
}, '#foo');

return {
    foo : 'foo',
    hoo : 'huu'
};

});

over 1 year ago ·