In chrome extensions manifest v3 it's stated that background.js is now replaced with service worker and dom is not available in a service worker. Then suggests undom
or jsdom
to be used as an alternative for DOMParser API.
Libraries such as jsdom can be used to emulate a typical browser window environment, complete with DOMParser, event propagation, and other capabilities like requestAnimationFrame. Lighter-weight alternatives like undom provide just enough DOM to power many frontend frameworks and libraries.
But undom
is too limited and is just capable of creating elements but not querying dom elements which I need despite being easily usable in the service worker. So it tried to use jsdom
which is more thorough with a drawback of a ~6MB size.
I tried to import jsdom
and I learned it can be done using browserify
in a comment to this question when I use a browserify
ed bundle in a simple HTML file it works as expected but not in the chrome extension, which gives this error:
ReferenceError: require is not defined
.
I used this answer to load the required js files like this:
try {
importScripts('assets/jsdom.bundle.js', 'common.js', 'search.js', 'background.js');
} catch (e) {
console.error(e);
}
and tried to use it like this in search.js
:
const jsdom = require("./assets/jsdom.bundle");
const { JSDOM } = jsdom;
How jsdom
can be used in a chrome extension service worker correctly?
Thanks to @wOxxOm's comment that put me in the right direction I managed to make it work like this:
1- Created a js file named main.js:
var jsdom = require("jsdom");
exports.jsdom = jsdom;
2- browserified it with this command:
browserify main.js -o jsdom.bundle.js --standalone jsdomModule
3- And finally used it in the service worker like this:
const { JSDOM } = jsdomModule.jsdom;
const jd = new JSDOM('<div>hello</div>');
Then I got this error when calling querySelector
function:
EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self'".
So after my 4th weekend on this, I gave up on using jsdom and went for doing the job in the content script and using "Message passing" to communicate with service worker which worked like a charm. I think google guys should remove their jsdom suggestion from the documentation.