1

I am trying to use socket.io library in a service worker of y Chrome extension, but when I try to load it in Chrome I get the error: Uncaught SyntaxError: "Cannot use import statement outside a module".

I got the library from here, then I saved the it in my extension folder, in socketIo.js:

enter image description here

Then in my service_worker.js, I try to import it:

import io from './socketIo.js';
const socket = io("http://localhost:3002");

Since it as service worker, I do not attach it to my extension html file, therefore I can't simply set the worker as a module like this:

<script type="module" src="./service_worker.js"></script>. 

Also, since extensions are not Node.js applications, they don't have a package.json where I could set the property "type": "module.

And as you can see I used both the relative path and the extension of the file imported, as suggested here: Chrome Extension Service Worker not Supporting Importing Other JS Files or NPM Packages

Now I've added the ES module version of socket.io and its "map" file. And updated my service worker in manifest.json to be a ES module too:

enter image description here

enter image description here

enter image description here

But when I tried to load the extension again, I get this warning: "Service worker registration failed. Status code: 3", and the generic error:

enter image description here

Lucas
  • 157
  • 1
  • 12

1 Answers1

2

Since it as service worker, I do not attach it to my extension html file, therefore I can't simply set the worker as a module like this: .

Also, since extensions are not Node.js applications, they don't have a package.json where I could set the property "type": "module.

Register the service worker

You can optionally specify an extra field of "type": "module" to include the service worker as an ES Module, which allows you to import further code.

manifest.json

{
    "manifest_version": 3,
    "name": "socket.io",
    "version": "1.0",
    "background": {
        "service_worker": "background.js",
        "type": "module"
    }
}

But the socket.io version you're using isn't an ES Module:

Uncaught SyntaxError: The requested module '/socket.io.js' does not provide an export named 'default'

So I downloaded socket.io.esm.min.js and socket.io.esm.min.js.map from https://cdn.socket.io/4.5.3

I don't know if they have an ES Module version of socket.io 1.7.3

Including the .map file in the extension prevents this error in the service worker console:

DevTools failed to load source map: Could not load content for chrome-extension://cfdinlnmiepoligakoinbffeaphkfmmp/socket.io.esm.min.js.map: System error: net::ERR_FILE_NOT_FOUND

background.js

import io from "/socket.io.esm.min.js";
const socket = io("http://localhost:3002");

The service worker console still gets flooded with this error:

Event handler of 'beforeunload' event must be added on the initial evaluation of worker script.

But I think there's a solution for that on Stackoverflow.

Or not:

Also, put the libraries socket.io.esm.min.js and socket.io.esm.min.js.map inside the same folder of service worker, in the same level (not in a sub folder).

After you made this changes, just refresh you extension in chrome://extensions/. But if this doesn't work, delete your extension and load it unpacked again.

Thomas Mueller
  • 514
  • 1
  • 4
  • 10
  • Hi @ThomasMuller ! What is the service worker console? I made the chages, and when reload my extension in chrome://extensions I get the error that I added up there in my question, but not the "Event handler of 'beforeunload' event must be added on the initial evaluation of worker script." – Lucas Nov 14 '22 at 11:46
  • This error disappears when I remove the "import io from "/socket.io.esm.min.js"; const socket = io("http://localhost:3002"); " from my service worker... – Lucas Nov 14 '22 at 11:56
  • 1
    "What is the service worker console?" --- Please read [Debugging extensions](https://developer.chrome.com/docs/extensions/mv3/tut_debugging/). – Thomas Mueller Nov 14 '22 at 13:09
  • 1
    I made the chages, and when reload my extension in chrome://extensions I get the error that I added up there in my question, but not the "Event handler of 'beforeunload' event must be added on the initial evaluation of worker script." --- It works for me, but if it doesn't for you, then I'm afraid I cannot help. Maybe someone else can. I wish you the best of luck with your extension! – Thomas Mueller Nov 14 '22 at 13:10
  • I had the socket.io files in a subfolder of that of serice_worker.js. So I moved them to the same level, and deleted and added my extension again (refresh was not enough), then it worked. – Lucas Nov 15 '22 at 17:22
  • It doesn't matter where you put the ES Modules, as long as the import statement in the service worker uses the correct path. If the ES modules are located at `/esm/socket.io.esm.min.js` and `/esm/socket.io.esm.min.js.map`, then `import io from "/esm/socket.io.esm.min.js";` in the service worker imports them. I used abolute paths because that's less confusing; you don't have to know the path of the importing file. – Thomas Mueller Nov 15 '22 at 21:39
  • Yeah. I know. But my relative paths were right, and even though id did not work. I'm not sure what happened. Maybe is something about how expensions manage imports in service worker. – Lucas Nov 16 '22 at 12:20