Wrapping up the first month at CNCF - Jaeger under LFX Mentorship

Ansh GoyalAnsh Goyal
4 min read

This blog post explains some challenges that I faced during my first month of contributing to the CNCF - Jaeger project under the LFX Mentorship Fall 2023 Cohort.

A brief about my project:

The project is about upgrading the whole codebase of Jaeger UI to the latest version of React.
The codebase is like 5-6 years old, and React was at a whole different level at that time.
No hooks at all. Nothing like useState(), useContext(), etc.
The old TypeScript definitions and a whole lot of deprecated and un-maintained packages need to be upgraded and replaced.

In short, 10000+ lines of code need to be replaced, keeping in mind the UI/UX and features of the project should be as they were before.

Major road blockers:

There are/were some major roadblocks in the project. Some of them are/were:

  • ant-design library

  • react-router-dom

  • redux toolchain, which includes redux, redux-actions, react-router-redux

  • types/react

Let's talk about each of them briefly.

ant-design library:

The Jaeger-UI was using ant-design v3, and the latest available version is v5.

Upgrading it to v5 directly wasn't possible, since it included a lot and a lot of breaking changes, in terms of UI, as well as TypeScript definitions for some components.

The approach we followed here was to first upgrade it to v4's latest version. But, that too isn't as simple as it seems.

We upgraded the library in a 3 step process. The flow was like this: upgrade v3.26.20 to v4.15.6 then to v4.16.0 then to v4.24.13.

Checkout the PRs on GitHub here:

v3.26.20 to v4.15.6: https://github.com/jaegertracing/jaeger-ui/pull/1748
v4.15.6 to v4.16.0: https://github.com/jaegertracing/jaeger-ui/pull/1750
v4.16.0 to v4.24.13: https://github.com/jaegertracing/jaeger-ui/pull/1751

The key takeaway here is that we should upgrade an old library bit by bit, and if you are using a VCS, then create small commits, so that each breaking change could be reverted.

redux toolchain:

The Jaeger UI was using,

  • redux-actions v2.2.1: This was an easy bump to v2.6.5 without any breaking change. [PR]

  • react-redux v5.0.6: Upgrading it to v8.1.2 was also fairly easy, as it included some type changes along with import changes. [PR]

  • redux v3.7.2: This was a bit tricky to upgrade to v4.2.1, but it didn't break anything. [PR]

  • react-router-redux v5.0.0-alpha.8: This was a tricky upgrade, or we can say a change, as we could no longer use this package due to its incompatibility with react-router-dom v6 as well as redux v8.

    We replaced this package with redux-first-history which is recommended by the whole react-router-redux community.
    There were minimal code changes while making the transition, thanks to the redux-first-history's author and community. [PR]

react-router-dom (rrd):

The Jaeger UI was using react-router-dom v4, while the latest available version is v6.

Would call it the most trivial change till now. The whole scenario of this package is changed in v6.

The rrd community introduced the use of hooks like useLocation(), useParams(), etc. to handle the route props.

Previously, rrd used to export a withRouter HOC (High-Order Component). What it does is, it injects the route props like location, history, params, search, etc. The developers could then use this HOC to wrap their class-based components and access these props inside their components.

Since the release of React v16, a whole new concept was introduced to access such props using the React Hooks.

So, could we simply use useLocation() where this.props.location was used?
NO. We cannot use React Hooks inside the class components.
So, should we convert class components to functional components?
NO. That would break the whole app. It's like re-writing the whole codebase from scratch.
So, what we did?
We created our own HOC from scratch and used hooks inside it. Check out the blog post on how we did this.

But, there's another problem. The history object could no longer be used, as there is no replacement hook for the history object, provided by rrd v6.
So, what we did here?
We created our own HistoryProvider and useHistory() hook. Check out the blog post on how we did this.

The rrd upgrade is still not complete, as it includes more breaking changes, like the use of Route children instead of Route component syntax.

Checkout the rrd upgrade tracker issue here: https://github.com/jaegertracing/jaeger-ui/issues/1825

Concluding the post here. That's all about the previous month ๐Ÿš€

10
Subscribe to my newsletter

Read articles from Ansh Goyal directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ansh Goyal
Ansh Goyal