fix(frontend): resolve Vite assets by manifest source path (#37836)

In dev mode `/api/swagger` returned HTTP 500 (`Failed to locate local
path for managed asset URI: css/swagger.css`): the backend synthesised
asset keys from the Vite entry name instead of reading the manifest,
which only worked by coincidence and broke once a source file name
diverged from its entry name.

This keys the manifest by its source path (e.g. `web_src/js/index.ts`)
and resolves entries directly — hashed `file` in prod, dev-server source
in dev. A new `AssetCSSLinks` helper renders a JS entry's stylesheet
`<link>` tags from the manifest (the entry's CSS plus the CSS of its
statically-imported chunks).

Fixes: https://github.com/go-gitea/gitea/issues/37830
Fixes: https://github.com/go-gitea/gitea/pull/37832
Fixes: https://github.com/go-gitea/gitea/pull/37876
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: prakhar0x01 <prakharporwal2004@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Giteabot <teabot@gitea.io>
This commit is contained in:
silverwind
2026-05-28 08:14:52 +02:00
committed by GitHub
parent db04bcb31a
commit 52fef74291
15 changed files with 122 additions and 128 deletions

View File

@@ -9,7 +9,7 @@
</div>
{{template "custom/body_outer_post" .}}
{{template "base/footer_content" .}}
{{ctx.ScriptImport "js/index.js" "module"}}
{{ctx.ScriptImport "web_src/js/index.ts" "module"}}
{{template "custom/footer" .}}
<script nonce="{{ctx.CspScriptNonce}}" type="module">
if (!window.config?.frontendInited && window.config?.runModeIsProd) alert("Frontend is not initialized, check console errors or asset files.");

View File

@@ -16,7 +16,7 @@ If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly.
notificationSettings: {{NotificationSettings}}, {{/*a map provided by NewFuncMap in helper.go*/}}
enableTimeTracking: {{EnableTimetracking}},
mermaidMaxSourceCharacters: {{MermaidMaxSourceCharacters}},
sharedWorkerUri: '{{AssetURI "js/eventsource.sharedworker.js"}}',
sharedWorkerUri: '{{AssetURI "web_src/js/eventsource.sharedworker.ts"}}',
{{/* this global i18n object should only contain general texts. for specialized texts, it should be provided inside the related modules by: (1) API response (2) HTML data-attribute (3) PageData */}}
i18n: {
error_occurred: {{ctx.Locale.Tr "error.occurred"}},
@@ -31,4 +31,4 @@ If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly.
{{/* in case some pages don't render the pageData, we make sure it is an object to prevent null access */}}
window.config.pageData = window.config.pageData || {};
</script>
{{ctx.ScriptImport "js/iife.js"}}
{{ctx.ScriptImport "web_src/js/iife.ts"}}

View File

@@ -1,2 +1,2 @@
<link rel="stylesheet" href="{{AssetURI "css/index.css"}}">
{{AssetCSSLinks "web_src/js/index.ts" "web_src/css/index.css"}}
<link rel="stylesheet" href="{{ctx.CurrentWebTheme.PublicAssetURI}}">

View File

@@ -1,4 +1,4 @@
{{template "base/head" ctx.RootData}}
<link rel="stylesheet" href="{{AssetURI "css/devtest.css"}}">
<link rel="stylesheet" href="{{AssetURI "web_src/css/devtest.css"}}">
<div class="tw-hidden" data-global-init="initDevtestPage"></div>
<div class="ui container tw-mt-4">{{template "base/alert" ctx.RootData}}</div>

View File

@@ -4,14 +4,14 @@
{{ctx.HeadMetaContentSecurityPolicy}}
<title>Gitea API</title>
<link rel="stylesheet" href="{{ctx.CurrentWebTheme.PublicAssetURI}}">
{{/* HINT: SWAGGER-CSS-IMPORT: import swagger styles ahead to avoid UI flicker (e.g.: the swagger-back-link element) */}}
<link rel="stylesheet" href="{{AssetURI "css/swagger.css"}}">
{{/* HINT: SWAGGER-CSS-IMPORT: load swagger styles ahead to avoid flicker (e.g. the swagger-back-link) */}}
{{AssetCSSLinks "web_src/js/swagger.ts" "web_src/css/swagger-standalone.css"}}
</head>
<body>
{{/* TODO: add Help & Glossary to help users understand the API, and explain some concepts like "Owner" */}}
<a class="swagger-back-link" href="{{AppSubUrl}}/">{{svg "octicon-reply"}}{{ctx.Locale.Tr "return_to_gitea"}}</a>
<div id="swagger-ui" data-source="{{AppSubUrl}}/swagger.v1.json"></div>
<footer class="page-footer"></footer>
{{ctx.ScriptImport "js/swagger.js" "module"}}
{{ctx.ScriptImport "web_src/js/swagger.ts" "module"}}
</body>
</html>