I'm using Service Worker in my React-JS project. Our project runs in 2 combinations of Browsers and an Operation System.
Chromium-102.0.5005.63 and Windows 7
Chromium-49.0.2623.75 and Windows XP
Service worker works fine in Chromium-102.0.5005.63 and Windows 7, but it's not working in Chromium-49.0.2623.75 and Windows XP, throwing the following error:
Uncaught TypeError: Cannot read property of 'set' of undefined
ServiceWorker script evaluation failed
A few things to mention:
1. Project URL load under https
2. Chromium-49.0.2623.75 supports Service Worker as mentioned in the specifications
Reference 1: https://caniuse.com/?search=service worker
Reference 2: https://blog.chromium.org/2016/02/chrome-49-beta-css-custom-properties.html
3. "serviceWorker" in navigator returns true
in Chromium-49.0.2623.75 and running on production mode
4. browserslist
is updated and defined as follows in package.json
"browserslist": {
"production": [
"> 0.04%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
When I use npx browserslist
I can see chrome 49
in the list.
5. I'm not using any .set
in service-worker.js
and serviceWorkerRegistration.js
UPDATE 1:
Cannot read property of 'set' of undefined
is caused by the following method in service-worker.js. cacheKeyURL.searchParams
is undefined.
var REVISION_SEARCH_PARAM = '__WB_REVISION__';
/**
* Converts a manifest entry into a versioned URL suitable for precaching.
*
* @param {Object|string} entry
* @return {string} A URL with versioning info.
*
* @private
* @memberof workbox-precaching
*/
function createCacheKey(entry) {
if (!entry) {
throw new WorkboxError_WorkboxError('add-to-cache-list-unexpected-type', {
entry: entry
});
} // If a precache manifest entry is a string, it's assumed to be a versioned
// URL, like '/app.abcd1234.js'. Return as-is.
if (typeof entry === 'string') {
var urlObject = new URL(entry, location.href);
return {
cacheKey: urlObject.href,
url: urlObject.href
};
}
var revision = entry.revision,
url = entry.url;
if (!url) {
throw new WorkboxError_WorkboxError('add-to-cache-list-unexpected-type', {
entry: entry
});
} // If there's just a URL and no revision, then it's also assumed to be a
// versioned URL.
if (!revision) {
var urlObject = new URL(url, location.href);
return {
cacheKey: urlObject.href,
url: urlObject.href
};
} // Otherwise, construct a properly versioned URL using the custom Workbox
// search parameter along with the revision info.
var cacheKeyURL = new URL(url, location.href);
var originalURL = new URL(url, location.href);
cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);
return {
cacheKey: cacheKeyURL.href,
url: originalURL.href
};
}
;// CONCATENATED MODULE: ./node_modules/workbox-precaching/utils/PrecacheInstallReportPlugin.js
You can see service-worker.js in here: https://drive.google.com/file/d/13bESH2QRG-y_s5WyZjX51FjP-_kC8vmC/view?usp=sharing
UPDATE 2: It seems the URL object works differently in chrome 49 and 102. I added the following code manually to service-worker.js (inside the build directory) and I no longer receive the "Cannot read property of 'set' of undefined" error instead I get "ServiceWorker failed to install" and I have no clue why since there is no information provided.
var cacheKeyURL = new URL(url, location.href);
var originalURL = new URL(url, location.href);
//This Part
if (!cacheKeyURL['searchParams']){
var urlParams = new URLSearchParams(location.search);
cacheKeyURL.searchParams = urlParams;
}
cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);
By the way, How can I add "//This Part" to the original service-worker.js?
Can you please help me out?!
Thanks in advance
CodePudding user response:
The problem is URL
prototype and waitUntil()
In chrome 49
Add the following code to fix URL problem:
if (!URL.prototype.searchParams) {
URL.prototype.searchParams = new URLSearchParams();
}
Use async-wait-until to run waitUntil()
synchronously (instead of asynchronous)