Repository navigation
Package all js libs - #5481
Package all js libs#5481
Conversation
45c9400 to
8faa479
Compare
| window.htmxConfig.inlineScriptNonce = "{{ csp_nonce(request) }}"; | ||
| </script> | ||
| <script defer src="{{ root_path }}/static/{{ bundle_js }}"></script> | ||
| <script type="module" src="{{ root_path }}/static/{{ bundle_js }}"></script> |
There was a problem hiding this comment.
Since this PR removes the vendored asset download/build path, I think the ui_airgapped branch here may need to be updated too. It still references /static/vendor/..., so offline mode appears to depend on files that is no longer produced.
There was a problem hiding this comment.
Could you also update the packages in this PR? Please?
npm update
npm audit
npm audit fix
2762e0b to
035aaec
Compare
032b0a4 to
39a1823
Compare
marekdano
left a comment
There was a problem hiding this comment.
A few findings:
Blocking
1. The bundled CSS (Font Awesome + CodeMirror) never gets linked into the page. admin.js now imports the vendor CSS (import 'codemirror/lib/codemirror.css', import '@fortawesome/.../all.min.css', etc.), and Vite does emit it — but only as separate files that the entry is expected to <link> from HTML. After npm run vite:build, the manifest looks like:
"mcpgateway/admin_ui/index.js": {
"isEntry": true,
"file": "bundle-3LZTBtVw.js",
"css": ["assets/index-RTp56Tkr.css"] // contains Font Awesome
}get_bundle_js_filename() (admin.py) reads only ["file"], so assets/index-*.css and assets/vendor-editor-*.css (the latter holds the .CodeMirror rules) are emitted but never referenced by any template or auto-injected by the bundle. In practice that means CodeMirror editors render unstyled and Font Awesome doesn't load. Would it work to have the manifest reader also return the entry's css array and emit a <link> for each?
2. The vendor/fontawesome path the templates still point at is no longer produced.
admin.html, login.html, and change-password-required.html all keep <link ... href=".../static/vendor/fontawesome/css/all.min.css">, but download-cdn-assets.sh and its Containerfile step are removed and static/vendor/ isn't committed, so that URL 404s. This is the same thing @madhu-mohan-jaishankar flagged. It hits login.html / change-password-required.html hardest since they don't load the JS bundle at all — even once #1 is fixed, those two pages have no Font Awesome source. Might be worth linking the Vite-emitted CSS on those pages too, or otherwise giving them a real path.
Suggestions
3. The lazy-loading currently doesn't split anything. The build reports:
[INEFFECTIVE_DYNAMIC_IMPORT] tools.js/servers.js/gateways.js/teams.js/llmChat.js/ logging.js/metrics.js/plugins.js is dynamically imported by lazy-loader.js but also statically imported by admin.js — dynamic import will not move module into another chunk.
Because admin.js still statically imports these modules, Rollup keeps them in the eager graph, so the tab-click loader + loading indicators don't actually defer anything yet. Similarly, chunk-vendor-charts (~200 KB) is pulled in eagerly via the top-level import { Chart } in admin.js, so Chart.js now loads for non-admins too (it used to be gated behind {% if is_admin %}). If deferral is a goal here, the static import chains into these modules would need to be broken first.
4. CSP still allowlists CDNs that are no longer used. Now that nothing loads from cdnjs/jsdelivr/unpkg, security_headers.py (script-src-elem, style-src, font-src) could drop those origins as a nice follow-up hardening. Not blocking.
5. A couple of test gaps. The tabs.test.js update mocks loadFeature to resolve instantly, so lazy-loader.js itself (dedup, in-flight coalescing, the error path) and the loading-indicator show/hide aren't exercised. A small unit test for the loader would be a good add.
ed51d5f to
5bb9b8f
Compare
marekdano
left a comment
There was a problem hiding this comment.
Just two more findings
- Lazy-loading is a no-op — every "lazy" chunk still loads on initial page load
mcpgateway/admin_ui/admin.js
admin.js (the eagerly-evaluated entry) statically imports gateways.js (L188), llmModels.js (L228), logging.js (L278), plugins.js (L342), servers.js (L427), teams.js (L459), and tools.js (L505). Because these are static imports of the entry, Vite emits them as static import statements in bundle-*.js, so the browser fetches and evaluates all of those chunks during initial load — loadFeature() at tab-click time just re-resolves already-loaded modules.
metrics.js and llmChat.js (the only two not imported by name) are grouped by manualChunks into the monitoring chunk (with statically-imported logging.js) and the llm chunk (with statically-imported llmModels.js), so those chunks load eagerly too.
Net effect: the initial payload isn't reduced, and lazy-loader.js, TAB_FEATURE_MAP, the loading-indicator UI, and the await loadFeature(...) path in showTab add complexity and startup cost while deferring nothing. To make lazy-loading real, remove the static feature imports (and their window.Admin.* assignments) from admin.js; otherwise drop the lazy machinery and reword the PR description.
- Air-gapped docs point at build paths that don't exist
docs/docs/overview/ui.md,docs/docs/deployment/container.md
ui.md states all three container builds "include the Vite-built Admin UI assets via the frontend-builder stage," and container.md says to "Use Containerfile.lite which automatically downloads remaining vendor assets during build." At the PR head, only Containerfile has a frontend-builder stage and copies static/; Containerfile.lite and Containerfile.scratch reference neither frontend-builder, the built static dir, nor any vendor download (and download-cdn-assets.sh is deleted in this PR). A user following the air-gapped guidance with Containerfile.lite/.scratch gets a build with no bundled Admin UI assets. Correct the doc claims to match what those Containerfiles actually do.
| window.DOMPurify = DOMPurify; | ||
|
|
||
| // Import Font Awesome CSS | ||
| import '@fortawesome/fontawesome-free/css/all.min.css'; |
There was a problem hiding this comment.
The PR imports CodeMirror CSS, CodeMirror theme CSS, and Font Awesome CSS from admin.js, which means Vite emits CSS files separately and records them in the manifest. However, the backend still only returns a single JS filename via get_bundle_js_filename(), and the template only injects the JS bundle. There is no corresponding generation for manifest[entry].css.
Suggested fix: Replace the single “bundle filename” helper with a manifest helper that returns both:
- entry JS file
2.entry CSS files
Then render:
admin.html
{% for css_file in bundle_css %}
<link rel="stylesheet" href="{{ root_path }}/static/{{ css_file }}">
{% endfor %}
<script type="module" src="{{ root_path }}/static/{{ bundle_js }}"></script>
Also ensure the fallback path handles assets/*.css if the manifest is missing.
c9438b0 to
936515f
Compare
marekdano
left a comment
There was a problem hiding this comment.
The PR looks good!
LGTM 🚀
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
db029c9 to
89e25c3
Compare
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
Pull Request
🔗 Related Issue
Closes https://github.ibm.com/contextforge-org/internal_issues/issues/387
📝 Summary
Packages all JS packages, and then chunks the package to prevent a massive bundle.
📏 Reviewability
triage🏷️ Type of Change
🧪 Verification
Run
make build-ui devthen test the app on localhost. Make sure there are no errors on the browser console.make lintmake testmake coverage✅ Checklist
make black isort pre-commit)