-
Notifications
You must be signed in to change notification settings - Fork 4
pass custom container to mount mfe app #218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: coderabbit_micro_frontend
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,7 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useState, useEffect, FC, PropsWithChildren } from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import createCache from '@emotion/cache'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { cache as emotionCssCache } from '@emotion/css'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { CacheProvider } from '@emotion/react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useState, useEffect, FC, PropsWithChildren, useMemo } from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Provider } from 'react-redux'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { BrowserRouter } from 'react-router-dom'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Store } from 'redux'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -18,11 +21,32 @@ import app from '../fn_app'; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { FNDashboardProps } from './types'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type FnAppProviderProps = Pick<FNDashboardProps, 'fnError'> & { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| container?: FNDashboardProps['container']; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| store: Store<StoreState>; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const FnAppProvider: FC<PropsWithChildren<FnAppProviderProps>> = (props) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { children } = props; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const emotionCache = useMemo( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const container = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| props.container instanceof Document ? props.container.head : props.container || document.head; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| emotionCssCache.sheet.container = container; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| emotionCssCache.sheet.tags.forEach((tag) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (tag.parentNode !== container) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| container.appendChild(tag); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return createCache({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key: 'grafana-mf', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| container, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [props.container] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+30
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mutating the shared global Emotion cache inside
Keep ♻️ Suggested direction- const emotionCache = useMemo(
- () => {
- const container =
- props.container instanceof Document ? props.container.head : props.container || document.head;
-
- emotionCssCache.sheet.container = container;
- emotionCssCache.sheet.tags.forEach((tag) => {
- if (tag.parentNode !== container) {
- container.appendChild(tag);
- }
- });
-
- return createCache({
- key: 'grafana-mf',
- container,
- });
- },
- [props.container]
- );
+ const container = useMemo(
+ () => (props.container instanceof Document ? props.container.head : props.container || document.head),
+ [props.container]
+ );
+ const emotionCache = useMemo(() => createCache({ key: 'grafana-mf', container }), [container]);
+
+ useEffect(() => {
+ // Re-parent existing `@emotion/css` tags into the scoped container.
+ // NOTE: this still touches a shared global cache; verify it is safe when
+ // multiple dashboards (shadow roots) are mounted simultaneously.
+ emotionCssCache.sheet.container = container;
+ emotionCssCache.sheet.tags.forEach((tag) => {
+ if (tag.parentNode !== container) {
+ container.appendChild(tag);
+ }
+ });
+ }, [container]);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const themeHref = config.bootData.themePaths[config.theme2.colors.mode]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [ready, setReady] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| navigationLogger('AppWrapper', false, 'rendering'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -40,19 +64,22 @@ export const FnAppProvider: FC<PropsWithChildren<FnAppProviderProps>> = (props) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Provider store={props.store}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <BrowserRouter> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <ErrorBoundaryAlert style="page"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <GrafanaContext.Provider value={app.context}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <ThemeProvider value={config.theme2}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div data-grafana-mf-root> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <GlobalStyles prefix="[data-grafana-mf-root]" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {children} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </ThemeProvider> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </GrafanaContext.Provider> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </ErrorBoundaryAlert> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </BrowserRouter> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Provider> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <CacheProvider value={emotionCache}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <link rel="stylesheet" href={themeHref} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Provider store={props.store}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <BrowserRouter> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <ErrorBoundaryAlert style="page"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <GrafanaContext.Provider value={app.context}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <ThemeProvider value={config.theme2}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div data-grafana-mf-root> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <GlobalStyles prefix="[data-grafana-mf-root]" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {children} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </ThemeProvider> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </GrafanaContext.Provider> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </ErrorBoundaryAlert> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </BrowserRouter> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Provider> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </CacheProvider> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,22 @@ | ||
| import { Portal } from '@mui/material'; | ||
| import { FC, PropsWithChildren } from 'react'; | ||
| import { FC, ReactNode } from 'react'; | ||
| import { createPortal } from 'react-dom'; | ||
|
|
||
| import { MfeContainer } from './types'; | ||
|
|
||
| export interface RenderPortalProps { | ||
| ID: string; | ||
| children: ReactNode | ((container: MfeContainer) => ReactNode); | ||
| } | ||
|
|
||
| export const RenderPortal: FC<PropsWithChildren<RenderPortalProps>> = ({ ID, children }) => { | ||
| export const RenderPortal: FC<RenderPortalProps> = ({ ID, children }) => { | ||
| const container = document.getElementById(ID); | ||
|
|
||
| if (!container) { | ||
| return null; | ||
| } | ||
|
|
||
| return <Portal container={container}>{children}</Portal>; | ||
| const shadowRoot = container.shadowRoot || container.attachShadow({ mode: 'open' }); | ||
| const content = typeof children === 'function' ? children(shadowRoot) : children; | ||
|
|
||
| return createPortal(content, shadowRoot); | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,25 @@ | ||
| <!doctype html><html lang="en"><head><title>CodeRabbit Micro-frontend</title><base href="/"/></head><body class="theme-light app-grafana"><div id="grafanaRoot"></div><script nonce="">window.fnData = { | ||
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <title>CodeRabbit Micro-frontend</title> | ||
| <base href="/" /> | ||
| </head> | ||
|
|
||
| <body class="theme-light app-grafana"> | ||
| <div id="grafanaRoot"></div> | ||
| <script nonce=""> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Empty nonce attribute defeats CSP protection. The Either populate the nonce with a cryptographically random value generated server-side, or remove the attribute if CSP is not being used. 🤖 Prompt for AI Agents |
||
| window.fnData = { | ||
| themePaths: { | ||
| light: '../../../public/build/grafana.light.d120ca3c6b86113973bc.css', | ||
| dark: '../../../public/build/grafana.dark.f4571afb90da68f52521.css', | ||
| light: '../../../public/build/grafana.light.65904cef23d9f7f76c4a.css', | ||
| dark: '../../../public/build/grafana.dark.7c4d93ecbdd92098eb9a.css', | ||
|
Comment on lines
+13
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Description: Check if the hashed CSS files referenced in the HTML exist
# Expected CSS files based on the HTML
LIGHT_CSS="public/build/grafana.light.65904cef23d9f7f76c4a.css"
DARK_CSS="public/build/grafana.dark.7c4d93ecbdd92098eb9a.css"
echo "Checking for CSS files..."
if [ -f "$LIGHT_CSS" ]; then
echo "✓ Found: $LIGHT_CSS"
else
echo "✗ Missing: $LIGHT_CSS"
fi
if [ -f "$DARK_CSS" ]; then
echo "✓ Found: $DARK_CSS"
else
echo "✗ Missing: $DARK_CSS"
fi
# Also search for any grafana theme CSS files to see what actually exists
echo -e "\nAll Grafana theme CSS files in public/build/:"
fd -e css 'grafana\.(light|dark)\.' public/build/ --exec echo "{}"Repository: coderabbitai/grafana Length of output: 381 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== Inspect index.html base + themePaths snippet =="
nl -ba public/microfrontends/fn_dashboard/index.html | sed -n '1,80p'
echo
echo "== Locate referenced hashed CSS files anywhere in repo =="
LIGHT_REF="grafana.light.65904cef23d9f7f76c4a.css"
DARK_REF="grafana.dark.7c4d93ecbdd92098eb9a.css"
echo "Searching for: $LIGHT_REF"
rg -n --hidden --no-ignore -S "$LIGHT_REF" . || true
echo "Searching for: $DARK_REF"
rg -n --hidden --no-ignore -S "$DARK_REF" . || true
echo
echo "== List any grafana.light.* and grafana.dark.* CSS files in repo =="
fd -e css "grafana\.(light|dark)\..*" . || true
echo
echo "== Check for common build output dirs (existence only) =="
for d in public/build build public/dist public/assets dist assets; do
if [ -d "$d" ]; then echo "Found dir: $d"; else echo "Missing dir: $d"; fi
doneRepository: coderabbitai/grafana Length of output: 176 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== Inspect index.html base + themePaths snippet =="
awk '{printf "%5d %s\n", NR, $0}' public/microfrontends/fn_dashboard/index.html | sed -n '1,120p'
echo
echo "== Locate referenced hashed CSS files anywhere in repo =="
LIGHT_REF="grafana.light.65904cef23d9f7f76c4a.css"
DARK_REF="grafana.dark.7c4d93ecbdd92098eb9a.css"
echo "Searching for: $LIGHT_REF"
rg -n --hidden --no-ignore -S "$LIGHT_REF" . || true
echo "Searching for: $DARK_REF"
rg -n --hidden --no-ignore -S "$DARK_REF" . || true
echo
echo "== List any grafana.light.* and grafana.dark.* CSS files in repo =="
fd -e css "grafana\.(light|dark)\..*" . || true
echo
echo "== Check for common build output dirs (existence only) =="
for d in public/build public/dist public/assets build dist assets; do
if [ -d "$d" ]; then echo "Found dir: $d"; else echo "Missing dir: $d"; fi
doneRepository: coderabbitai/grafana Length of output: 1680 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== Check whether referenced build JS files exist =="
RUNTIME="public/build/runtime~fn_dashboard.a5d060ef4f8cb38ef003.js"
BUNDLE="public/build/fn_dashboard.61924fc7a748b4f2ecc3.js"
for f in "$RUNTIME" "$BUNDLE"; do
if [ -f "$f" ]; then
echo "✓ Found: $f"
else
echo "✗ Missing: $f"
fi
doneRepository: coderabbitai/grafana Length of output: 246 🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n --hidden --no-ignore -S "runtime~fn_dashboard\.a5d060ef4f8cb38ef003\.js" . || true
rg -n --hidden --no-ignore -S "fn_dashboard\.61924fc7a748b4f2ecc3\.js" . || true
rg -n --hidden --no-ignore -S "grafana\.(light|dark)\." public/microfrontends/fn_dashboard/index.html || true
ls -la public || true
ls -la public/microfrontends/fn_dashboard || trueRepository: coderabbitai/grafana Length of output: 2017 Fix asset URLs: referenced hashed CSS/JS under
🤖 Prompt for AI Agents |
||
| } | ||
| };</script><script nonce="" src="../../../public/build/runtime.6bc90f2808f6a6cec604.js" integrity="../../../sha384-3As+cCSgxk8iweHxuF0ngRBgr9/ctzbHdj+SGyxLEsEcj6HkIQ9CSdeyXHvbZWHz" crossorigin="anonymous"></script><script nonce="" src="../../../public/build/6029.5c0893d1623856e7b325.js" integrity="../../../sha384-LCMBgpyynxT2jXlhS9LdLRKvKFwONDIYBW6yP4ZgNSZo7VxpgMGsUdspsX7oCvt5" crossorigin="anonymous"></script><script nonce="" src="../../../public/build/5234.b70fab3b1fc48a116b38.js" integrity="../../../sha384-6z/x7G0Kuq5vHq8SixVqItA9g2cqD1Tw4nVd8f947akcoV/Y/8suL1cymdz83GDW" crossorigin="anonymous"></script><script nonce="" src="../../../public/build/4159.2474818cd0a590b4b852.js" integrity="../../../sha384-mDVs9x2bqCV4KOdzAVdPIhNhftT6jp5rgT4z0W2PFICSgYO9WspVQ1NZEZ9uopBj" crossorigin="anonymous"></script><script nonce="" src="../../../public/build/2410.606a87b065106e81ad31.js" integrity="../../../sha384-BFVRm68sCi1AfvPOncSziFN0wyR9pFWDILKADQNXW3osulVTaKUFvv6PVohbLlgE" crossorigin="anonymous"></script><script nonce="" src="../../../public/build/9569.5956dfdd4b3fdd6a93a6.js" integrity="../../../sha384-Rt0UcbPtFvyQunoSipLsiTe0QFnqPd8+C9P4dKme0l0oWhfMRdjHufKTF4GjR4GN" crossorigin="anonymous"></script><script nonce="" src="../../../public/build/6263.c2ee3ac2fe2934607fe0.js" integrity="../../../sha384-2VdfTyu5FomdOEQn4OvRVDRX1C8TWJAVA9tPJlRoPq0FvWM+KhrzCtq6HNg2m9Fe" crossorigin="anonymous"></script><script nonce="" src="../../../public/build/6947.6fa9ff70b916365b6259.js" integrity="../../../sha384-IbuK21HpudeblOqkfNJfp6wvrHVlhxcd2s830P75awAlEiCS5pLngZ18qg0S0K/W" crossorigin="anonymous"></script><script nonce="" src="../../../public/build/4894.89be4a92855ef9eb683b.js" integrity="../../../sha384-EoWaAzRvJN8kNdv/uj04uulL4FoocvQgg0+KIIlTi+FoNCAZHcxAj/pJ57FZi3qK" crossorigin="anonymous"></script><script nonce="" src="../../../public/build/530.1c5ae442b33495c705a5.js" integrity="../../../sha384-Cv4HLe8qompnosQrBeW5214V6jyT5fWyYce0wl/H6F0e0VdI+icvpGcLUrnCqnHs" crossorigin="anonymous"></script><script nonce="" src="../../../public/build/7223.d145fd99105c51a27905.js" integrity="../../../sha384-Ps7r+bS4dMRkHGzfn2hbwrLuPvsBrvH0BxwjA44TkTUo2u4JVwTRyvlT1EV+XtyH" crossorigin="anonymous"></script><script nonce="" src="../../../public/build/280.04d501de6deac449c563.js" integrity="../../../sha384-ET/a2+qGxnfC4uCd8wYZrOjvnkYk7ZgeNwly0P/UoiogdLNhIftTGwFXRLqKEh5O" crossorigin="anonymous"></script><script nonce="" src="../../../public/build/fn_dashboard.3b27ec7a6c915d13b983.js" integrity="../../../sha384-y5RXL2jFR/Tl6RXV1RQMqZI3kbEq6s8y6SZGjZvxKC9I2eQAbvbRrV20qIZlS8Mg" crossorigin="anonymous"></script></body></html> | ||
| }; | ||
| </script> | ||
|
|
||
|
|
||
| <script nonce="" src="../../../public/build/runtime~fn_dashboard.a5d060ef4f8cb38ef003.js" type="text/javascript"></script> | ||
|
|
||
| <script nonce="" src="../../../public/build/fn_dashboard.61924fc7a748b4f2ecc3.js" type="text/javascript"></script> | ||
|
Comment on lines
+20
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Empty nonce attributes and missing integrity protection. These script tags have two security issues:
Recommended fixes:
🔒 Example with SRI attributes- <script nonce="" src="../../../public/build/runtime~fn_dashboard.a5d060ef4f8cb38ef003.js" type="text/javascript"></script>
+ <script nonce="{SERVER_GENERATED_NONCE}" src="../../../public/build/runtime~fn_dashboard.a5d060ef4f8cb38ef003.js" type="text/javascript" integrity="sha384-{HASH}" crossorigin="anonymous"></script>
- <script nonce="" src="../../../public/build/fn_dashboard.61924fc7a748b4f2ecc3.js" type="text/javascript"></script>
+ <script nonce="{SERVER_GENERATED_NONCE}" src="../../../public/build/fn_dashboard.61924fc7a748b4f2ecc3.js" type="text/javascript" integrity="sha384-{HASH}" crossorigin="anonymous"></script>Note: Generate integrity hashes using: 🤖 Prompt for AI Agents🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Description: Check if the hashed JS bundles referenced in the HTML exist
# Expected JS files based on the HTML
RUNTIME_JS="public/build/runtime~fn_dashboard.a5d060ef4f8cb38ef003.js"
MAIN_JS="public/build/fn_dashboard.61924fc7a748b4f2ecc3.js"
echo "Checking for JS bundles..."
if [ -f "$RUNTIME_JS" ]; then
echo "✓ Found: $RUNTIME_JS"
else
echo "✗ Missing: $RUNTIME_JS"
fi
if [ -f "$MAIN_JS" ]; then
echo "✓ Found: $MAIN_JS"
else
echo "✗ Missing: $MAIN_JS"
fi
# Also search for any fn_dashboard JS files to see what actually exists
echo -e "\nAll fn_dashboard JS files in public/build/:"
fd -e js 'fn_dashboard' public/build/ --exec echo "{}"Repository: coderabbitai/grafana Length of output: 385 🏁 Script executed: #!/bin/bash
set -euo pipefail
# 1) Locate the expected hashed bundle filenames anywhere in the repo
echo "Searching for exact hashed bundle filenames..."
rg -n --hidden --no-ignore-vcs -S "runtime~fn_dashboard\.a5d060ef4f8cb38ef003\.js|fn_dashboard\.61924fc7a748b4f2ecc3\.js" . || true
echo
echo "Finding files by name (may take a moment)..."
find . -type f \( -name 'runtime~fn_dashboard.a5d060ef4f8cb38ef003.js' -o -name 'fn_dashboard.61924fc7a748b4f2ecc3.js' \) -print || true
echo
# 2) Check whether a public/build directory exists anywhere under repo
echo "Checking for build output directories..."
find . -type d -path "*/public/build" -print || true
find . -type d -name build -maxdepth 4 -print || true
echo
# 3) Show the relevant section of the HTML for base href and script tags
echo "---- public/microfrontends/fn_dashboard/index.html (relevant section) ----"
nl -ba public/microfrontends/fn_dashboard/index.html | sed -n '1,120p'Repository: coderabbitai/grafana Length of output: 713 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "1) Does any fn_dashboard JS exist anywhere?"
find . -type f \( -name '*fn_dashboard*js' -o -name '*runtime~fn_dashboard*js' \) -print || true
echo
echo "2) What JS files exist under pkg/build and scripts/build (limited by fn_dashboard keywords)?"
for d in ./pkg/build ./scripts/build; do
if [ -d "$d" ]; then
echo "-- $d --"
find "$d" -type f -name '*fn_dashboard*js' -print || true
find "$d" -type f -name '*runtime*fn_dashboard*js' -print || true
fi
done
echo
echo "3) Reprint public/microfrontends/fn_dashboard/index.html lines 1-60 (no nl)."
sed -n '1,80p' public/microfrontends/fn_dashboard/index.htmlRepository: coderabbitai/grafana Length of output: 1027 Fix: referenced hashed fn_dashboard JS bundles aren’t present at /public/build
🤖 Prompt for AI Agents |
||
|
|
||
| </body> | ||
| </html> | ||
Uh oh!
There was an error while loading. Please reload this page.