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
Related
I want to add optional permissions to my extension and would like to test the warning messages (locally) prior to publishing.
I followed this article, and created the packed .crx file.
However when I upload it (via drag and drop), I get:
This extension is not listed in the Chrome Web Store and may have been added without your knowledge. Learn More
...but, my extension IS listed in the Chrome Webstore.
Am I missing something, or did Chrome permanently disable .crx uploads?
Seems like there is no solution to this online.
Is it possible that my "updated" manifest is causing this issue as it is now using v3 whereas the published extension is v2?
As a workaround, you can use chrome.management.getPermissionWarningsByManifest.
It can be ran from any extension (without the "management" permission, and not necessarily the extension you're testing for warnings) and takes a valid extension manifest file as a string, returning an array of warnings in callback.
An example using the manifest of the extension as linked in your question:
const m = `
{
"update_url": "https://clients2.google.com/service/update2/crx",
"manifest_version": 2,
"version": "2.0.0",
(..skipped..)
"permissions": [
"tabs",
"contextMenus",
"storage",
"alarms",
"downloads",
"downloads.shelf"
],
(..skipped..)
}`;
chrome.management.getPermissionWarningsByManifest(
m,
warnings => { for (let warning of warnings) console.log(warning); }
);
// Prints:
// Read your browsing history
// Manage your downloads
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
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.
I want to distribute a PNaCl app, inline installation and use the app without leaving the current page. I have published the app on CWS. The app needs some user permissions. Inline installation works and the app appears in the Chrome browser apps section. But, I get this error :
"NaCl module load failed: could not load manifest url"
when I try to load the app using:
<embed id="testapp"
width=0 height=0
src="testapp.nmf"
type="application/x-pnacl" />
This is the testapp.nmf file which is located in the .zip pkg that I uploaded to developers dashboard.
{
"program": {
"portable": {
"pnacl-translate": {
"url": "testapp.pexe"
},
"pnacl-debug": {
"url": "testapp_unstripped.bc"
}
}
}
}
Manifest.json in the package file looks like :
{
"name": "testapp",
"version": "0.0.0.2",
"manifest_version": 2,
"description": "TCP/UDP test",
"offline_enabled": true,
"icons": {
"128": "icon128.png"
},
"app": {
"background": {
"scripts": ["background.js"]
}
},
"permissions": [
{
"socket": [
"tcp-listen:*:*",
"tcp-connect",
"resolve-host",
"udp-bind:*:*",
"udp-send-to:*:*"
]
}
]
}
The HTML page is on Google's blogspot.com and verified successfully.
Observations:
You can't use socket APIs outside a packaged app (since there is no way to get permissions for them otherwise).
A packaged app is mostly self-contained: it's not something interacting with the normal browser, it's a preset collection of resources that is displayed in a separate window.
A certain website can still communicate with the app.
Seems like you're trying to follow two guides at once, for a packaged app and a web app. PNaCl can work in the context of a web app by just placing the pexe and the manifest on the site itself; but you require raw network access, and it can only be requested in a packaged app.
You can absolutely use inline install to add the app to the user's machine, but you can't embed a module from it in a normal page.
Your module can only be embedded in the app's own pages. So if you wanted to show some UI, you need to make that a page packaged together with the app and show it with chrome.app.window.create.
If you absolutely need to expose functionality to a certain website, you can list it in externally_connectable and use messaging API to communicate with the app's background page.
An app always has an event page, that is a page that unloads if it's idle. So if you just embed your module in that page by dynamically creating an <embed> element, it may fail. However, if you're using the externally_connectable method, you should be able to keep a port open, that would cause the page to keep running.
I am working on my first extension and am trying to create a simple extension to inject a draggable div on a page. That works nicely, but I want to preserve the location of the div on the background page (I'm also trying out local storage, but want to understand why this isn't working).
I do not need a button so have not created a popup.html file, which, I believe, is entirely optional. It certainly has worked so far just injecting javascript files.
However, I now get the following error thrown when executing chrome.extension.getBackgroundPage():
Uncaught Error: chrome.extension.getBackgroundPage can only be used in extension processes. See the content scripts documentation for more details.
The content scripts documentation did not seem to identify anything wrong with my approach: http://code.google.com/chrome/extensions/content_scripts.html
Here is a redacted manifest I am using:
{
"name": "My helper",
"version": "1.0",
"description": "Tastes great",
"background_page": "background.html",
"content_scripts": [
{
"matches":["https://page.of.interest/*"],
"run_at":"document_idle",
"js":[ "jquery.js", "jquery-ui-1.8.17.custom.min.js", "my_content_script.js"],
"css": [ "my_content_script.css" ]
}
],
"permissions": [
"background"
]
}
So I am running this statement inside "my_content_script.js". Is this NOT considered part of the extension process? Can I only run this on a popup.html (or other possibly?) file?
If this is the case, then maybe it is easier to just use localstorage rather than trying to communicate through the dom with the extension process.
Hope I've been clear despite my ignorance about some of these concepts.
I don't think the docs explicitly say you can't use chrome.extension.getBackgroundPage() from a content_script but because the content_script has permissions more oriented with the page it is being run on it isn't allowed access. The docs do mention a few methods you can use however.
Unlike the other chrome.* APIs, parts of chrome.extension can be used by content scripts:
You will have to use message passing to communicate between the background_page and the content_script.
You have to use the chrome.cookies.get() in background.html, and then do the communication between your content script and background.html for exchanging cookie data.