Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

After setting up a frontend module locally, you'll want to start making changes to it. This guide will walk you through the steps you need to follow when doing local development on a frontend module. We'll cover how to install dependencies, run frontend modules locally, write tests, push your changes to GitHub, maintain dependencies and troubleshoot common issues.

Installing dependencies

In most cases, we use the latest version of yarn(opens in a new tab) as our package manager. To install dependencies, you'll typically cd into your local copy of the frontend module you want to work on and run yarn (which is short for yarn install). For example, if you want to work on the Patient Chart(opens in a new tab) frontend module, you'd run:

Code Block
languagesh
cd openmrs-esm-patient-chartyarn

Running frontend modules locally

Non-monorepos

Some of our projects are not monorepos. For example, the Form Builder(opens in a new tab) is a standalone project. To run the Form Builder locally, you'd cd into the project directory and run yarn start. For example:

...

You shouldn't need to scope commands by their target packages in non-monorepos.

Monorepos

Most of our frontend modules are part of monorepos. For example, the Patient Chart(opens in a new tab) monorepo consists of several frontend modules that handle Patient-related concerns. You'll typically want to run a specific frontend module within a monorepo. To do that, run yarn start --sources and pass in the relative path to your target frontend module. For example, to run just the Vitals(opens in a new tab) frontend module, you'd run:

...

To learn more about the develop command, read through its implementation(opens in a new tab).

Using import map overrides

O3 determines where to load the code for frontend modules from based on the import map provided to the app shell. The import map is a JSON object that maps module specifiers to URLs. You can find the import map for your O3 distro by navigating to /openmrs/spa/importmap.json in your browser. The Devtools(opens in a new tab) frotend modules provides an interface for overriding entries in your import map. You can leverage this when doing local development to load copies of your frontend modules from your local dev server. For example, if you fire up a local development server running the app shell, it's possible to override import map entries for multiple frotend modules from multiple projects at the same time. This is useful when you're working on a feature that spans multiple frontend modules.

...

Import map overrides don't work on the dev3 server because of security restrictions. We'll work on loosening these restrictions in the future. For now, you can only use import map overrides on a local dev server.

Example: Running the Implementer tools and Primary navigation frontend modules against the app shell

Run the app shell

Code Block
languagesh
cd @openmrs/esm-coreyarn run:shell

This should fire up a dev server on port 8080 (assuming you have no other dev server running).

Run the implementer tools app

In a different terminal window, run:

...

Note that if you're running multiple frontend modules simultaneously using yarn start, the app shell will run on port 8080 and the frontend modules will run on the next available ports. That is, the packages will run on port 8081, 8082, and so on, if available. However, if you're running each frontend module individually, you'll likely have to configure the port number manually as the app shell will default to trying to load the frontend module from the next available port after 8080.

Run the primary navigation app

In a different terminal window, run:

Code Block
languagesh
cd openmrs/esm-coreyarn start --sources packages/apps/esm-primary-navigation-app --port=9000

Consolidate everything

On the dev server running the app shell, login and navigate to the home page. We want to make sure that import map overrides are enabled. Type this command in the browser devtools console and press enter:

...

You should now see your changes to the Implementer tools and Primary navigation apps propagate to the app shell. You can now test out your changes in the context of the app shell.

Running esm-patient-common-lib locally

The esm-patient-common-lib is a library of common components and utilities used primarily by the patient chart in O3. You might to make changes to the library and test those changes against a local dev server. To achieve that, you can do the following:

  • Launch the package.json file for the frontend module you want to work on. Look for the esm-patient-common-lib dependency in the peerDependencies section. Remove that entry and run yarn to install dependencies.

  • Run your local dev server using yarn start. For example, for the labs app, run:

    Code Block
    languagesh
    yarn start --sources 'packages/esm-patient-labs-app'
  • Try making a change to a library, e.g. adding a console.log to a file such as DashboardExtension.tsx. Your dev server should reload and you should see your console.log printed in the browser console once you navigate to the patient chart.

  • Once you're done making changes, you can revert the changes you made to the package.json file and run yarn to install dependencies again.

Running the app shell locally

Most of the time, this should be all a developer needs to do to get a local dev server running. One notable departure, however, is running the app shell. You’ll need to run the shell directly if you want to:

...

This command should run the build script in all of the constituent frontend modules whose code you’ve changed. Once the build is complete, you should see your changes reflected in the dev server in your browser.

How do I know where to make changes?

There is no simple correlation between frontend modules and pages and content. The first step to figuring out where to make changes is to identify the frontend module you want to work on. For example, if you want to make changes to the patient chart, you’d work on the patient-chart frontend module. If you want to make changes to the patient search, you’d work on the patient-search frontend module. If you want to make changes to the login page, you’d work on the login frontend module. And so on. There are a few ways to figure out which frontend module you need to work on:

...

There are no hard and fast rules for figuring out where to make changes. The best approach is to try out different things and see what works for you. The more you work on the codebase, the more familiar you’ll become with it and the easier it’ll be to figure out where to make changes. If you have done all of the things above and still haven’t found the code you’re looking for, feel free to ask in the #openmrs-helpme channel(opens in a new tab) on Slack.

How can I develop against a restricted environment?

In general, you can develop against another environment using the --backend flag. If the other environment is guarded, e.g., by an IP or network restriction then this is something you need to take care of on your local machine. In case the guarded environment is restricted via some SSO mechanism using a cookie you could use the --add-cookie flag to achieve this. As an example, look at the access for a development server from the ICRC:

...

The cookie must be obtained by you and strongly depends on the backend used.

Should I write tests?

Yes, absolutely! We have a test suite for the frontend modules in the monorepo. We use Jest(opens in a new tab) for testing. We also use React Testing Library(opens in a new tab) for testing React components. We have a testing guide that you can refer to for more information on how to write tests. We're adding support for Playwright e2e tests(opens in a new tab) as well across our repositories. Consider adding e2e tests for your changes as well. Going through the testing guide as well as the tests in the codebase should give you a good sense of how to write tests.

Pushing your changes to GitHub

Once you’re done working on a feature or fix, you’ll want to push your changes to GitHub and file a PR. To do this, package your changes in a commit. We have guidelines for writing commit messages in our contributing guide(opens in a new tab).

...

If any of these tasks fail, the push should fail. The terminal should display the error message(s) that caused the push to fail. You’ll need to fix the error(s) and push again. Once the push succeeds, you can go to the GitHub repo related to your package and file a pull request.

Maintaining dependencies

Maintaining up-to-date dependencies is important to leverage the latest features, performance improvements and security patches. Yarn 3 provides a handy interactive tool to help you keep your dependencies up to date. To use it, run the following command:

...

This command lists the dependencies of your project that are eligible for updates. You can navigate the list using your keyboard's arrow keys. In general, you want to avoid making major version updates because they can introduce breaking changes. You also want to keep OpenMRS-related dependencies (such as openmrs and @openmrs/esm-framework) pinned to next. Everything else should generally be OK to update to the latest version. Once you've selected the dependencies you want to update, you can press Enter to update them. Make sure to test your changes to ensure that nothing has broken. Ensure the app runs OK, tests pass and the app can get built correctly. If everything looks good, you can commit your changes and push them to GitHub.

Troubleshooting

I'm getting a bunch of errors related to missing dependencies

If you're working off of a fork, your fork might miss the latest changes from main. To fix this, you can run the following command to update your fork:

Code Block
languagesh
git pull upstream main --rebase

I'm getting an Error: ENOSPC: System limit for number of file watchers reached error

If you’re running Linux, you may see the following error the first time you run a dev server: Error: ENOSPC: System limit for number of file watchers reached. If that happens, you need to increase the system limit for the number of file watchers. See this StackOverflow answer(opens in a new tab).

I see errors about missing APIs when I run the app

If your dev server is throwing errors about missing APIs or functions, it's likely because you're running outdated versions of core tooling. This means that new functionality was likely added to Core(opens in a new tab) that your local dev server doesn't have. New pre-release versions of the openmrs(opens in a new tab) CLI and @openmrs/esm-framework(opens in a new tab) get published each time a pull request is merged in Core. To ensure you have the latest versions of these packages, run:

...

This command might change the versions of the packages specified in your manifest file (package.json). If it does, you'll need to revert the versions back to next before you commit your changes. You might need to run yarn to install the new versions of the packages after effecting the changes. Once you've done that, you should be able to run the dev server without any issues. Be sure to only commit the updated yarn.lock file.

I'm getting a ERR_OSSL_EVP_UNSUPPORTED error when running yarn run build

If you're running or building the form-entry package (an Angular wrapper around the AMPATH Form Engine) using Node v18, you may see the following error:

...

Code Block
languagesh
export NODE_OPTIONS=--openssl-legacy-provider

I'm getting errors after upgrading @carbon/react

You might see the following errors in your terminal when running a local dev server after upgrading @carbon/react:

...

Code Block
languagets
declare module "@carbon/react";declare type SideNavProps = {};

I'm getting merge conflicts in my yarn.lock file

To resolve merge conflicts in your yarn.lock file, run the following command:

Code Block
languagesh
git checkout HEAD yarn.lock && yarn

The verify job is failing on GitHub Actions for my PR

You likely have a lint or typescript error in your code. ESLint is setup to fail when it flags warnings. Run yarn turbo lint locally to the specific lint error in your IDE. For TypeScript errors, you should see the error in the CI log. If not, run yarn turbo typescript locally.

I'm getting 502 errors from attempting to fetch the session when running a local dev server

If you're running a local dev server and you're getting 502 errors from attempting to fetch the session, that's likely because the dev3 server (which your local dev server proxies to) is down. Check that you can log in to dev3(opens in a new tab) first. If you cannot log in, then you'll need to wait for the server to come back up.

I'm using @openmrs/esm-patient-common-lib and getting "No workspace named '...' has been registered"

If you're getting this error, you most likely need to add @openmrs/esm-patient-common-lib to the peerDependencies list in your package.json. Also, make sure that you have @openmrs/esm-patient-common-lib: next listed under your devDependencies.

I'm getting an Oops! An unhandled promise rejection occurred error when loading my dev server

If you see an Unhandled promise rejection error when running a dev server or a production instance of O3, it likely means that you have a module that is not getting loaded correctly. The devtools console in your browser will likely contain an error message about the module that is not getting loaded. Typically, you'll want to start by checking that you don't have any stale overrides set up in the import map overrides panel. To fix the error, you will likely need to open the implementer tools panel and click the Reset all overrides button. Once you've done that, reload the page. The error should go away. Alternatively, you could also look through your browser's local storage and delete any overrides that you find there. Remember to reload the page after doing so.