mesa
mesa copied to clipboard
Add React via esbuild
What is this?
This is the start of a journey to modernize and enhance the mesa frontend. The basic premise is that I added a lot of cool functionality with my mesa-viz package, but I ended up with rewriting large parts of the server and writing very unexperienced frontend react code. While I guess the package still works I think it is outdated beyond repair. But to salvage some of the functionality (like time traveling model steps and parallel simulation runs) I want to pursue a more gentle approach for updating the stack.
Over the last couple days I have been experimenting on how to best add react to our frontend stack. Most frameworks rely on hosting there own dev server, but this makes it quite hard to fit to our current ´modular_tempate.html´. That was also the main reason why mesa-viz required a new server and did not make use of tornados templating.
In this approach I only use esbuild to create a single main.ts file that is script-included in the template. Currently that means only a single invisible div is added at the front-end, but this allows us to gradually adopt react code.
The immediate goals are to move the existing html code and our runcontrol.js logic into react. The other modules can stay and should work independently like before.
The long term goals would be to move everything over to react so that we will only have a single ´js´ file that bundles all our dependencies and js modules together. That means we can have a small package footprint, while at the same time improve the development experience of the front end stack (which really is the point of all this).
While the actual need for react is discussable, it just enables to write more functional, descriptive code. Just as an example instead of writing
const canvas = document.createElement("canvas");
Object.assign(canvas, {
width: canvas_width,
height: canvas_height,
style: "border:1px dotted",
});
in react you only write (via JSX)
<canvas width={canvas_width} height={canvas_height} style={{border: "1px dotted"}}></canvas>
Things like a ChartJS chart can become concise as <Chart type='line' data={chartData} />
Any thoughts and opinions are very welcomed! Especially @rht since you are currently doing a lot of frontend development
Codecov Report
Base: 91.09% // Head: 91.09% // No change to project coverage :thumbsup:
Coverage data is based on head (
5aa0e7e) compared to base (5ed28a6). Patch has no changes to coverable lines.
:exclamation: Current head 5aa0e7e differs from pull request most recent head f359fb5. Consider uploading reports for the commit f359fb5 to get more accurate results
Additional details and impacted files
@@ Coverage Diff @@
## main #1334 +/- ##
=======================================
Coverage 91.09% 91.09%
=======================================
Files 18 18
Lines 1348 1348
Branches 260 260
=======================================
Hits 1228 1228
Misses 85 85
Partials 35 35
| Impacted Files | Coverage Δ | |
|---|---|---|
| ...a/visualization/modules/CanvasGridVisualization.py | 95.83% <0.00%> (ø) |
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.
:umbrella: View full report at Codecov.
:loudspeaker: Do you have feedback about the report comment? Let us know in this issue.
<canvas width={canvas_width} height={canvas_height} style={{border: "1px dotted"}}></canvas>
Yes, this is more readable. We could approximate it using vanilla JS's backticks, but it's not semantic.
Regarding with using React, I assume that you want to use the SPA functionality of it as much as possible? My only concern with this is that then it becomes harder to run viz on a Jupyter notebook (#1263). We could have 2 separate ("parallel universes") viz libraries for the Tornado-based (~~or nodejs~~) server, and the Jupyter. But this may increase the maintenance cost.
Regarding with using React, I assume that you want to use the SPA functionality of it as much as possible? My only concern with this is that then it becomes harder to run viz on a Jupyter notebook (#1263). We could have 2 separate ("parallel universes") viz libraries for the Tornado-based (~or nodejs~) server, and the Jupyter. But this may increase the maintenance cost.
Interesting point. I think with Jupyter we have have two options:
- Display the server inline, which I never managed to do reliable. It should be possible, but it always feels a bit alien and doesn't allow close coupling with parameter changes
- Custom visualization logic like in #1263. In that case we always will have some parallel logic e.g. for the UserSettableParameters. I don't think it matters that much how the "normal" looks like in that case, no?
But if we architecture this with this issue in mind the components based approach of react might actually help us. If we have a visualisation component (i.e. without controls and navbar, etc.), we might be able to display just that component inside a jupyter widget. I haven't evaluated how realistic that is, just putting out ideas here.
Display the server inline, which I never managed to do reliable.
This problem is documented in https://github.com/projectmesa/mesa/discussions/1259.
Authoring a Jupyter widget with React: https://blog.jupyter.org/build-a-jupyter-widget-with-react-and-typescript-d83e07340fa3.
Is this PR obsolete, given that Solara is based on React principles?
Not so much because of its react principles, but yes, solara suits mesa much better. This was meant to replace ModularServer, but a solara based approach makes more sense.