How to debug chrome extension service worker for manifest v3? - google-chrome-extension

I am experimenting with chrome extension manifest v3 (on chrome canary) and I can't find any way to debug the service worker script defined in the manifest.json. For manifest v2 there was a link on the chrome://extensions/ page that would open a background page console. Is there any way to view logs in the manifest v3 service worker script?
I am testing with this minimal working example of a manifest v3 service worker extension: https://gist.github.com/dotproto/3a328d6b187621b445499ba503599dc0.
There is nothing mentioned on this debugging page: https://developer.chrome.com/apps/tut_debugging
There is also nothing mentioned on either of the migration guides:
https://developer.chrome.com/extensions/migrating_to_manifest_v3
https://developer.chrome.com/extensions/migrating_to_service_workers

I guess you are looking for the internal ServiceWorker (backend page) of your extension and their connections.
There are two URLs you should be aware of:
chrome://inspect/#service-workers
chrome://serviceworker-internals/?devtools
You might also want to "debug the debugger" e.g. for breakpoints inside your extension page.
1. Registered ServiceWorker list (normal + internal)
chrome://inspect/#service-workers
2. ServiceWorker activity (active connections/clients, console logs, … )
chrome://serviceworker-internals/?devtools
3. Inspect DevTools extension
Option A: From contextmenu
Open your extension panel
Open contextmenu and select inspect
2nd DevTools instance opens
Option B: From extensions page
Open chrome://extensions
Find your extension click "Details"

After a bit of searching I found that logs are displayed in the Service Workers section of inside the page's console under Application. You must run the service worker and then click inspect to see logs generated by the service worker script.

we write the manifest.json in v2 like this:
{
...
"manifest_version": 2,
"background": {
"scripts": ["background.js"]
},
...
}
but refer to Simeon Vincent Talk you should write manifest like this in v3
{
...
"manifest_version": 3,
"background": {
"service_worker": "background.js"
}
...
}
and then refresh the extension you can see the inspect view Service Worker on chrome://extensions/, then click the Service Worker link to open a DevTools and show the Console.

Related

With a Manifest v3 Chrome Extension, is it possible to load an extension HTML resource file into a new tab?

With a Manifest v3 Chrome Extension, is it possible to load an extension HTML resource file into a new tab? I was thinking about providing a plugin with a larger, full-page user experience than what the popdown panel could provide. I created a page.html (just simple HTML for now, no JS or CSS) and put it in my extensions folder. I then added this to the manifest.json:
"web_accessible_resources": [
{
"resources": ["page.html"],
"matches": [ "*://*/*" ]
}
]
I reloaded the plugin and then tried navigating to this page in my browser with:
chrome://extensions/MY-EXTENSION-ID-GOES-HERE/page.html
I get an ERR_FAILED and "This site can't be reached" message.
There is no need for a web_accessible_resources in this case in the v3 manifest for this action. Just use something like the following code to open it from the service-worker.js:
chrome.tabs.create({url:chrome.runtime.getURL('page.html'),active:true});
This will automatically open something akin to...
chrome-extension://MY-EXTENSION-ID/page.html
...where MY-EXTENSION-ID is automatically filled in by chrome.runtime.getURL('page.html').
You can then reference remote and local resources in your HTML tags. For local resources, just use relative pathing. For remote resources, keep an eye on Google Chrome Extension developer policies.
Thanks goes to wOxxOm for his assistance.

Service worker registration failed. Chrome extension

I don't understand how to migrate from manifest v2 to v3 in part of Service Worker. Occurs error Service worker registration failed
// manifest.json
"background": {
"service_worker": "/script/background/background.js"
},
// background.js
chrome.runtime.onInstalled.addListener(onInstalled);
Please find below the cause for your specific issue and the cause for not getting the details of failure in the console log.
Before Chrome 93, the service worker file must be in the root path
where manifest.json is.
This is a limitation of Service Worker specification, relaxed for extensions since Chrome 93.
If, for whatever reason, you want to allow your extension to be used in older Chrome, the correct manifest.json should look like this:
"background": {
"service_worker": "background.js"
},
Conversely, to use an arbitrary path you need to prevent installation in older Chrome:
"minimum_chrome_version": "93",
"background": {
"service_worker": "js/bg/worker-loader.js",
"type": "module"
},
Type module is optional and is supported since Chrome 92. You can import ES modules statically for now. The support for dynamic imports is in development.
In any Chrome version you can use importScripts('/path/foo.js', '/path/bar.js'); to import scripts from other directories.
If the worker script throws an error at installation, the worker won't be registered and you will not be getting the error information triggered by your service worker in the console, but only get "Service worker registration failed". This behavior is due to a bug bug in Chrome versions earlier than Chrome 93.
Solution:
use Chrome 93 or newer.
Limited workaround:
wrap everything in try/catch as shown in the other answer or use a "loader" script.
Typical causes:
accessing an undeclared variable
syntax error like an unclosed parenthesis
accessing a chrome API without declaring it in manifest.json's permissions field
a crash in the worker process
If the same error is still here after the script was moved to the root folder as wOxxOm mentioned, than you probably have an error in your background.js file. However at the time of this post there was no adequate error message on this, other than generic Service worker registration failed.
Try to follow Simeon's workaround described here
For example you could wrap your v2 background.js script into an error-catching service worker and import your old scripts in it:
// manifest.json
{
"name": "Throw on Register!",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "background-wrapper.js"
}
}
// background-wrapper.js file
try {
importScripts("background.js");
} catch (e) {
console.error(e);
}
// background.js
console.log("start");
throw new Error("lol");
console.log("end");
After that your service worker will be registered as it is as simple as possible and you will have the error info in the console. In my case it looks like that: example
Happy moving to v3 :)
Service workers must be registered at root level: they cannot be in a
nested directory.
Since background.js is service worker now it can't be inside nested folder
Reference: https://developer.chrome.com/docs/extensions/mv3/mv3-migration-checklist/#api_checklist

Chrome background.js do not run unless manually click refresh icon in extension page every time the chrome first open

Recently I am developing an extension which listens to tab change and do some stuff according to it. Now I wrote my main logic in chrome.runtime.onInstalled.addListener in background.js. I used unpacked version for development. However, to make the extension work, I need to manually go to the extension page and click refresh icon every time when first open a chrome window, otherwise, it will not work. Is there a way to make the background.js run the code without manually click refresh button? I tried onStartup but it doesn't work out.
Although not ideal, you can make the background script run persistently if you modify your manifest.json to...
{
"name": "My extension",
...
"background": {
"scripts": ["background.js"],
"persistent": true
},
...
}
This is not recommended because background scripts can use a lot of resources so you should use something like chromes messaging API to run only on set/specific events.
If you need to look into changing your background script, look at this for more information.

Opening chrome extension in new tab

Is this still valid?
"app": {
"launch": {
"local_path": "window.html",
"container": "tab"
}
},
I'm using Chrome v46 and it works but I'd like to be sure it is not a bug.
I cannot see anything like this in the manifest file reference
Your manifest snippet (containing app.launch.local_path) describes a legacy packaged app. These are deprecated and not officially supported any more.
If you want to have an icon in the app launcher, then you need to create a Chrome app (if you want to host the content in the package) or a hosted app (if you want to host the content online).
If you don't want to create an app, but an extension, then you could use a browser action button to add a button to the toolbar, and then open a page in a new tab using chrome.tabs.create. Or, if your actual goal is replacing the new tab page, use chrome_url_overrides to override newtab.

How to inject javascript into Chrome DevTools itself

Ok, so just the other day I learned that you can inspect the devtools if it is in its own window(explained here). I also learned that you can style the devtools with your own css by editing the Custom.css file in your profile on your computer(more on that here).
What I want to do is not only add css, but also javascript, via a chrome extension. I am very aware of devtools pages, but those do not do what I want. Pretty much I want to get a content script to run on the devtools inspector itself. I found one extension that does exactly this, but for the life of me I have not been able to replicate it(even when copy-pasting the code!!). The extension is the "Discover DevTools Companion extension" from Code School(on the webstore). They even explain how it works, but I still have had no luck. That was the only extension I have found that does what I want. So I guess what I'm really asking is if its just me that cannot get it to work or if others that try are having trouble also.
Usually, you cannot create a Chrome extension which injects code in a devtools page.
The "Discover DevTools Companion" extension from now on, referred to as DDC is allowed to do this, because this extension is whitelisted in the source code of Chromium: (this is no longer the case)
// Whitelist "Discover DevTools Companion" extension from Google that
// needs the ability to script DevTools pages. Companion will assist
// online courses and will be needed while the online educational programs
// are in place.
scripting_whitelist_.push_back("angkfkebojeancgemegoedelbnjgcgme");
If you want to publish an extension in the Chrome Web Store with these capabilities, give up.
If you want to create such an extension for personal / internal use, read further.
Method 1: Impersonate the DDC a whitelisted extension
The easiest way to create an extension with such permissions is to create an extension with the extension ID of a whitelisted extension (e.g. ChromeVox). This is achieved by copying the "key" key of its manifest file to your extension's manifest (see also: How to get the key?). This is a minimal example:
manifest.json
{
// WARNING: Do NOT load this extension if you use ChromeVox!
// WARNING: Do NOT load this extension if you use ChromeVox!
// WARNING: This is a REALLY BIG HAMMER.
"content_scripts": [{
"js": [ "run_as_devtools.js" ],
"matches": [ "<all_urls>" ]
}],
// This is the key for kgejglhpjiefppelpmljglcjbhoiplfn (ChromeVox)
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEGBi/oD7Yl/Y16w3+gee/95/EUpRZ2U6c+8orV5ei+3CRsBsoXI/DPGBauZ3rWQ47aQnfoG00sXigFdJA2NhNK9OgmRA2evnsRRbjYm2BG1twpaLsgQPPus3PyczbDCvhFu8k24wzFyEtxLrfxAGBseBPb9QrCz7B4k2QgxD/CwIDAQAB",
"manifest_version": 2,
"name": "Elevated Devtools extension",
"version": "1.0"
}
run_as_devtools.js
if (location.protocol === 'chrome-devtools:') (function() {
'use strict';
// Whatever you want to do with the devtools.
})();
Note: This method is truly a hack. Since the extension shares the same ID as ChromeVox, both extensions cannot co-exist. And if Chrome decides to remove the whitelisted extension, then your permissions will evaporate.
Instead of filtering via the content script, you can also use the include_globs key to restrict the content script to devtools only.
Method 2: Modify resources.pak
I suggest to go with method 1 if possible. When method 1 fails (e.g. because the extension is no longer whitelisted), use the next method.
Get paktools.py, unpack.py and pack.py from DennisKehrig/patch_devtools (on Github).
Locate your Chrome directory containing resources.pak.
Run python2 unpack.py resources.pak, which creates a directory resources containing all files (all file names are numbers).
Locate the file containing a script which runs in the context of the developer tools. Add your desired code there.
Remove resources.pak
Run python2 pack.py resources to create the new resources.pak file.
Note: resources.pak may be replaced when Chrome is updated, so I suggest to create a script which automates my described algorithm. That shouldn't be too difficult.
If you're interested, you can look up the .pak file format in ui/base/resource/data_pack_literal.cc (description in human language).
For those googlers who end up at this page (as I did) looking for something else, this page answers the question of manipulating DevTools ITSELF - not adding jQuery to DevTools, or injecting javaScript onto a web page. For those, see here instead:
Inject jQuery into DevTools (Chrome or Firefox):
Firefox DevTools: Automatically injecting jQuery
Inject your own javascript/css onto any web page:
How to edit a website's background colors

Resources