ReactJs - Quality And Evolution

ReactJs - Quality And Evolution

In one of our previous posts, we briefly described what the key quality attributes are and explored how ReactJS realizes these key concepts through its component-based architecture. In this post, we focus on the means to safeguard the quality and architectural integrity of the underlying system.

System’s key quality attributes

There are two perspectives on how key quality attributes can be realized.

The first perspective is from the end-user’s point of view in which web developers use the ReactJS framework. The key to safeguarding quality and architectural integrity is to correctly use component-based architecture. Many qualities are assured and satisfied by utilizing components. The main argument is to make components decoupled, focused on a single task, and keep them well tested. Therefore, components assure many qualities such as reusability, testability, customizability, and portability .

For this essay, we focus on the second perspective. This focus is on the quality attributes of the framework and its future development as seen from the contributors’ and maintainers’ point of view.

Quality Description
Maintainability Focusses on how maintainers control and maintain the source code
Reliability How do contributors reliably make code contributions without breaking core functionalities
Security Are there any vulnerabilities in the source code

Software Quality Processes and Test Processes

To maintain consistent and continuous quality for an open-source project like Reactjs contributors have a series of rules and practices that contributors must adhere to.1

Code Style

React has an enforced code-style rule which is maintained using third party software like Prettier2 for automatic code styling and they also refer contributors to the AirBnB style guide3 if they have questions on how to style their code. A consistent code style across the project makes it more manageable and maintainable between users.

Code Reviews & Requests for Comments

Any changes made to the React project must be peer-reviewed and accepted by the React community, they do this in order to maintain and control the features and changes being made in the project. For small changes like bug fixes a Pull requests can be made for review instantly, for more substantial changes like a new feature they ask that it undergo a design process4 which also goes under review and must have mass consensus in the team.

This is to not only maintain the quality of the actual code of the React project, but also serves as a method to filter or prevent bad code. Any code that does not achieve a certain acceptable quality will be rejected.

Testing Suite & Type Checking

React employs an automated testing suite, any new code into the project must be adequately tested. The testing code will be reviewed along with the code changes to the repository being made by the React contributors.

React is written in JavaScript which does not natively support types. Type checking in software can prove useful in preventing bugs and unexpected behaviours, which increases the quality of the software. The React team introduced Flow5 typecheck the codebase.

Merge Steps

To summarise to maintain the quality of the React software the team asks every contributor to perform the following before making a merge:

  1. Fork the repository and create their own branch.
  2. Add tests for any new code and ensure test suite passes.
  3. Format code with prettier, lint and typecheck with flow.
  4. Complete the React CLA.

Key elements of the system’s continuous integration processes

ReactJS uses CirceCI as their continious integration and continious delivery platform. ReactJS has four workflows, which are described below 67. For any PR to be accepted, a contributor license agreement also needs to be signed.

Workflow Description
fuzz_tests Used on the main branch. It consists of 2 jobs: setup and test_fuzz. The main purpose of this workflow is to trigger fuzz tests hourly.
build_and_tests Used in PRs and replaces the old stable and experimental workflows
publish_preleases Used to publish a prerelease manually via the command line. It consists of three jobs: setup, publish_prerelease and publish_prerelease
publish_preleases_nightly This workflow publishes on a cron schedule. It consists of three jobs: setup, publish_prerelease and publish_prerelease.

Code Coverage

Code Coverage

React does not provide us with insights into the code coverage directly on their Github repository. One of the possible reasons is that the public repository of React mainly focuses on getting contributions from the Open Source Community. Thus it only provides with CI/CD pipelines using CircleCi and refers us to documentation on how to correctly make Pull Requests.

The code coverage in the below table is provided by Istanbul, a tool specifically made to cover JavaScript lines. Results show that the code is only covered for approximately 48%. When examining the covered files it is apparent that the react-devtools are not tested for the majority of the code.

File % Statements % Branch % Functions % lines
All Files 50.13 (27661/55178) 44.24 (14970/33840) 50.4 (3237/6422) 52.53 (22549/42930)

Hotspot Components and its Code Quality

Hotspot components are components that have changed a lot in the past. We analyze those components in React using CodeScene 8.

Figure: Hotspot Components in React

Figure: Hotspot Components in React packages

The darker that circle is, the more change happened in that file. Hotspot components of React are scattered throughout the modules. Codescene let the components to be sorted by the number of commits. The noticeable components are the following:

  1. react/packages/shared/ReactFeatureFlags.js
  2. react/packages/react-server/src/ReeactFizzServer.js
  3. react/packages/react-devtools-shared/src/backend/rederer.js
  4. react/packages/react-reconciler/src/ReactFiberWorkLoop.new.js
  5. react/packages/react-dom/src/server/ReactDOMServerFormatConfig.js

Test files and similar files are excluded to explore more diverse hotspot components. Unlike what the graph shows, changelogs from React show most of the main changes are in the DOM 9. React DOM updates are not centred at one specific part of the code, so it is hard to say from the graph itself React DOM is a hotspot component. However, based on a review of the changelogs React Dom could in fact be considered a hotspot component.

According to our previous essay 1 and this article 10, there will be new updates for the React DOM, server-side rendering, etc. Putting all this information together, we can predict that React DOM and Server will be two of the main hotspot components in the future.

Code Quality

To measure code quality we used two tools CodeScene which we mentioned earlier as well as Sonarqube11. Both allow for automatic scanning and analysis of source code to produce a quality score using metrics like code complexity, the number of vulnerabilities and code smells.

The figure below shows the overview result of Sonarqube analysis.

Figure: Sonarqube Overview on React

The reason for majority of what is considered a bug according to Sonarqube is because:

It enables assistive technologies, such as screen readers, to provide a comfortable reading experience by adapting the pronunciation and accent to the language.

While accessibility is beneficial, the final responsibility of this relies on the developer who uses React when they are building their web apps. If this is taken into account the code quality of the React project is actually quite good.

The 179 Security Hotspot, are points in the code which the analysis tool needs a manual inspection to determine if vulnerable. We looked into it and it seems that the security hotspot points involve things like not encrypting sensitive data like an imgur images included in the documentation.

Focusing on the Hotspot components mentioned above, the code analysis tools mainly found problems with code smells and not with vulnerabilities and potential bugs. The majority of the problems are related to TODO comments left in the code, for the top hotspot components like ReactFeatureFlags.js this is the only problem found. Since React is open source TODO comments are a form of communication which justify the code smell. Hotspot components like ReactFizzServer.js, have code smells related to functions having too many arguments.

To summarise, the result is not as bad as it seems. Most problems are repeated non-problems for the end goal of React to serve the developer. Considering the project size and complexity, we believe the React project to be high-quality code as its Maintainability score of A indicates.

Quality culture

The repository of ReactJS is a monorepo, meaning all packages are under one repo. It should be possible to release a new minor version from the tip of main at any time. Therefore, no breaking changes are allowed into main and code that will be merged must be compatible with the latest stable release. All significant changes are documented in the Changelog. Importance is put into keeping the latest version stable and clean, PR#20831 PR#20832 PR#20840 remove an unused dependency to address cross-origin isolation warning, PR#18970 improve memory usage. However, new issues have been opened that also focus on the health older React versions, #19371 sets up the CI infrastructure to run against multiple React versions instead of the version of main only.

Furthermore, ReactJS follows semantic versioning. Patch versions are released for critical bugfixes, minor versions for new features or non-essential changes, and major versions for any breaking changes. Deprication warnings are introduced in a minor version, before a breaking change. This notifies users in advance of upcoming changes and allows them to change their code in advance.

As mentioned before, for consistent quality of the software and collaboration, consensus is needed before changes in the design process are allowed. Issues have been created allowing for discussion and sharing ideas on improving the architecture: #23237, #23186, #23175, PR#18561.

Other issues have been thoroughly discussed and checked before a PR was created and merged:

  • #11935 started a discussion on the best solution to fix the bug, after the solution was found PR#101 was merged.

There are also issues that did not contribute to a bugfix and were closed by the ReactJS team: #24108, #24103 and PR#24124.

At the moment of writing this, there are 726 issues and 238 PRs. The oldest issues dates back to 2013 and the oldest PR goes back to 2018. The project keeps its issues and PRs neat as issues and PRs are closed if they do not provide some solution or improvement.

Technical Debt

Technical debt is a metaphor which describes the cost of additional rework caused by choosing an easy solution now instead of using a better approach that would take longer12. There are a few factors that cause technical debt, time pressure on the development team, outdated technology and constant change 13. This technical debt can be measured by tools such as Sonarqube 11.

As can be seen from out Sonarqube results, React has some code issues regarding reliability and security, but shows an outstanding result for maintainability.

Figure: Maintainability debt Overview

The above diagram explains the maintainability result and the technical debt. In Sonarqube, the estimated technical debt is the estimated time to fix all Maintainability Issues and code smells (1 day of debt = 8 working hours). React has, in total, 9500 code smells, 249 days of debt, and also 0.8% debt ratio. The standard of Rating ‘A’ is when the debt ratio is maller than 5.0%. We analyze the top 5 bubbles.

File Technical Debt
cjs/react-dom.development.js 25d
umd/react-dom.development.js 21d
cjs/react-test-renderer.development.js 18d
umd/react-test-renderer.development.js 15d
webcomponent.js 10d

These files are previously used by a lot of developers. Many of the issues causing this technical debt came from bad coding practices.

Here are some examples.

Figure: Bad code example

Figure: Bad code example

React is using lint, prettier, flow, etc for its static code analysis. Incorporating a tool like Sonarqube can reduce refactoring time for future development, bringing a long-term benefit. However, even without using Sonarqube, React repository is showing a decent performance in terms of maintainability. We can assume that the current open-source environment and current analysis tools are good enough to keep technical debt low.

References


  1. “How to Contribute”, React. [Online]. Available: https://reactjs.org/docs/how-to-contribute.html [Accessed: 19-Mar-2022]. ↩︎

  2. “Prettier”, Prettier Team. [Online]. Available: https://prettier.io/ [Accessed: 19-Mar-2022]. ↩︎

  3. “AirBnB JavaScript StyleGuide”, AirBnB [Online]. Available: https://github.com/airbnb/javascript [Accessed: 19-Mar-2022]. ↩︎

  4. “RFC Repository”, React. [Online]. Available: https://github.com/reactjs/rfcs [Accessed: 19-Mar-2022]. ↩︎

  5. “Flow”, Flow. [Online]. Available: https://flow.org/ [Accessed: 19-Mar-2022]. ↩︎

  6. Facebook/React. 2022. react/config.yml at main · facebook/react. [online] Available at: https://github.com/facebook/react/blob/main/.circleci/config.yml [Accessed 20-March-2022]. ↩︎

  7. CirceCI. 2022. CirceCI React. [online] Available at: https://app.circleci.com/pipelines/github/facebook/react?filter=all [Accessed 20-March-2022]. ↩︎

  8. “Software quality visualization - tech debt|codescene,” Software Quality Visualization - Tech Debt|CodeScene. [Online]. Available: https://codescene.com/. [Accessed: 20-Mar-2022]. ↩︎

  9. Facebook, “React/changelog.md at main · facebook/react,” GitHub. [Online]. Available: https://github.com/facebook/react/blob/main/CHANGELOG.md#1702-march-22-2021. [Accessed: 20-Mar-2022]. ↩︎

  10. D. Bhalani, “React 18 new features and updates,” Medium, 24-Nov-2021. [Online]. Available: https://medium.com/dhiwise/react-18-new-features-and-updates-2e608d862a6d. [Accessed: 20-Mar-2022]. ↩︎

  11. “Code quality and code security,” SonarQube. [Online]. Available: https://www.sonarqube.org/. [Accessed: 19-Mar-2022]. ↩︎

  12. “Technical debt,” Wikipedia, 08-Feb-2022. [Online]. Available: https://en.wikipedia.org/wiki/Technical_debt. [Accessed: 19-Mar-2022]. ↩︎

  13. “What is technical debt,” OutSystems. [Online]. Available: https://www.outsystems.com/glossary/what-is-technical-debt/. [Accessed: 19-Mar-2022]. ↩︎