I'm using a boilerplate to boostrap my project and I replicate the issue here https://github.com/datgrog/chrome-extension-boilerplate-react.
- When you run
npm startafternpm i, go to https://example.com/ and open the dev tool (F12). You will see that there isUnchecked runtime.lastError: Could not establish connection. Receiving end does not exist.which is normal as no popup is open. - Then open the popup or open a new tab with your
extension_idchrome-extension://extension_id/popup.html and reload the example.com page, you will see that it works as expected. - Then edit the
Popup.jsxor either background/content'sindex.jswith anything, a log, or modify the text of the component. The popup reloads and reflects the change. Then reload the example.com page, you will see that the message does not pass anymore.
I slightly modify the repo above by using chrome.runtime.connect instead and same results. There is no error, it feels just stuck, no error throw.
content's index.js
function notifyPopupPage() {
const port = chrome.runtime.connect({name: "knockknock"});
port.postMessage({joke: "Knock knock"});
port.onMessage.addListener(function(msg) {
console.log(msg);
if (msg.question === "Who's there?")
port.postMessage({answer: "Madame"});
else if (msg.question === "Madame who?")
port.postMessage({answer: "Madame... Bovary"});
}
);
port.onDisconnect.addListener(function(event) {
console.log('disconnected', event);
});
}
popup.jsx
function knockListener(port) {
console.assert(port.name === "knockknock");
port.onMessage.addListener(function(msg) {
console.log(msg);
if (msg.joke === "Knock knock") {
port.postMessage({question: "Who's there?"});
}
else if (msg.answer === "Madame")
port.postMessage({question: "Madame who?"});
else if (msg.answer === "Madame... Bovary")
port.postMessage({question: "I don't get it."});
});
port.onDisconnect.addListener(function(event) {
console.log('disconnected', event);
});
}
const Popup = () => {
// https://www.pluralsight.com/guides/event-listeners-in-react-components
React.useEffect(() => {
// chrome.runtime.onMessage.addListener(greetingListener);
chrome.runtime.onConnect.addListener(knockListener);
return () => {
// chrome.runtime.onMessage.removeListener(greetingListener);
chrome.runtime.onConnect.removeListener(knockListener);
};
}, []);
EDIT: from my understanding, it is not related about Chrome extension content script re-injection after upgrade or install because as mentionned I don't mind reloading the example.com page, which is the one who trigger the chrome.runtime. And it does fire but the receiver never catch it and it stays stuck, and of course then the callback is never called.