localstack-extensions icon indicating copy to clipboard operation
localstack-extensions copied to clipboard

feat(Template): Introduce template for react extensions

Open Pive01 opened this issue 1 year ago • 2 comments

Motivation

To allow a better integration between extensions and other LocalStack related products we can allow the creations of an extensions with e pre-built react app inside it that reuses the theme of our web app. This will allow a matching theme and easy access for developers to use react with it.

Content

  • Shifted the template into 2 folders, the first for the classic extension without UI and the second for the react one. To allow the cli to also work as expected I've raised another PR here
  • The extension itself work like so:
    • Divided into fronted and backend folders: the first one contains the react code while the second contains the routes definitions
    • The react app will be built before packaging the extension and will be included in the pypi module such that the total weight will be fairly low (base is around 0.5MB) and will not include all the node modules. It uses esbuild with some other packages to handle assets.
    • The routing will assume that your extension is hosted following the standards with subdomains and submounts. The default route "/" will always fall back to the index.html while by default everything else will serve files from the build folder. You will still be able to add /hello handler and respond with what you want. Since for routing we use react-router-dom an url could be valid and invalid at the same time: once you land on the "/" page and the extension responds with the index.html then will be react itself to handle routing and not the extension, which means that navigating from the ui to pages such as /one and /dashboard will work because handled by react route, but going directly into them with a link will result in LocalStack try to resolve them and give you the file called "one" in your build folder (or if you have defined a handler for that route it will give you that).

Other

Before merging this:

  • [x] Merge this PR -> publish package on npm -> update package.json with new link to dependency

After merging this:

  • [ ] Merge this PR to allow template to be generated with cli

On the next major release we could also restructure both templates into a single folder to keep the project more clean but doing it now would break the localstack extensions dev new command as it would be a breaking change for older cli versions

Pive01 avatar Jul 03 '24 13:07 Pive01

Overall I wonder whether organizing the frontend code into the python module like this is the best option. currently we are "nesting" language projects into each other. there's the "outer" python project (indicated by the setup.cfg and my_localstack_extension module), and then the package.json which is nested inside the module. i haven't thought it through, but maybe it makes sense to have a frontend or react folder next to the my_localstack_extension python module. then, during packaging, include the built files into the python distribution? we would place the package.json into the root folder next to the setup.cfg, and during make dist we'd first build the minified json with dependencies and include it into the dist.

On one way I agree that having 2 languages intertwisted is a bit ugly; on the other way though your proposal doesn't convince me much either: Having the package.json side to side with the setup.cfg seems wrong to me as setup.cfg defines the extension while package.json defined the react part of the extension...We could then move the /frontend folder as a whole side to side with the my_localstack_extension module....but I'm not too convinced about this either :sweat_smile: as the extension serves the react app as part of it; In the end is the same concept you applied with the jinja templates having them inside the module just that now is a whole react app to be built and served and not just the templates (even though in the end is just what is in the build folder to be served but details)

    my_extension
    ├── extension.py
    ├── __init__.py
    ├── static              <-- make sure static resources get packaged!
    │   ├── __init__.py
    │   ├── favicon.ico
    │   └── style.css
    └── templates            <-- jinja2 templates
        └── index.html

This aside I've addressed the other comment, thanks btw for the review @thrau :smile:

Pive01 avatar Jul 09 '24 14:07 Pive01

@Pive01 I've pushed the changes necessary for a single pyproject.toml that replaces both setup.cfg and setup.py. I suggest we'll add some linting/formatting in a follow-up as well, just to make sure we stay fairly homogenous with the extensions there as well :+1:

One thing I'm not sure yet about is if we should really use python -m plux entrypoints in the install-backend target. There's probably no need for this in an extension since we manually specify the entrypoint in the pyproject.toml file. We could remove either one of those and it should still work.

dominikschubert avatar Jul 26 '24 07:07 dominikschubert