MarshallOfSound / electron-devtools-installer

An easy way to ensure Chrome DevTools extensions into Electron
MIT License
1.11k stars 136 forks source link

[ReactDevTools] components are not loaded #238

Open spamshaker opened 1 year ago

spamshaker commented 1 year ago

On Mac M1 OS Ventura when used installer I am getting the following error

"electron-devtools-installer": "^3.2.0", "electron": "23.1.1"

(node:75950) ExtensionLoadWarning: Warnings loading extension at /Users/user/Library/Application Support/app/extensions/fmkadmapgofadopljbjfkapdkoienihi:
  Permission 'scripting' is unknown or URL pattern is malformed.

[75950:0326/172543.650797:ERROR:CONSOLE(2)] "Electron sandboxed_renderer.bundle.js script failed to run", source: node:electron/js2c/sandbox_bundle (2)
[75950:0326/172543.650825:ERROR:CONSOLE(2)] "TypeError: object null is not iterable (cannot read property Symbol(Symbol.iterator))", source: node:electron/js2c/sandbox_bundle (2)
[75950:0326/172545.408171:ERROR:extensions_browser_client.cc(62)] Extension Error:
  OTR:     false
  Level:   2
  Source:  chrome-extension://poocdgihabcgkndohblokpkdlnkmlkdj/build/background.js
  Message: Uncaught TypeError: Cannot read properties of undefined (reading 'registerContentScripts')
  ID:      poocdgihabcgkndohblokpkdlnkmlkdj
  Type:    RuntimeError
  Context: chrome-extension://poocdgihabcgkndohblokpkdlnkmlkdj/build/background.js
  Stack Trace: 
    {
      Line:     107
      Column:   1
      URL:      chrome-extension://poocdgihabcgkndohblokpkdlnkmlkdj/build/background.js
      Function: (anonymous function)
    }
[75950:0326/172548.361243:ERROR:CONSOLE(2)] "Electron sandboxed_renderer.bundle.js script failed to run", source: node:electron/js2c/sandbox_bundle (2)
[75950:0326/172548.361280:ERROR:CONSOLE(2)] "TypeError: object null is not iterable (cannot read property Symbol(Symbol.iterator))", source: node:electron/js2c/sandbox_bundle (2)
[75950:0326/172549.919597:ERROR:extensions_browser_client.cc(62)] Extension Error:
  OTR:     false
  Level:   2
  Source:  chrome-extension://poocdgihabcgkndohblokpkdlnkmlkdj/build/background.js
  Message: Uncaught TypeError: Cannot read properties of undefined (reading 'registerContentScripts')
  ID:      poocdgihabcgkndohblokpkdlnkmlkdj
  Type:    RuntimeError
  Context: chrome-extension://poocdgihabcgkndohblokpkdlnkmlkdj/build/background.js
  Stack Trace: 
    {
      Line:     107
      Column:   1
      URL:      chrome-extension://poocdgihabcgkndohblokpkdlnkmlkdj/build/background.js
      Function: (anonymous function)
    }
2023-03-26 17:37:35.472 Electron[75950:28284964] +[CATransaction synchronize] called within transaction
2023-03-26 17:37:35.563 Electron[75950:28284964] +[CATransaction synchronize] called within transaction

the extension is loaded in browser view, but in Devtools -> Components tab, it says

Loading React Element Tree... If this seems stuck, please follow the troubleshooting instructions.

The extension works fine in Chrome browser.

what could be wrong?

spamshaker commented 1 year ago

ok seems it is the Electron issue which differs from Chrome. So the extension won't work due to electron has not exposed chrome.scripting in the api https://www.electronjs.org/docs/latest/api/extensions#supported-extensions-apis maybe this should be mentioned in README that the https://github.com/facebook/react/tree/main/packages/react-devtools-extensions/chrome extension won't work

xupea commented 1 year ago

@spamshaker hope this repo ease your pain: https://github.com/xupea/electron-devtools-installer

jonluca commented 1 year ago

That version seems to be having issues with electron 24.

Also that repo redirects CRX requests to the developers domain, instead of downloading directly from the chrome webstore. (see here https://github.com/xupea/electron-devtools-installer/blob/master/src/downloadChromeExtension.ts#L24) - I now realize this is required, because google doesn't let you download historical chrome versions, unfortunately

capture 2023-04-06 at 1 22 26 PM

I published https://www.npmjs.com/package/electron-extension-installer to fix that (source code here)

import { installExtension, REACT_DEVELOPER_TOOLS } from "electron-extension-installer";

app.on("ready", async () => {
  await installExtension(REACT_DEVELOPER_TOOLS, {
    loadExtensionOptions: {
      allowFileAccess: true,
    },
  });
});
unzld commented 1 year ago

That version seems to be having issues with electron 24.

~Also that repo redirects CRX requests to the developers domain, instead of downloading directly from the chrome webstore. (see here https://github.com/xupea/electron-devtools-installer/blob/master/src/downloadChromeExtension.ts#L24)~ - I now realize this is required, because google doesn't let you download historical chrome versions, unfortunately

capture 2023-04-06 at 1 22 26 PM

I published https://www.npmjs.com/package/electron-extension-installer to fix that (source code here)

import { installExtension, REACT_DEVELOPER_TOOLS } from "electron-extension-installer";

app.on("ready", async () => {
  await installExtension(REACT_DEVELOPER_TOOLS, {
    loadExtensionOptions: {
      allowFileAccess: true,
    },
  });
});

I'm still getting errors while using yours, but this time they're different from OP. I'm using electron@23.2.1

[1] [149237:0414/043621.834038:ERROR:CONSOLE(2)] "Electron sandboxed_renderer.bundle.js script failed to run", source: node:electron/js2c/sandbox_bundle (2)
[1] [149237:0414/043621.834072:ERROR:CONSOLE(2)] "TypeError: object null is not iterable (cannot read property Symbol(Symbol.iterator))", source: node:electron/js2c/sandbox_bundle (2)
[1] [149237:0414/043624.487576:ERROR:CONSOLE(2)] "Electron sandboxed_renderer.bundle.js script failed to run", source: node:electron/js2c/sandbox_bundle (2)
[1] [149237:0414/043624.487647:ERROR:CONSOLE(2)] "TypeError: object null is not iterable (cannot read property Symbol(Symbol.iterator))", source: node:electron/js2c/sandbox_bundle (2)
syabro commented 1 year ago

@unzld same here...

jonluca commented 1 year ago

AFAICT that issue is internal, when calling load extension, and needs to fixed from electrons side.

MarcelFinkbeiner commented 1 year ago

Same for me (vite,vue3,ts,electron,VUEJS3_DEVTOOLS).

jcharnley commented 1 year ago

That version seems to be having issues with electron 24.

~Also that repo redirects CRX requests to the developers domain, instead of downloading directly from the chrome webstore. (see here https://github.com/xupea/electron-devtools-installer/blob/master/src/downloadChromeExtension.ts#L24)~ - I now realize this is required, because google doesn't let you download historical chrome versions, unfortunately

capture 2023-04-06 at 1 22 26 PM

I published https://www.npmjs.com/package/electron-extension-installer to fix that (source code here)

import { installExtension, REACT_DEVELOPER_TOOLS } from "electron-extension-installer";

app.on("ready", async () => {
  await installExtension(REACT_DEVELOPER_TOOLS, {
    loadExtensionOptions: {
      allowFileAccess: true,
    },
  });
});

this is the only solution that works for me, great work on the npm package

Stanzilla commented 3 months ago

@MarshallOfSound any plans to update this?

nikinikinico commented 3 months ago

I used electron-extension-installer but another promble occured, [39252:0415/173432.902:ERROR:CONSOLE(2)] "Electron renderer.bundle.js script failed to run", source: node:electron/js2c/renderer_init (2) , does any body have the same promble?

tomhervieu9 commented 3 months ago

I used electron-extension-installer but another promble occured, [39252:0415/173432.902:ERROR:CONSOLE(2)] "Electron renderer.bundle.js script failed to run", source: node:electron/js2c/renderer_init (2) , does any body have the same promble?

I am facing the same issue on electron v25. According the the publisher of electron-extensions-installer, it seems the problem is from electron's side. https://github.com/MarshallOfSound/electron-devtools-installer/issues/238#issuecomment-1538349985 . It could be that updating to a more recent version of electron could fix this or the error just needs to get handled to avoid polluting the log (somehow) until the bug gets fixed.

Still, big shout out to @jonluca for publishing the package.

danthegoodman commented 1 week ago

After some digging around, I found the following things:

  1. React looks for __REACT_DEVTOOLS_GLOBAL_HOOK__ with a checkDCE function. (HMR tooling also sets up this global but without that property, which threw off my debugging a little bit)
  2. The extension injects this global into every page through the use of a background: {serviceWorker: ...} property in the manifest.
  3. Electron doesn't seem to init this service worker until after the devtools are opened up for the first time.

So to work around this in my own app, I setup this function and call it before I setup my app window:

async function loadDevtools() {
  const edi = await import('electron-devtools-installer');
  const installExtension = edi.default.default;
  await installExtension(edi.REDUX_DEVTOOLS);
  await installExtension(edi.REACT_DEVELOPER_TOOLS);

  // hack because extension service workers aren't loaded until after first launch
  const win = new BrowserWindow({
    show: false,
    webPreferences: { devTools: true },
  });
  await win.loadURL('about:blank');
  win.webContents.openDevTools({ mode: 'detach', activate: false });
  await new Promise<void>((resolve, reject) => {
    let checksLeft = 300;
    const interval = setInterval(() => {
      const all = session.defaultSession.serviceWorkers.getAllRunning();
      if (Object.keys(all).length > 0) {
        clearInterval(interval);
        resolve();
      } else {
        checksLeft -= 1;
        if (checksLeft <= 0) {
          clearInterval(interval);
          reject(new Error('react dev tools failed to load a service worker'));
        }
      }
    }, 10);
  });
  win.close();
}
Stanzilla commented 1 week ago

After some digging around, I found the following things:

  1. React looks for __REACT_DEVTOOLS_GLOBAL_HOOK__ with a checkDCE function. (HMR tooling also sets up this global but without that property, which threw off my debugging a little bit)
  2. The extension injects this global into every page through the use of a background: {serviceWorker: ...} property in the manifest.
  3. Electron doesn't seem to init this service worker until after the devtools are opened up for the first time.

So to work around this in my own app, I setup this function and call it before I setup my app window:

async function loadDevtools() {
  const edi = await import('electron-devtools-installer');
  const installExtension = edi.default.default;
  await installExtension(edi.REDUX_DEVTOOLS);
  await installExtension(edi.REACT_DEVELOPER_TOOLS);

  // hack because extension service workers aren't loaded until after first launch
  const win = new BrowserWindow({
    show: false,
    webPreferences: { devTools: true },
  });
  await win.loadURL('about:blank');
  win.webContents.openDevTools({ mode: 'detach', activate: false });
  await new Promise<void>((resolve, reject) => {
    let checksLeft = 300;
    const interval = setInterval(() => {
      const all = session.defaultSession.serviceWorkers.getAllRunning();
      if (Object.keys(all).length > 0) {
        clearInterval(interval);
        resolve();
      } else {
        checksLeft -= 1;
        if (checksLeft <= 0) {
          clearInterval(interval);
          reject(new Error('react dev tools failed to load a service worker'));
        }
      }
    }, 10);
  });
  win.close();
}

that errors with

[{
    "resource": "/Users/stan/projects/personal/wago-app/src/main/main.ts",
    "owner": "typescript",
    "code": "2339",
    "severity": 8,
    "message": "Property 'default' does not exist on type '(extensionReference: string | ExtensionReference | (string | ExtensionReference)[], options?: boolean | ExtensionOptions | undefined) => Promise<...>'.",
    "source": "ts",
    "startLineNumber": 146,
    "startColumn": 40,
    "endLineNumber": 146,
    "endColumn": 47
}]

for

const installExtension = edi.default.default;

I assume you wanted const installExtension = edi.default; but that sadly does not work here either.

Error: react dev tools failed to load a service worker

When exactly are you calling your function?

danthegoodman commented 1 week ago

When exactly are you calling your function?

app.whenReady().then(main).catch(console.error);
async function main(){
if (IS_DEV) {
await loadDevTools();
}
await launchApp();
}

I assume you wanted const installExtension = edi.default; but that sadly does not work here either.

I wrestled with the import a little bit. I'm using ESM imports, @swc-core/cli to compile my code and typescript to just do type linting. In various iterations, I just clobbered the offending import with //@ts-ignore statements and poked and prodded with the import statement until I got it to run.