Remove the service worker (#25010)

It's been disabled by default since 1.17
(https://github.com/go-gitea/gitea/pull/18914), and it never really
delivered any benefit except being another cache layer that has its own
unsolved invalidation issues. HTTP cache works, we don't need two cache
layers at the browser for assets.

## ⚠️ BREAKING

You can remove the config `[ui].USE_SERVICE_WORKER` from your `app.ini`
now.
pull/25012/head
silverwind 2 years ago committed by GitHub
parent 28a89e360f
commit 50bd7d0b24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .dockerignore
  2. 1
      .gitignore
  3. 1
      .ignore
  4. 2
      Makefile
  5. 3
      custom/conf/app.example.ini
  6. 1
      docs/content/doc/administration/config-cheat-sheet.en-us.md
  7. 2
      modules/setting/ui.go
  8. 3
      modules/templates/helper.go
  9. 23
      package-lock.json
  10. 2
      package.json
  11. 1
      templates/base/head_script.tmpl
  12. 57
      web_src/js/features/serviceworker.js
  13. 2
      web_src/js/index.js
  14. 23
      web_src/js/serviceworker.js
  15. 9
      webpack.config.js

@ -76,7 +76,6 @@ cpu.out
/yarn-error.log /yarn-error.log
/npm-debug.log* /npm-debug.log*
/public/js /public/js
/public/serviceworker.js
/public/css /public/css
/public/fonts /public/fonts
/public/img/webpack /public/img/webpack

1
.gitignore vendored

@ -77,7 +77,6 @@ cpu.out
/yarn-error.log /yarn-error.log
/npm-debug.log* /npm-debug.log*
/public/js /public/js
/public/serviceworker.js
/public/css /public/css
/public/fonts /public/fonts
/public/img/webpack /public/img/webpack

@ -1,5 +1,6 @@
*.min.css *.min.css
*.min.js *.min.js
/assets/*.json
/modules/options/bindata.go /modules/options/bindata.go
/modules/public/bindata.go /modules/public/bindata.go
/modules/templates/bindata.go /modules/templates/bindata.go

@ -114,7 +114,7 @@ FOMANTIC_WORK_DIR := web_src/fomantic
WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f) WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f)
WEBPACK_CONFIGS := webpack.config.js WEBPACK_CONFIGS := webpack.config.js
WEBPACK_DEST := public/js/index.js public/css/index.css WEBPACK_DEST := public/js/index.js public/css/index.css
WEBPACK_DEST_ENTRIES := public/js public/css public/fonts public/img/webpack public/serviceworker.js WEBPACK_DEST_ENTRIES := public/js public/css public/fonts public/img/webpack
BINDATA_DEST := modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.go BINDATA_DEST := modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.go
BINDATA_HASH := $(addsuffix .hash,$(BINDATA_DEST)) BINDATA_HASH := $(addsuffix .hash,$(BINDATA_DEST))

@ -1208,9 +1208,6 @@ LEVEL = Info
;; Whether to search within description at repository search on explore page. ;; Whether to search within description at repository search on explore page.
;SEARCH_REPO_DESCRIPTION = true ;SEARCH_REPO_DESCRIPTION = true
;; ;;
;; Whether to enable a Service Worker to cache frontend assets
;USE_SERVICE_WORKER = false
;;
;; Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used. ;; Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used.
;; A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic). ;; A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic).
;ONLY_SHOW_RELEVANT_REPOS = false ;ONLY_SHOW_RELEVANT_REPOS = false

@ -230,7 +230,6 @@ The following configuration set `Content-Type: application/vnd.android.package-a
add it to this config. add it to this config.
- `DEFAULT_SHOW_FULL_NAME`: **false**: Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used. - `DEFAULT_SHOW_FULL_NAME`: **false**: Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used.
- `SEARCH_REPO_DESCRIPTION`: **true**: Whether to search within description at repository search on explore page. - `SEARCH_REPO_DESCRIPTION`: **true**: Whether to search within description at repository search on explore page.
- `USE_SERVICE_WORKER`: **false**: Whether to enable a Service Worker to cache frontend assets.
- `ONLY_SHOW_RELEVANT_REPOS`: **false** Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used. - `ONLY_SHOW_RELEVANT_REPOS`: **false** Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used.
A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic). A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic).

@ -32,7 +32,6 @@ var UI = struct {
CustomEmojis []string CustomEmojis []string
CustomEmojisMap map[string]string `ini:"-"` CustomEmojisMap map[string]string `ini:"-"`
SearchRepoDescription bool SearchRepoDescription bool
UseServiceWorker bool
OnlyShowRelevantRepos bool OnlyShowRelevantRepos bool
Notification struct { Notification struct {
@ -136,7 +135,6 @@ func loadUIFrom(rootCfg ConfigProvider) {
UI.ShowUserEmail = sec.Key("SHOW_USER_EMAIL").MustBool(true) UI.ShowUserEmail = sec.Key("SHOW_USER_EMAIL").MustBool(true)
UI.DefaultShowFullName = sec.Key("DEFAULT_SHOW_FULL_NAME").MustBool(false) UI.DefaultShowFullName = sec.Key("DEFAULT_SHOW_FULL_NAME").MustBool(false)
UI.SearchRepoDescription = sec.Key("SEARCH_REPO_DESCRIPTION").MustBool(true) UI.SearchRepoDescription = sec.Key("SEARCH_REPO_DESCRIPTION").MustBool(true)
UI.UseServiceWorker = sec.Key("USE_SERVICE_WORKER").MustBool(false)
// OnlyShowRelevantRepos=false is important for many private/enterprise instances, // OnlyShowRelevantRepos=false is important for many private/enterprise instances,
// because many private repositories do not have "description/topic", users just want to search by their names. // because many private repositories do not have "description/topic", users just want to search by their names.

@ -127,9 +127,6 @@ func NewFuncMap() template.FuncMap {
"MetaKeywords": func() string { "MetaKeywords": func() string {
return setting.UI.Meta.Keywords return setting.UI.Meta.Keywords
}, },
"UseServiceWorker": func() bool {
return setting.UI.UseServiceWorker
},
"EnableTimetracking": func() bool { "EnableTimetracking": func() bool {
return setting.Service.EnableTimetracking return setting.Service.EnableTimetracking
}, },

23
package-lock.json generated

@ -51,8 +51,6 @@
"vue3-calendar-heatmap": "2.0.5", "vue3-calendar-heatmap": "2.0.5",
"webpack": "5.84.1", "webpack": "5.84.1",
"webpack-cli": "5.1.1", "webpack-cli": "5.1.1",
"workbox-routing": "6.6.0",
"workbox-strategies": "6.6.0",
"wrap-ansi": "8.1.0" "wrap-ansi": "8.1.0"
}, },
"devDependencies": { "devDependencies": {
@ -11045,27 +11043,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/workbox-core": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz",
"integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ=="
},
"node_modules/workbox-routing": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz",
"integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==",
"dependencies": {
"workbox-core": "6.6.0"
}
},
"node_modules/workbox-strategies": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz",
"integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==",
"dependencies": {
"workbox-core": "6.6.0"
}
},
"node_modules/wrap-ansi": { "node_modules/wrap-ansi": {
"version": "8.1.0", "version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",

@ -51,8 +51,6 @@
"vue3-calendar-heatmap": "2.0.5", "vue3-calendar-heatmap": "2.0.5",
"webpack": "5.84.1", "webpack": "5.84.1",
"webpack-cli": "5.1.1", "webpack-cli": "5.1.1",
"workbox-routing": "6.6.0",
"workbox-strategies": "6.6.0",
"wrap-ansi": "8.1.0" "wrap-ansi": "8.1.0"
}, },
"devDependencies": { "devDependencies": {

@ -12,7 +12,6 @@ If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly.
assetUrlPrefix: '{{AssetUrlPrefix}}', assetUrlPrefix: '{{AssetUrlPrefix}}',
runModeIsProd: {{.RunModeIsProd}}, runModeIsProd: {{.RunModeIsProd}},
customEmojis: {{CustomEmojis}}, customEmojis: {{CustomEmojis}},
useServiceWorker: {{UseServiceWorker}},
csrfToken: '{{.CsrfToken}}', csrfToken: '{{.CsrfToken}}',
pageData: {{.PageData}}, pageData: {{.PageData}},
notificationSettings: {{NotificationSettings}}, {{/*a map provided by NewFuncMap in helper.go*/}} notificationSettings: {{NotificationSettings}}, {{/*a map provided by NewFuncMap in helper.go*/}}

@ -1,57 +0,0 @@
import {joinPaths, parseUrl} from '../utils.js';
const {useServiceWorker, assetUrlPrefix, assetVersionEncoded} = window.config;
const cachePrefix = 'static-cache-v'; // actual version is set in the service worker script
const workerUrl = `${joinPaths(assetUrlPrefix, 'serviceworker.js')}?v=${assetVersionEncoded}`;
async function unregisterAll() {
for (const registration of await navigator.serviceWorker.getRegistrations()) {
if (registration.active) await registration.unregister();
}
}
async function unregisterOtherWorkers() {
for (const registration of await navigator.serviceWorker.getRegistrations()) {
const scriptPath = parseUrl(registration.active?.scriptURL || '').pathname;
const workerPath = parseUrl(workerUrl).pathname;
if (scriptPath !== workerPath) await registration.unregister();
}
}
async function invalidateCache() {
for (const key of await caches.keys()) {
if (key.startsWith(cachePrefix)) caches.delete(key);
}
}
async function checkCacheValidity() {
const cacheKey = assetVersionEncoded;
const storedCacheKey = localStorage.getItem('staticCacheKey');
// invalidate cache if it belongs to a different gitea version
if (cacheKey && storedCacheKey !== cacheKey) {
await invalidateCache();
localStorage.setItem('staticCacheKey', cacheKey);
}
}
export async function initServiceWorker() {
if (!('serviceWorker' in navigator)) return;
if (useServiceWorker) {
// unregister all service workers where scriptURL does not match the current one
await unregisterOtherWorkers();
try {
// the spec strictly requires it to be same-origin so the AssetUrlPrefix should contain AppSubUrl
await checkCacheValidity();
await navigator.serviceWorker.register(workerUrl);
} catch (err) {
console.error(err);
await invalidateCache();
await unregisterAll();
}
} else {
await invalidateCache();
await unregisterAll();
}
}

@ -11,7 +11,6 @@ import {initHeatmap} from './features/heatmap.js';
import {initImageDiff} from './features/imagediff.js'; import {initImageDiff} from './features/imagediff.js';
import {initRepoMigration} from './features/repo-migration.js'; import {initRepoMigration} from './features/repo-migration.js';
import {initRepoProject} from './features/repo-projects.js'; import {initRepoProject} from './features/repo-projects.js';
import {initServiceWorker} from './features/serviceworker.js';
import {initTableSort} from './features/tablesort.js'; import {initTableSort} from './features/tablesort.js';
import {initAdminUserListSearchForm} from './features/admin/users.js'; import {initAdminUserListSearchForm} from './features/admin/users.js';
import {initAdminConfigs} from './features/admin/config.js'; import {initAdminConfigs} from './features/admin/config.js';
@ -116,7 +115,6 @@ onDomReady(() => {
initImageDiff(); initImageDiff();
initMarkupAnchors(); initMarkupAnchors();
initMarkupContent(); initMarkupContent();
initServiceWorker();
initSshKeyFormParser(); initSshKeyFormParser();
initStopwatch(); initStopwatch();
initTableSort(); initTableSort();

@ -1,23 +0,0 @@
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
const cacheName = 'static-cache-v2';
// disable workbox debug logging in development, remove when debugging the service worker
self.__WB_DISABLE_DEV_LOGS = true;
// see https://developer.mozilla.org/en-US/docs/Web/API/RequestDestination for possible values
const cachedDestinations = new Set([
'font',
'manifest',
'paintworklet',
'script',
'sharedworker',
'style',
'worker',
]);
registerRoute(
({request}) => cachedDestinations.has(request.destination),
new StaleWhileRevalidate({cacheName}),
);

@ -62,9 +62,6 @@ export default {
fileURLToPath(new URL('web_src/js/standalone/swagger.js', import.meta.url)), fileURLToPath(new URL('web_src/js/standalone/swagger.js', import.meta.url)),
fileURLToPath(new URL('web_src/css/standalone/swagger.css', import.meta.url)), fileURLToPath(new URL('web_src/css/standalone/swagger.css', import.meta.url)),
], ],
serviceworker: [
fileURLToPath(new URL('web_src/js/serviceworker.js', import.meta.url)),
],
'eventsource.sharedworker': [ 'eventsource.sharedworker': [
fileURLToPath(new URL('web_src/js/features/eventsource.sharedworker.js', import.meta.url)), fileURLToPath(new URL('web_src/js/features/eventsource.sharedworker.js', import.meta.url)),
], ],
@ -73,11 +70,7 @@ export default {
devtool: false, devtool: false,
output: { output: {
path: fileURLToPath(new URL('public', import.meta.url)), path: fileURLToPath(new URL('public', import.meta.url)),
filename: ({chunk}) => { filename: () => 'js/[name].js',
// serviceworker can only manage assets below it's script's directory so
// we have to put it in / instead of /js/
return chunk.name === 'serviceworker' ? '[name].js' : 'js/[name].js';
},
chunkFilename: ({chunk}) => { chunkFilename: ({chunk}) => {
const language = (/monaco.*languages?_.+?_(.+?)_/.exec(chunk.id) || [])[1]; const language = (/monaco.*languages?_.+?_(.+?)_/.exec(chunk.id) || [])[1];
return `js/${language ? `monaco-language-${language.toLowerCase()}` : `[name]`}.[contenthash:8].js`; return `js/${language ? `monaco-language-${language.toLowerCase()}` : `[name]`}.[contenthash:8].js`;

Loading…
Cancel
Save