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%20worker
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?!
I'm little late to answer, But I would like to extend accepted @M.H.'s answer
From the mozilla-docs It states
If a browser doesn't yet support the
URL() constructor
, you can access a URL object using the Window interface's URL property. Be sure to check to see if any of your target browsers require this to be prefixed.
And you are accesing the searchParams
as <URL_instance>['searchParams']
. This doesn't work on all scenarios, this works only when you have key , value
pair.
So it is preferred to use the .
dot operator.
Further from docs:
Change your following code which fetches using key
if (!cacheKeyURL['searchParams']){ 👈 instead of using the instance variable
var urlParams = new URLSearchParams(location.search);
cacheKeyURL.searchParams = urlParams;
}
to use dot
operator
if (!URL.prototype.searchParams) { 👈 try to access using prototype
URL.prototype.searchParams = new URLSearchParams();
}
Hope it helps and adds more value to the accepted answer.