Integrating microfrontend tooling into OpenMRS SDK?

We’re trying to clean up the documentation to make it easier for others to contribute to Microfrontend work. @bistenes brought up the SDK with me today, and since we’ve been talking about the Technical Roadmap for 2021, seems like good timing.

Proposal:

Imagine if the tooling a dev needs in order to contribute to Micro Frontend work was already part of our SDK. You’d run openmrs-sdk (and maybe add a tag for whether you want MFE tooling or not), and it would set up a SPA environment for you so that you simply navigate to SPA on your local server and you could get started. In theory this could also reduce initial support requests as people try to get started using SPA.

Questions:

  • Do people think this is something we should try to get done in Q1 or Q2 this year?
  • What tools, or how much of the MFE system, would we want added to the OMRS SDK?

CC: @mseaton @burke @dkayiwa @jdick @florianrappl

1 Like

Sure looks a wondeful idea

@grace IMO the OpenMRS SDK should have any proposed packaging and deployment feature for modules, distrbutions including micro-front end asset packaging (which will probably be a pain) including the distribution management being proposed by Mekom for the Iniz module

1 Like

This is a great idea!

It would be lovely to have something in place before GSoC gets started for the purposes of these projects, as that’s when I’d expect we have a spike of users trying to setup an MF for the first time.

As much as we can make easier by integrating things into the SDK. I think at a minimum:

  1. Some capacity to create a “new” microfrontend project with reasonable defaults.
  2. Some capacity to easily load this into a running instance of OpenMRS (which is pretty trivial, though it would be nice if there was a command to automatically activate it for given SDK servers).
  3. Some capacity for bundling up the resulting JS + other assets into whatever format we expect this to be deployed in (ideally a format that can be versioned in some fashion).
3 Likes

Sounds a great idea , however since MFE projects are taking a totally different path , i may have this suggestion

  1. What is more expensive coming up with a new JS based SDK dedicated to MFE / OCL

Some problems (We can Weigh Benefits vs Cost)

  1. If we came up with a MFE / OCL SDK , what would be the cost of starting something new / maintenance vs simply adding the feature to the existing SDK which means maintenance as well ?

  2. Does a MFE and may be OCL Developer want the cost of setting up Java and Maven for the sake of MFE / OCL(may Be) . Why not setup node / npm and concentrate on that

  3. If Current SDK becomes a god-sdk won’t we have more diverging problems for the maintainers (Java VS Node)

Just asking I may be wrong this way , otherwise a MFE / (and may be OCL ) feature on SDK is a sweet bunch of bananas for this year :grinning: :grinning:

1 Like

Exactly!

@tendomart excellent suggestion re. the OCL for OpenMRS work as well, thank you for thinking of that. You ask a good question about whether there should be 1 or 2 SDKs. What do others think about that? @dkayiwa @burke?

@ssmusoke sorry can you clarify: What exactly about the MFE asset packaging do you anticipate will be a pain?

@tendomart A few things:

  • I’d separate out the OCL stuff from the MF stuff. Yes, they’re both generally ReactJS-based SPAs, but the OCL for OpenMRS Client is (in my mind) a one-off project rather than something we’d expect to see people adding their own custom versions of.
  • I agree that there very little value to a pure front-end developer having this integrated into the SDK. I’d expect that what we actually going is adding some thin Maven wrappers around functionality provided by NodeJS-based scripts, so a front-end developer could always just by-pass the Maven stuff.
  • However, for new devs who might work on both a module and a front-end for that module-provided functionality, having the SDK integration isn’t too much overhead (and if we’re thinking in a microservice way, teams are generally supposed to own “features” rather than dividing the work into “backend stuff” and “frontend stuff”; having a single tool to create whatever kind of OpenMRS-related project you need helps make that easier).
  • I think the worry about a “god-sdk” is a little misplaced. In terms of Java code, the SDK really only has a small number of responsibilities: 1) setup a new module / project, 2) setup and run a local OpenMRS server, and 3) deploy modules / projects to the local server. Everything else (compiling code, building and packaging OMODs, etc.) is handled elsewhere (and generally by the default Java / Maven stack). Having a version of openmrs-sdk:create-project that creates a MFE project by calling whatever appropriate generator using system NodeJS and that can (call out to) the NodeJS tools for automatically creating / deploying an import map doesn’t seem like a huge lift.
1 Like

Ooh Noted , thanks for the insight @ibacher

@bistenes @mseaton does this sound like what you had in mind?

@dkayiwa How could we proceed with breaking down this work and getting this done? Is this something that the TAC or PM Team would take on, in a similar way to how we get the releases handled and launched?

@grace I have no idea since I have not yet dipped my toes, into it it yet, so was just a suggestion.

@tendomart 2 SDKs are a no-go area. What is so special about MFE/OCL that requires a new different SDK. Remember the lifetime of these front-end technologies is 2-3 years, so it will be replaced soon with something else

FYI - Server side rendering is back in vogue with new paradigms like HotWire and now React has some implementation

1 Like

years or just months :grinning: ??

I agree with @ibacher’s points, though since you called it out over the others @grace I think SDK goals that facilitate creating a new microfrontend (eg. create-project) are less valuable than those responsible for installing and updating artifacts into a server (eg. the deploy goal), whether this is a new install or an update of an existing install, and whether this is an individual artifact or all of the components that make up a broader distribution.

At PIH, we rarely if ever use the openmrs-sdk:create-project goal. We very often use goals like “setup” and “deploy” against a server that is configured with an openmrs-distro.properties file as a part of a distribution.

The typical workflow would be to:

  1. Install a distribution into a new server with openmrs-sdk:setup, where -Ddistro points to a maven project that has an openmrs-distro.properties file on the classpath.

  2. Update this server to the latest version of the distribution over time, using openmrs-sdk:deploy -Ddistro points to an updated openmrs-distro.properties file with new versions

  3. Update this server to run a new or update an existing artifact, but running openmrs-sdk:deploy while in the top-level directory (with pom.xml) for a given project.

It would be great if we could start:

  1. Specifying the microfrontends that are part of our distribution in a structured configuration file (expanding on the current openmrs-distro.properties, or evolving this in some way)

  2. Have the SDK goals responsible for installing/updating artifacts into an SDK server able to do so in a manner consistent with how it supports modules, war, and owas.

(Note: supporting config packages would be the other component we’d want to support in a similar fashion)

Mike

2 Likes

Agree with not creating a second SDK. Devs working primarily in frontend technologies already have tooling like npm, nvm, etc.

Enhancing our SDK to facilitate the packaging, deployment, and running of OpenMRS instances with new frontend artifacts makes sense.

Put simply, our SDK should make development, packaging, & deployment easier while focusing on simplifying & standardizing the OpenMRS-specific steps that devs otherwise need to do manually and the fewer OpenMRS-specific aspects of development we have, the better.

1 Like

Noted all ,thanks

I’d like to work on this in the next couple weeks. Not the generator part (sorry @ibacher ) but rather the integration with setup, deploy, and run.

What we have presently is IMO a second SDK, npx openmrs, which is a very good thing and was definitely the right decision. The task now is to integrate that with the maven SDK.

I agree with @mseaton 's proposals. As @ibacher suggests, I think we should implement this by having the maven SDK delegate to the openmrs frontend tool as much as possible.

So I suggest that openmrs-distro.properties should support the following sorts of properties:

# Microfrontends to include, a la microfrontends.json
spa.microfrontends.@openmrs/esm-home-app=next
spa.microfrontends.@openmrs/esm-login-app=1.3.0

# The base application path and SPA path
spa.apiBase=openmrs/
spa.spaBase=openmrs/spa/

# Paths to config files to build in
spa.config=config.json,config-site.json

# Additional import map lines
spa.importmap.config-file=assets/another-config.json
    # becomes the line "config-file"="assets/another-config.json"

# Additional assets to bundle with the application
spa.assets=assets

Where we have files config-json, config-site.json, and assets/another-config.json all in the distro folder.

This will build the specified frontend application to frontend/ in the application data directory, both in development and when building the distribution. This will work out of the box with openmrs-module-spa.

I don’t know how the SDK should support builds where the frontend is being served from outside the application data directory. We should figure this out. @mksrom , @mksd ?

I realize this seems like a lot of new stuff in openmrs-distro.properties. Other ideas are welcome. But these are all application build parameters and that seemed like the natural place for them to go.

CC @jdick , @corneliouzbett , @dkayiwa

EDIT: Changed spa.@xyz to spa.microfrontends.@xyz

3 Likes

This is great! I might start working on MFs.

IMO: with the assumption that the individual who wants to serve frontend assets outside the application directory already has a pipeline of building those assets. So maybe adding a prompt to decide whether to serve from a remote URL, If yes ask for the URL and skip building the frontend assets, then use the information to set the GPs; spa.remote.enabed=true and spa.remote.url=<provided-URL>. Dunno how SDK is architecture but a simple insert for the GPs will do the trick.

2 Likes

As far as I know that doesn’t matter too much.

And otherwise I am really excited to see this work being moved forward @bistenes! That will be really useful for the ICRC as we start embracing O3 in the next few months (hopefully).

Cc @frederic.deniger

2 Likes

Thanks for working on this @bistenes ! With a quick review, this makes sense to me!

Take care, Mark

@bistenes Thanks for this, this looks great!

Are these actually necessary to create a distro bundle? They look to me like more of runtime considerations than distribution-time, but I suppose these are embedded in the actual SPA page?

The SDK doesn’t really have a role in the actual instance running nor do we want to make that a requirement. So having the SDK directly create GPs is probably not the best idea (the SDK at best loads a skeleton of the OMRS DB schema that’s then modified by the Liquibase scripts).

3 Likes