2018 Refactor Plans


Status
IN PROGRESS
Outcome
Due date
Owner

Background

Discussion on prioritizing infrastructural improvements to the CMPD Explorers Christmas Project applications based on what we learned in 2017.


What wasn't great

FE/BECategoryWhatExplanationNotes
BothOrganizationInconsistent file / directory namingWith the combination of time constraints & diverse backgrounds, cmpd was never allowed to adopt standard conventions for naming or project structure.  This has added to the complexity of the project making it hard for existing devs to work across different areas and for new devs to quickly become productive.
BothOrganizationNo standard validation patternThere is currently no standard pattern for how validation errors are handled on the server side (what errors to throw, logging, library use, etc.)   
BothArchitectureBuild process is Inconsistent from backend to frontendThe build process for the FE relies on webpack while the BE does not.  Having a streamlined build system means that the two processes don't have to be developed separately.
BothArchitectureFlowtypeFlowtype performance is bad, particularly when using tools like VS Code or even the terminal.  The solution of disabling flow actually leads to an even worse developer experience than not using it at all.
BothArchitectureMissing conventions for things like logging, validation, file naming, etc.

BEArchitectureLack of back end framework
  • Express provides very little standardization
  • Using a framework provides better conventions, more batteries-included may improve churn
BEArchitectureCode and service separationRouting logic and business logic are mixed together.  This is a code smell, and by not decoupling the two we are marrying ourselves to express long-term.
  • We should split the application into more services

Discussion Points

FE/BECategoryWhatExplanationNotes
BothArchitectureRemoving flowtype and migrating our type checking to TypeScript

Using flow makes sense on the front-end but not the back-end.  It would make even less sense to use two different static typing languages for each.  Flow has good React support but TypeScript has better JS community support by a wide margin. Compared to flow, TypeScript has

  • significantly better tooling, especially backend
  • More 3rd party support
  • Higher adoption rate
  • Transpiles JavaScript code (no need to depend on Babel)
  • Needs to be implemented for front-end and back end.
  • Front-end can migrate to create-react-app-ts
  • Almost every 3rd party lib we use has TypeScript types
BEArchitectureBack end framework examinationImplementing node best practices will definitely go a long way to improve the architecture and project structure of the application, but we could do better. We should examine some of the popular frameworks that are extensions or alternatives to express.
  • Potential frameworks (ideas submitted by Ryan Edge)
    • Conventional Option #1
      • apollo-server - a framework agnostic GraphQL server
      • apollo-codegen - a library to generate API code / type annotations based on GraphQL Schemas
    • Conventional Option #2
      • nest: mirrors angular structure on backend (decorators, DI, etc.)
      • typeorm - cross-platform ORM for database access
        • Offers a cleaner, friendlier syntax than sequelize
    • Conventional Option #3
      • fastify - an alternative to express that offers better performance & built-in schema validation.
    • Less Conventional Option
FEArchitectureFE General Refactor
  • Standardize file and directory naming conventions
    • Andrew uses PascalCase for component file names and component directoy names.
    • JSX extension to clarify React.Component vs library file
    • Document naming conventions and best practices in Confluence
FEArchitectureBuild ConfigurationCurrently, we rely on create-react-app which offers us a zero configuration setup at the cost of vendor lock-in.  Should explore fuse-box and webpack as alternatives to this approach.
FEArchitectureBootstrap ReplacementBootstrap isn't a particularly good mobile framework.  It is still pretty heavy, and many of it's components are not reflective of mobile UI trends (switches being a perfect example). There are several alternatives that are equally popular in the community.  We should examine them.
  • Some lightweight mobile-first CSS framework
FEArchitectureReact Alternative

We currently only plan to build CMPD as a web app.  Since there is no plan to target other platforms, we should examine the benefits of using a much slimmer alternative, preact. This will greatly reduce the bundle size of the application...

  • allowing us to experiment more with libraries that may enhance its capabilities.
  • offering significant increases in performance.
This will greatly reduce the bundle size of the application, allowing us to experiment more with libraries that may enhance its capabilities.
FEArchitectureState ManagementWe currently have no pattern for managing global state.  There's inherently nothing wrong with an application that explicitly uses setState and smart components, but we should examine whether or not there's a better pattern for managing state.
FEArchitectureData FetchingThere isn't much benefit to using axios, which was created prior to the implementation of fetch.  We should examine using a library that offer advantages in terms of size gains or enhancements.Use fetch or apollo-client (thru apollo-link-rest)
BothTestingReplacing existing test setup and adding tests

BEArchitectureSeparation of code using additional services
  • We currently have the "auth" and "nominations" services. "nominations" is a bit bloated as it also handles reporting, address tools, and user management. 2018 will see the need for at the least a delivery tracking system which should be built as a separate service as to not impact the existing nomination system, but we may also see the need for additional services as well. Need to decide on an updated project structure, etc.
BothArchitectureImplement Node Best Practices

A major goal for 2018 should be to implement the best practices for a node application that are not currently implemented:

  1. Project Structure
    1. Structure solution by components (link)
    2. Layer components (link)
    3. Wrap common utilities as npm packages (link)
  2. Error Handling Process
    1. Distinguish operational vs programmer errors (link)
    2. Handle errors centrally, not within an Express middleware (link)
    3. Fail fast, validate arguments using a dedicated library (link)
  3. Code Style Practices
    1. Do Require on the folders, not directly on the files

This is not an exhaustive list, but rather a list of some of the important areas where the existing app may be lacking.



Confirmed Action Items

TBD