DanInProgress opened a new issue, #56169:
URL: https://github.com/apache/airflow/issues/56169
### Apache Airflow version
3.1.0
### If "Other Airflow 2 version" selected, which one?
_No response_
### What happened?
Hi! I was reviewing the experimental react_app loading functionality while
poking at the new release with some colleagues, and I might? have spotted a
minor issue.
Looking at the plugin loading pattern, it appears that plugin authors are
asked to assign their exports to `globalThis.AirflowPlugin`. Could an
incorrectly bundled or empty plugin bundle inadvertently reuse the export of a
prior plugin bundle?
*Note*: I haven't had time to create a minimal reproduction yet, and I'm
still getting familiar with the code/bundling patterns used, so this might be
completely off-base.
### What you think should happen instead?
Maybe we could set `globalThis.AirflowPlugin` to `undefined` somewhere
pre-import or post-assignment? (Minimial changeset, avoid this issue, identical
plugin api)
I know this is literally brand new, and still experimental, so my focus is
on confusion during prototyping/debugging and not on isolation between plugins.
I'm sure there are many changes to come.
### How to reproduce
Planned reproduction steps:
1. Create a minimal `PluginA` with proper UMD bundle that exports to
`globalThis.AirflowPlugin`
2. Create a minimal `PluginB` with malformed/empty UMD bundle that does not
set `globalThis.AirflowPlugin`
3. Attempt to load `PluginA` and then `PluginB`
4. Check the value of `window['PluginB']`
### Operating System
TODO: update post-reproduction
### Versions of Apache Airflow Providers
_No response_
### Deployment
Other
### Deployment details
TODO: update post-reproduction
### Anything else?
Thanks for your time, and sorry if this turns out to be noise! Just wanted
to get this written down while it was fresh in my mind so I could come back to
it on monday.
**Feel free to close or move to discussions if you think it's more
appropriate.**
## Investigation notes
```typescript
// Line ~40: Import bundle
import(/* @vite-ignore */ reactApp.bundle_url)
.then(() => {
// Line ~44: Check if plugin already cached
let pluginComponent = globalThis[reactApp.name];
// Line ~47: If not cached, grab from shared global
if (pluginComponent === undefined) {
pluginComponent = globalThis.AirflowPlugin; // ← ISSUE: could this be
stale?
globalThis[reactApp.name] = pluginComponent;
}
// Line ~51: Validate and return
if (typeof pluginComponent !== "function") {
throw new TypeError(`Expected function, got ${typeof
pluginComponent}`);
}
return { default: pluginComponent };
})
Code references:
- dev/react-plugin-tools/react_plugin_template/
-
[src/main.tsx](https://github.com/apache/airflow/blob/e1bea44197d0b86953e6744f78e6238712f56860/dev/react-plugin-tools/react_plugin_template/src/main.tsx#L45)
- `export default PluginComponent`
-
[vite.config.ts](https://github.com/apache/airflow/blob/e1bea44197d0b86953e6744f78e6238712f56860/dev/react-plugin-tools/react_plugin_template/vite.config.ts#L35-L38)
- entry: src/main.tsx , format: umd, name: AirflowPlugin
- airflow-core/src/airflow/ui/
-
[src/pages/ReactPlugin.tsx](https://github.com/apache/airflow/blob/e1bea44197d0b86953e6744f78e6238712f56860/airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx#L38-L52)
- loading logic
### Are you willing to submit PR?
- [x] Yes I am willing to submit a PR!
### Code of Conduct
- [x] I agree to follow this project's [Code of
Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]