-
Notifications
You must be signed in to change notification settings - Fork 96
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
Support Javascript configuration #199
Comments
I'm looking for thoughts, here. Particularly from @felipemontoya and @regisb. |
In order to comment with my opinion here I had to go open the pandora box of Thinking about how to bring that capability here, I agree with you that putting js files in the In the time I have been investigating the Now, about the option |
The docs say that the config file can be either If that's the case, there is an additional layer of complexity which is that something (either the Django backend or the MFE container / webpack etc.) needs to convert the JSX to plain JS. (I would prefer to require either [A] that the config file is |
The initial premise of microfrontends was:
Then we realized it was a terrible idea, because we needed dynamic configuration. So that became:
And now we are saying that configuration is more complex than we thought, so we need to build it. Thus microfrontends become:
I think that this additional complexity is unnecessary. We are going to transform configuration into code because we are making the incorrect assumption that plugin loading needs to reside in configuration. This does not have to be the case. Plugins should be loaded at build time. Then setting values no longer need to include js code. Microfrontends are already a bloody mess. Can we try to make them simpler, and not more complex? |
I disagree. Even though this is not true now, plugins, like MFEs, should be loadable at runtime. It is the direction we're going with the Piral/module federation work. And as such, there's no way around having some form of dynamic configuration.
It is not an assumption, made without consideration. It was a conscious decision based on how Node, Webpack, and React work, and also what we envisioned frontend plugins to be: "dumb" collections of components, that the user then decides where to load via configuration. Why? Because it's easy to imagine a user wanting to match the same plugins to the same UI slots, but in different ways. One may want to change the order the widgets appear. Another may want one widget to load on the left sidebar, as opposed to the right.
They are indeed! :) And we're working on simplifying some things (via Piral/module federation), but adding a plugin system is not where you'd usually want to reduce complexity. I'd argue that it's actually impossible to do so without making at least some things less straightforward. |
I have also felt strongly that microfrontends are blody mess, however I disagree in that the goal is not simplicity but actual usability. The process of:
Didn't work because the built microfrontends where not usable. We needed to extract configuration from the build (not unlike the python edx-platform images) so that you did not need to fork away every time. This is what led to
but this didn't work because the configuration that could be served dynamically was not good enough to make them very usable. So for most instances we were back to having to fork the MFE and build for every single deploy instead of deploy anywhere. So at this point we are pursuing a better configuration, that optionally requires a build, so that actually the "build once" promise is fullfilled. Making a reactive, fast, user friendly interface is hard and the frontend landscape is hard and frustrating at times. As is making a scalable, flexible and fast backend. The move to microfrontends was championed by a team that had a high ratio of developers per site and we have not yet reached the same level of usability for sites that have way less than that, but we are working towards it. |
Tangential note on MFEs in general: we have a brand new version of OEP-0065 that is intended to solve some of the frustrations we all know. openedx/open-edx-proposals#575 It's the Piral OEP, but without the Piral (because it added too much unneeded complexity. ;) |
@arbrandes you are saying that we should have plugins loaded at runtime. Both of these propositions can't be achieved at the same time, right? |
The configuration build step is currently only necessary to support Anyway, at first glance, if (typeof envConfig === 'function') {
config = await envConfig();
} We could have Tutor supply a static As @felipemontoya put it, all this doesn't need to replace |
Of course, there's also the option of making Tutor aware of the JS config file syntax so it could be templated with patches, like everything else. Thus potentially hiding away some of the complexity from the user. |
One further detail I neglected to bring up is that as things stand now, pre OEP-65, the plugin packages do need to be npm-installed at build time. In Tutor, this would be achieved via the post-npm-install hooks. So, in practice, while we'd have a dynamic way to configure plugins, we'd still have to install them up front. |
Small note: the reason that the env.config can be js or jsx is because while it is present at build time and outside the Maybe I'm missing some internals of tutor, but so long as the file is something our webpack build can handle, we don't need to precompile it in any way; the build itself does that. |
Maybe what you're missing is that currently Tutor relies on mfe_config for all env config, so that users can use a Tutor-provided pre-built Docker image while still being able to make some changes specific to their deployment (LMS and CMS base URLs, for instance). If JS config is to replace that, we'll need Tutor to be able to load it at runtime too. |
I bet you a round of piña coladas for all commenters on this PR against a case of peanut butter (here is our family's favorite brand) that we will want to include jsx/tsx config files before Teak is out. Probably because plugins will want to import nodejs modules. Then we will realize that the right way to achieve that is to serve config values at runtime (in js), and to load plugins at build time (in jsx). When that happens, I'll have a good reason to love microfrontends and I'll be grateful for them every time I spread chocolate chips on my peanut butter sandwiches. |
I think you are just trying to get a lifetime supply of peanut butter from Adolfo 😂. In my opinion we would want to include jsx/tsx config today if that had been proven to work for instances in the community. We will also want to include the css file with all the variables after paragon supports design-tokens. And should the I have been circulating this idea in my mind, would it make sense to have 2 different plugins for MFE support in tutor? One where long term maintainability and build once, deploy everywhere is the driving goal and a second that has a lot less expectation of long term support but allows Frontend devs to have advanced building tools and extensions? If this is heretic dont burn me at the stake just yet, I am coming at this from the angle that maybe we cant find a compromise between lightweight easy to maintain instances and heavy modified frontends in a single plugin. |
That sounds right to me. All the possible/installed plugins should be baked into the MFE image at build time, and you can then enable/configure them dynamically using the MFE config API, which doesn't need to support JSX/TSX. The MFE can use ESM dynamic imports (
I'm actually kind of thinking along those lines too. I think Tutor MFE doesn't need to support "dev mode" for MFEs anymore, because I discovered that the way Tutor does MFE config makes it super easy to just run the MFE on your host. For example, with this change I made it so you can just run |
Just went through the above discussion, why are not we simply include plugin packages in The only problem seems is that there are 10 MFEs (suppose) and I want to change different slots in all MFEs. I have to include all the plugins in one file That's all my understanding from testing Footer (using Plugin approach) in Learner-dashboard MFE. Am I missing any crucial point? |
@hinakhadim, for Redwood, that is likely all we're going to do. I'll whip up a PR that changes the README to document how to do it. However, once plugins themselves can be loaded dynamically (as a consequence of OEP-0065), we'll also want to configure them dynamically. And in doing so, we could also deprecate the |
It's now possible to configure frontend plugin slots across MFEs (notably, header and footer). This documents how this can be done as simply as possible. See overhangio#199
It's now possible to configure frontend plugin slots across MFEs (notably, header and footer). This documents how this can be done as simply as possible. See overhangio#199
It's now possible to configure frontend plugin slots across MFEs (notably, header and footer). This documents how this can be done as simply as possible. See overhangio#199
I've finally written some instructions on how to make use of frontend plugin slots as they stand now: Given how frontend-base is evolving, I don't think it would be worth the effort to do anything more complicated, yet. |
And an alternate approach that actually elevates env.config.jsx to a first-class template in tutor-mfe, based on feedback: #234 |
Description
tutor-mfe doesn't currently support Javascript configuration, except potentially by the old, abandoned expedient of baking it into the image. The latter is obviously not something we want to go back to, so a way must be devised to take advantage of JS configuration dynamically.
Why should we support it?
Because plugins will require it.
Solution Space
A list of potential solutions, for discussion.
1. Extend mfe_config
Extend the mfe_config API so that JS configuration can also be served. Extend runtimeConfig() so that it makes use of it.
site_configuration
doesn't sound like the best idea ever. Editing it will be horrible, for one.2. Refactor mfe_config
This is mostly the same as 1., except instead of piggy-backing on
site_configuration
, we write a dedicated admin page for it.3. Move mfe_config to tutor-mfe
Note: this last option is the most similar to how Piral does - or can do - configuration. I suggest we explore it seriously, as it might make our jobs easier later.
Instead of relying on an edx-platform API, we build a mechanism in tutor-mfe to serve the correct JS file dynamically. We'd likely be able to leverage the fact that
.env.config.js
is just Javascript to make a request to a predictable location that Caddy can then service. This file would be user-overridable, so if the operator wants to do something fancy like fetching a different configuration depending on the domain, they totally could.Pros:
Cons:
The text was updated successfully, but these errors were encountered: