Building a frontend Maven package

Thanks for the reply @mksd and the reminder to check what has been done in refapp 3.x.

First - what @bistenes is discussing here is not inconsistent with the approach that is there - namely to build a distribution zip artifact that contains the war, omods, and frontend (as well as owas and config as appropriate).

I think it is helpful to look at config as an example, before we look at frontend. With config, there are situations where a distribution may want to keep their configuration files in the same github project as their distribution itself. This is what the refapp does, and is what we do in our rwandaemr-imb-butaro and rwandaemr-imb-rwinkwavu distributions at PIH. But although the refapp includes the configuration in the same codebase, it is ultimately built independently (eg. it is built into openmrs-config-refapp-xyz.zip, and published to maven at org.openmrs.distro:referenceapplication-config:x.y.z). And the distribution build process that pulls this in does so by pulling in the built maven artifact and unpacking it for inclusion in the distribution zip. So ultimately it doesn’t matter whether this config is maintained in the same github project or not. A distribution may choose to do so or not do so based on their needs. The config is a project that builds to a versioned artifact, and the distro includes a particular version of this artifact. And for our PIH-EMR distributions, we have chosen to maintain our configuration in separate github repositories from our distribution.

For the frontend, we are currently doing the same thing that the refapp is doing. Namely, we have an openmrs-distro.properties file that lists out all of the various spa.frontendModules.xyz that we want to include in our distro. However, what @bistenes and I are working on is an idea to evolve away from this to a model similar to what we do with configs. Namely - build the frontend in a separate Maven project that publishes this frontend code (eg. the contents of the spa directory in the distro) to Maven, and then have our distribution build process pull this artifact in and unpack it just like we do with the configuration. Ultimately the distribution build process will arrive at the same result. It’s really just a matter of whether one views building the frontend artifact as a fundamental part of building the distribution, or whether the frontend artifact is something independent that one or more distributions may choose to include at a particular version.

In principle, I think separating these out is a cleaner approach, but there is no reason why we shouldn’t support both and leave it to the distribution authors to decide what works best for them. In practice, I’ve personally found that the inclusion of the frontend build process in the distribution build is unpleasant as it dramatically slows down the distribution build itself. The frontend build with npx takes a decent amount of time to run, whereas building a distribution has historically been (and I’d like it to continue to be) quick - simply copying Maven artifacts into a package. If I can offload the frontend build to a CI server and then just pull in that artifact (and cache it locally with maven like all of the others), I’d like to do so, particularly if it isn’t anything I am actively working on or concerned with.

Where I think I’d like us to move is to a point where our openmrs-distro.properties can refer to configuration artifacts and frontend artifacts in the same way that it currently refers to omod, war, and owa artifacts.

We’d simply have some new properties like:

config.refapp=x.y.z
frontend.refapp=x.y.z

And these would be used:

a) During the distribution build (via the openmrs-sdk plugin) to pull the appropriate artifacts from Maven, and unpack their contents into the distribution package zip

b) During SDK setup/deploy to set a new SDK server up with configurations and frontend that are necessary, as defined in the distro properties, such that doing an openmrs-sdk:setup followed immediately with an openmrs-sdk:run will fully run a distribution instance with no other steps. Currently this is not possible as configuration is not installed by the SDK.

Ultimately, all of this is where I’d like to head. And @bistenes question is really just around - if we were to start doing this at PIH, do we want to do so with any community conventions in mind. For example, we have the following conventions currently:

Github conventions:

Maven conventions:

  • org.openmrs.module:module_id:version
  • org.openmrs.distro:distroname:version

And do we want any conventions around configuration packages and frontend packages that we follow.

At PIH, we have already started establishing our own configurations, as there wasn’t really an existing standard, and also it seemed like there would be an argument for branching beyond the “org.openmrs” domain. So we started using “org.pih.openmrs” as our groupId, and “openmrs-config-xyz” as our artifactIds. For example: openmrs-config-zl/pom.xml at master · PIH/openmrs-config-zl · GitHub

It’s probably most straightforward for us to continue this pattern with a github.com/PIH/openmrs-frontend-pihemr repository that builds a Maven artifact at “org.pih.openmrs:openmrs-frontend-pihemr:version”, which we will put into our own Maven repository here.

But it’s worth discussing if we want to establish any standard naming conventions that either build off of this approach that we have been using, or recommend a slightly different standard.

Happy to take this to a TAC call, but figured I’d lay these thoughts out here first.

2 Likes