Permalink
Branch: master
Find file Copy path
2d1adab Jan 15, 2019
1 contributor

Users who have contributed to this file

145 lines (98 sloc) 12.7 KB

Front-End Technical Vision

The following document is a guide for all future Magento front-end applications outside of core, for which we should be mindful of the following values:

  • Portability
  • Extensibility
  • Maintainability
  • Consistency
  • Performance
  • Accessibility
  • Internationalization
  • Productivity (Efficiency)
  • Quality (Reliability)

React

Portability, Performance, Productivity, Quality, Internationalization.

React's continued growth and popularity coupled with its solid documentation make it an excellent choice for building user interfaces. If written appropriately, it enables portability by crossing over into native applications with React Native.

Performance is easy to achieve with React, because it only re-renders DOM elements where and when necessary. That's not to say that React prevents you from creating performance problems, but the docs do well at explaining what to avoid and how to profile.

Creating a new React project has never been easier with CRA, which comes out-of-the-box with hot reloading. This increases productivity by giving developers short, positive feedback loops. Hot reloading is also achievable in React Native. Another opportunity for short, positive feedback loops is testing with Jest and Enzyme. Tests are fastest when writing unit tests with the Shallow Rendering API and reserving the Full Rendering API for integration tests. The better the development experience in these cycles, the better quality we achieve as a result. Jest's snapshot testing is another way to ensure quality in that we don't inadvertently introduce breaking changes.

Technologies

  • Create a new React project with CRA.
  • Redux as a predictable state container.
  • Internationalization with react-intl.
    • Warning: the documented path here is to couple the components to this library. This will be fine for most projects, but if ultimate portability is required, you will need to decouple the component from the i18n library.

TypeScript

Maintainability, Productivity, Quality, Consistency.

TypeScript is not going to solve all of our problems, but its static typing features definitely have the potential to improve the quality of the code we produce. TypeScript code is also easier to maintain, because it purposefully makes it more difficult to inadvertently break something that was already defined to work a certain way. As a superset of JavaScript, it allows us to leverage both the JavaScript ecosystem as well as any existing developer knowledge. It also happens to work quite well with React and JSX syntax, replacing prop-types (run-time) with TypeScript Interfaces (compile-time).

Types and interfaces are only a compile-time construct and have no effect on the generated code.

Catching errors at compile time also increases productivity, because we don't have to run the development server to see the errors. In fact, we can see them directly in the editor before anything is run. Additionally, Microsoft has open sourced the TypeScript Language Service API, which is used across the most popular editors of today. As a result, you'll see consistent errors between these editors.

Type definitions are provided for many of the most popular npm packages, meaning developers can increase productivity by staying in-editor instead of constantly task switching and looking up documentation online. Even internally, there is less need to open a local file when you can extract most of the relevant information you need via Intellisense.

Disclaimer: though possible to introduce TypeScript into an existing CRA app and though TypeScript can co-exist with JavaScript, it may not make sense to introduce it into an existing project if you feel it may hinder momentum.

Technologies

Portability

We should prepare to achieve as much code sharing as possible, regardless of environment. JavaScript is the only language that can run natively in all browsers; yet, it also transcends the browser, running on servers and even native mobile applications. As such, the golden path for sharing code starts with JavaScript. By writing components in a decoupled way, we don't limit ourselves as to where those components can run.

On top of sharing code between different environments, we should also be concerned about sharing code between projects. For this, we should introduce a business logic repository that includes common helper functions – logic that we're likely to use between projects.

Business Logic Repository

  1. Written and documented in TypeScript.
  2. Semantic versioning to ensure that progress can be made without breaking things for existing - consumers.
  3. 100% unit test coverage via Jest for consistency.

For performance reasons, JavaScript should only be used for cheap operations on the front end, reserving expensive operations for a services layer. It's worth calling out that we could achieve even more code sharing if this API were written in JavaScript. For practical reasons, however, it makes more sense to leverage internal PHP resources for this task.

Browser Support

All users should have a consistent user experience. For the best performance, those with the latest browsers should not be penalized by incurring an additional payload hit than those with older browsers.

There are various ways to achieve this goal; however, an in-house approach might be warranted to prevent the stability issues of relying on 3rd party resources. One idea would be to publish multiple build targets, tailored to various environments.

React UI Component Library

Consistency, Productivity, Scalability, Maintainability, Accessibility.

We should lean against downloading various UI components from different sources for the following reasons:

  • Inconsistent implementations, documentation, theming and customization.
  • Limited accessibility and support.

If you have the budget to pay for a product, it might be a good choice in this space. Why? Because it's much better to get all of your components from a single source than to have completely different paradigms scattered everywhere.

Disclaimer: there may be licensing limitations that prevent an open-source product from implementing a paid-for product.

Downloading a 3rd-party package

There are times when you may consider downloading a 3rd party package (e.g., a component). When this happens, consider the following criteria before making a final choice:

  1. First thing's first – what is the license?
    • Is it open source?
    • You may need to reach out to your legal department if things are a bit blurry.
  2. Does the package have a bright future?
    • Popularity – are there a significant number of weekly downloads?
    • Is the downloads line graph going up or down?
  3. Look for tests, ideally with 100% test coverage.
  4. Look at the bundle size with Bundle Phobia.
  5. Does it have good/clear documentation?
  6. Is it currently maintained?
    • Look at the number of issues vs. pull requests.
    • How long have these issues and PRs been open?
    • When was the last comment made on them and by whom?
    • Reliability – how serious are the issues?
  7. Search and compare this package with other similar packages to gauge which package is the best choice and feel free to reach out to other team members for guidance.

Resources

Styles

Bundle optimization works best when CSS Modules are imported directly into the JavaScript components that use them (a better TypeScript experience is being talked about in this CRA issue).

The coupling here is a bit unfortunate for some projects (e.g., libraries), but pretty standard for applications. For ultimate portability, reusable components should be provided their styles externally.

Resources

Code Quality

Quality, Maintainability, Productivity.

We should leverage the built-in code coverage reports that Jest provides, but also the following GitHub integrations/apps:

  • Continuous integration with Travis-CI.
  • CodeClimate
    • Quality by Code Climate provides automated code review for test coverage, maintainability and more so that you can save time and merge with confidence.
    • Code Climate’s engineering process insights and automated code review for GitHub and GitHub Enterprise help you ship better software, faster.

Resources

Performance Testing

Ideally, for each front-end project, there will be a separate project that covers both performance and critical-path testing. This project is separate so that it doesn't cripple the short feedback loops of feature development. Additionally, we would do well to have additional performance testing around the most commonly used components (e.g., used in 3+ places).