Loading...
Loading...
Migrate a Grafana plugin to React 19 compatibility. Use when the user asks to update a plugin for React 19, prepare for React 19, fix React 19 compatibility, upgrade to React 19, migrate to React 19, bump grafanaDependency to 12.3.0, externalize jsx-runtime, or run react-detect. Triggers on phrases like "update plugin for React 19", "React 19 migration", "prepare for React 19", "plugin React 19 compat", "grafanaDependency 12.3.0", "JSX runtime externals", "react-detect", "SECRET_INTERNALS", "ReactCurrentOwner", or "ReactCurrentDispatcher".
npx skill4agent add grafana/skills react-19-plugin-migrationyarn.lockPLUGIN_JSON=$([ -f src/plugin.json ] && echo "src/plugin.json" \
|| ([ -f plugin/src/plugin.json ] && echo "plugin/src/plugin.json" || echo ""))
PKG_JSON=$([ -f package.json ] && echo "package.json" \
|| ([ -f plugin/package.json ] && echo "plugin/package.json" || echo ""))
PLUGIN_ID=$(jq -r '.id' $PLUGIN_JSON 2>/dev/null)
[ -f yarn.lock ] && PM="yarn" || ([ -f pnpm-lock.yaml ] && PM="pnpm" || PM="npm")
CP_VERSION=$(jq -r '.version' .config/.cprc.json 2>/dev/null)
echo "PLUGIN_ID=$PLUGIN_ID PM=$PM CP=$CP_VERSION"PLUGIN_IDnpm run build 2>&1 | tail -5
npx -y @grafana/react-detect@latest 2>&1jsxRuntimeImport__SECRET_INTERNALSdefaultPropspropTypesReactDOM.renderfindDOMNode@grafana/create-pluginadd externalize-jsx-runtimenpx @grafana/create-plugin@latest update 2>&1yarn installyarn install--ignore-enginesyarn install --ignore-scripts --ignore-engines 2>&1 | tail -10git add -A && git commit -m "chore: intermediate create-plugin update" --no-verify
npx @grafana/create-plugin@latest update 2>&1git add -A && git commit -m "chore: update create-plugin (ESLint 9 migration manual)" --no-verifyyarn install --ignore-scripts --ignore-engines 2>&1 | tail -10
cat .config/.cprc.jsongit add -A && git diff --cached --quiet || git commit -m "chore: update create-plugin scaffolding" --no-verifycreate-plugin updateeslint.config.js.eslintrcls eslint.config.js .eslintrc* .config/.eslintrc* 2>/dev/null
npx eslint --version 2>&1eslint.config.jsyarn linteslint.config.jsyarn lintyarn lint 2>&1 | head -30Invalid option '--ignore-path'Invalid option '--ext'lintpackage.jsoneslint.config.jseslint --cache .Cannot find module 'eslint-plugin-deprecation'eslint.config.js@typescript-eslint/no-deprecatedeslint.config.jsls node_modules/@grafana/eslint-config/flat.js 2>/dev/nullflat.jseslint.config.jsimport grafanaConfig from '@grafana/eslint-config/flat';
export default [
...grafanaConfig,
{
ignores: ['**/dist/', '**/node_modules/', '**/.config/', '**/coverage/'],
},
];.eslintrclint"lint": "eslint --cache .".eslintrc.config/.eslintrcyarn lint 2>&1 | tail -20yarn lint --fixgit add -A && git diff --cached --quiet || git commit -m "chore: complete ESLint 9 flat config migration" --no-verifycreate-plugin addnpx @grafana/create-plugin@latest add externalize-jsx-runtime 2>&1grep "jsx-runtime" .config/bundler/externals.ts 2>/dev/nullwebpack.config.tsexternals: ['react/jsx-runtime', 'react/jsx-dev-runtime'],git add -A && git diff --cached --quiet || git commit -m "feat: externalize jsx-runtime" --no-verifygrafanaDependencyjq -r '.dependencies.grafanaDependency' $PLUGIN_JSON>=12.3.0create-plugin addgrep '"@grafana/faro' $PKG_JSON| Package | Target |
|---|---|
| |
| |
| |
grep '"@grafana/' $PKG_JSON | grep -v faro | grep -v create-plugin@grafana/data@grafana/runtime@grafana/schema@grafana/ui^12.2.0@grafana/i18n@^12.2.0@grafana/scenesreactreact-dom^18.3.0@types/react@^18.3.0@types/react-dom@^18.3.0eslint-plugin-deprecation@typescript-eslint/no-deprecated@types/testing-library__jest-domsetupTests.d.tsyarn installresolutions"resolutions": {
"<package-name>": "<working-version-or-git-ref>"
}yarn.locknode_modulesrm -rf node_modules yarn.lock
yarn install --ignore-engines 2>&1 | tail -10@openfeature/web-sdk@grafana/runtime@openfeature/react-sdk@openfeature/web-sdkyarn --version 2>&1 | head -11.yarn install --ignore-engines 2>&1 | grep "unmet peer dependency.*openfeature/web-sdk"yarn add -D @openfeature/web-sdk @openfeature/core --ignore-enginesgrep -rn "ReactDOM\.render\|ReactDOM\.unmountComponentAtNode\|ReactDOM\.findDOMNode" src/ --include="*.tsx" --include="*.ts"
grep -rn "\.defaultProps\s*=" src/ --include="*.tsx" --include="*.ts"
grep -rn "\.propTypes\s*=" src/ --include="*.tsx" --include="*.ts"
grep -rn "contextTypes\|getChildContext" src/ --include="*.tsx" --include="*.ts"
grep -rn "createFactory" src/ --include="*.tsx" --include="*.ts"
grep -rn "ChangeEvent<HTMLInputElement>" src/ --include="*.tsx" --include="*.ts"| Pattern | Fix |
|---|---|
| |
| Move to destructured parameter defaults |
| Leave — still works |
| Remove |
| Use |
| Use JSX or |
| Change to |
rm -rf node_modules dist
yarn install --ignore-engines 2>&1 | tail -10
yarn build 2>&1 | tail -10
yarn typecheck 2>&1 | tail -10
yarn test --watchAll=false 2>&1 | tail -10| Error | Fix |
|---|---|
| Step 4 not applied — re-run |
| Step 7 — |
| |
| Bump |
| Add |
Stale git hash in | Add |
@grafana/schemagrep -rn "plugin-ci-workflows\|e2e-version" .github/workflows/ 2>/dev/nullplugin-ci-workflows@mainplugin-actions/e2e-versionskip-grafana-react-19-preview-image: falseGRAFANA_VERSION=dev-preview-react19 docker compose up --buildgit reset --soft origin/main
git add -A
git commit -m "fix: Prepare plugin for React 19 compatibility"