Using React-App-Rewired
User Story: MB-9033 🔒
Background
The MilMove client application uses Create-React-App and React-Scripts for its build toolchain. This build toolchain has many benefits to developing the client application, but also has limitations when it comes to updating the configuration of various build tools that are used in the development of the client application. These tools such as webpack, ESLint, and Babel are configured with pre-determined configurations that are in-accessible without ejecting from the Create-React-App toolchain.
Facebook's own documentation mentions that If you aren't satisfied with the
build tool and configuration choices, you can eject
at any time. This command
will remove the single build dependency from your project. This is not an
option currently on MilMove as ejecting would add some maintainability overhead
that the development team may address at a later time or a later ADR.
Decision drivers
Some of the issues we've seen is that in order to best control our build
toolchain there are certain configurations that need to be updated. For
instance, webpack 5 removed the Node polyfills that are used
by the MilMove client application. This causes our client application to break
in unique ways around process
not being defined. Refactoring our client
application is a possible solution, but there are ways to have webpack 5 use
the Node polyfills that we need by defining it in a webpack configuration
file. Our issue here is that Create-React-App and React-Scripts prevent
us from modifying these scripts as they are not exposed to users of those
libraries.
This is true for other tools such as ESLint as well and has been an issue previously on the client application for the project. Sometimes the React-Scripts and Create-React-App tools update and support some level of customization but it leaves the MilMove engineering team in a holding pattern without a clear path forward besides following contributions upstream or contributing upstream to the Create-React-App project.
It's also true that Facebook's Create-React-App development team is
notorious for denying any changes for specific configuration updates. As stated
above, their own documentation states that ejecting
or maintaining a fork of
Create-React-App are the only viable solutions for customization using their
build toolchain.
Considered Alternatives
bold denotes chosen
- Do nothing
- Eject the Create-React-App configuration
- Dynamically patch the configurations
Decision Outcome
- Chosen Alternative: Dynamically patch the configurations
We can leverage React-App-Rewired in order to perform dynamic patching of
the webpack configuration, and other configurations as needed, in
order to bring back these Node polyfills for supporting the process
object
that the client application currently relies on. This is also useful in case
there are other configuration options that would like to be modified or extended
in the future. The React-App-Rewired library supports modifying webpack
& Jest configurations.
Pros and Cons of the Alternatives
Do nothing
+
There's no work to be done so teams can focus on other work.-
Leaves dependencies out of date due to not being able to update to the latest versions of NPM packages.
Eject the Create-React-App configuration
+
Reduces the dependency on Create-React-App.+
Allows engineering team to take ownership of the configuration for the client application.-
No wide-support from engineering team to maintain the build toolchain.+
Without wide-support from engineering, the lack of configuration is a safer space to exist in for the project regardless of the benefits or responsibilities to leverage the build toolchain manually.
-
Removes the reliance on Create-React-App and React-Scripts to incorporate security fixes which have much larger teams dedicated to this.-
Breaks out of the update cycle for Create-React-App and React-Scripts.+
The update cycle of Create-React-App and React-Scripts is one that is owned by their upstream development team. This cycle is a benefit to the MilMove engineering team as there are less dependencies that need to be managed by us.
Dynamically patch the configurations
+
Allows for control of extending or modifying build toolchain configurations.+
Removes the need toeject
from the Create-React-App ecosystem.-
Changes the build toolchain commands due to dynamic patching.