Create a gist now

Instantly share code, notes, and snippets.

@jchiatt /readme.md Secret
Created Jul 30, 2018

Embed
What would you like to do?
Trinity README

Trinity Frontend — 2018

Frontend for the 2018 rewrite. Powered by React and good style.

Table of Contents

Setup

The TL;DR

  1. Node v8.11.3
  2. npm install && npm start
  3. Profit?

Assuming you have Node 8.11.3 installed on your machine, cd into the directory you want to clone the project, and copy, paste, and run the following:

git clone <REDACTED> && cd <REDACTED> && npm install && npm start

Installing Node & Nodenv

This project uses Node 8.11.3.

You can install Node directly from the Node website, but this is not recommended. Instead, we recommend using a version manager, such as Nodenv (recommended) or NVM.

We recommend you install via the "Basic Github Checkout" option instead of Homebrew. Windows Subsystem for Linux note: Modify your ~/.profile instead of ~/.bash_profile, as ~/.profile seems to be the default shell profile in WSL (or at least, this was our experience while installing Nodenv on Tyler's computer).

Installing the Project

Once you've installed 8.11.3, cd into the directory in which you want to clone this repo and run:

<REDACTED>

If you're using nodenv, it will utilize the .node-version file in the repo to know what Node version (8.11.3) to use for all Node/NPM commands you run — no manual version switching required. 🎊

Lastly, install all the project dependencies with npm install.

Sanity Check

You can ensure everything is working properly by running npm start — you should see the app build in your shell and then your web browser should open automatically. If it doesn't, refer to the Troubleshooting section below.

The Stack

React

Use: UI Layer

React is one of the best modern JS libraries for creating user interfaces. Its "learn once, write anywhere" approach is really powerful, especially here at Trinity where we have multiple interfaces, including multiple web applications and multiple mobile applications.

At the end of the day, writing React is mostly just writing pure JavaScript, so there are pure JavaScript resources below in addition to React-specific resources.

Resources

  • React Docs - The docs are really good.
  • React for Beginners - Course by Wes Bos. Everything you need to know to understand how React works and reason about React components.
  • Awesome React - A collection of awesome things in the React ecosystem.
  • ES6 for Everyone - Course by Wes Bos. Also includes ES7 and ES8.
  • You Don't Know JS - Book Series by Kyle Simpson.
  • JavaScript 30 - Great course by Wes Bos. Build a thing a day for 30 days using pure JavaScript.

Redux

Use: State Management

Redux is a predictable state container for JavaScript apps. It's based on the Flux architecture from Facebook, but uses a single, immutable store rather than multiple stores.

Redux was chosen for state management for three main reasons:

  1. It's predictable. We're able to determine what the state of our app will be at any given point with a high degree of certainty. This gives us confidence in our UI and also makes things really easy to test (since everything dealing with state is a pure function).

  2. The developer experience is amazing. Because we have an immutable state tree, we are able to have nice things. Like a Time Traveling Debugger.

  3. It's very well documented. Redux has been around for 3 years now, which is forever in the world of frontend. It's battle-tested, and there's a ton of articles, videos, and helpful chatrooms if we are ever stuck on something or have a specific use case we want to learn more about. This is really important since there are currently only two people who have experience with this stack and they're both juniors.

Why not just use React's Context API?

This was considered, but ultimately the immutability, dev tools, and documentation made Redux the winner. Plus, sticking to React's internal state management would still make us reach for a helper library when dealing with async operations. Redux Thunk makes this very easy.

Resources

  • Redux Docs - These are really good, too. Dan Abramov knows how to make good documentation.
  • Redux & React For Everyone - Perhaps the single best course I've found for quickly learning Redux. Pair it with his React 16 For Everyone course before doing the Redux one for power levels over 9000.
  • Learn Redux - Great course from Wes Bos. A little out of date in terms of the API, but still great for grasping the concepts.

Parcel

Parcel is a zero-configuration bundler. Out of the box, it has code splitting, hot module replacement, automatic transforms, friendly error logging, and it bundles pretty much any type of asset you throw at it. It's also really fast.

Parcel was chosen over Webpack simply because of time constraints. Webpack may very well be used in the future, but Parcel allowed us to get up and running much faster.

Resources

CSS

There was a lot of things to consider in terms of CSS. An overwhelming amount, actually:

Ultimately, here's what we went with and why:

  1. Material UI — Material seemed to be a great choice based on the bandwidth our [one] designer, Ryan, has. We may hit the big leagues one day and have our own design system, but for now Material provides a ton of great designs and microinteractions that would require a lot of time to design and build out from scratch. To date, we are using base material elements.

  2. Styled Components - Styled Components is a CSS-in-JS library that makes writing CSS in React a pure joy. Material UI integrates really well with it as well.

  3. PostCSS — We're currently only using PostCSS to do some basic transforms with CSS Next so we can use new CSS properties. We still write fallbacks for IE, as you'll see in the codebase.

  4. Flexbox and CSS Grid - There's good support for these, except not fully in IE11 (but they are nearly fully supported in IE11). Just be sure to test in IE and reference their known bugs (see Flexbox and CSS Grid on Can I Use).

Things to still consider in the future:

  • To BEM, or not to BEM?
  • ITCSS? (a fantastic way to keep specificity low, even with a YUGE codebase - may not be necessary since Styled Components inherently solves scoping collisions)

Resources

Testing

Jest

Our testing library of choice is Jest.

Resources

Storybook

Storybook is a development environment for UI components. It allows you to browse a component library, view the different states of each component, and interactively develop and test components. Really improves team productivity and efficiency, especially between frontend engineers and designers.

Resources

Linters, Type Checkers, Editor Configuration

Airbnb hands down has one of the best JavaScript style guides, so that's what was chosen to get up and running with a sensible configuration very quickly. We also use prettier to automagically make our code pretty. 💅

For type checking, we are currently using React's Prop Types, although we also have Flow integrated (in a very basic way). Flow is a static type checking library that allows you to type both your props and your state, as well as catch issues very early instead of at runtime. The goal is to migrate our typing to Flow after finishing Parts Ordering.

Resources

VS Code

My editor of choice is currently Visual Studio Code. Here's a link to my settings (some of the settings are specific to me — if you are unsure, just ask!).

Here's the relevant extensions I have installed:

And here's the other extensions I have installed, in case you're curious:

Project Structure

Folder Structure

The main folder of concern is src. It contains the entire source of the app. We use feature folders, here's an example:

src/auth
├── PrivateRoute.js
├── actions.js
├── authService.js
├── config.js
├── constants.js
├── reducer.js
└── setAuthorizationHeader.js

As you can see, everything needed for auth can be found in this one folder, including components, reducers, actions, helper functions, etc.

Available Scripts

npm dev

Uses Concurrently to start the mock-api, storybook, and parcel dev server.

// package-json
"dev": "concurrently \"npm:json\" \"npm:storybook\" \"npm:start\"",

npm run json

Spins up a mock API via the json-server package. Data is loaded from /test-data.

// package.json
"json": "json-server --watch ./test-data/db.json --routes ./test-data/routes.json",

npm start

Builds the app, runs the development server, and opens your default web browser to http://localhost:1234.

//package.json
"start": "parcel ./public/index.html --open",

npm run build

Builds the app in production mode (minifies, uglifies, disables Hot Module Replacement). Output is found in /dist/

//package.json
"build": "parcel build ./public/index.html",

npm run lint

Runs ESLint on the codebase and outputs any warnings or errors. Note that it does not fix the issues.

//package.json
"lint": "eslint .",

npm run lintfix

Runs ESLint and automagically fixes violations, where possible.

//package.json
"lintfix": "eslint . --fix",

npm run flow

Runs Flow on the codebase and reports any Type errors.

//package.json
"flow": "flow",

npm test

Runs tests with Jest.

//package.json
"test": "jest",

npm run storybook

Starts Storybook at http://localhost:6006.

//package.json
"storybook": "start-storybook -p 6006",

npm run build-storybook

Builds storybook into a static, production-ready bundle and outputs the build into /storybook-static. This folder currently automatically deploys to https://idpbp-storybook.netlify.com/ every time there's a push to master.

//package.json
"build-storybook": "build-storybook --output-dir dist-storybook",

npm run fixparcel

Removes Parcels .cache directory and starts Parcel. Useful if the app starts randomly failing to load in development mode and is outputting obscure errors. (See this question in the Troubleshooting section)

//package.json
"fixparcel": "rm -rf ./cache && npm start"

Git

Naming Branches

  1. Production Branch: master (do not push directly to this branch)
  2. When working on a feature or fix, create a branch with your name + a short description of the feature: jc/parts_ordering

Rules

  1. Do not push directly to master
  2. When you're ready to merge a branch, make a Pull Request, assign a reviewer (J.C. or Tyler), and assign it to J.C.
  3. Ensure your commits are relevant to the branch you are on

Creating Issues

When should I create an issue?

TL;DR — Create an issue.

  • Something need to be done? Create an issue.
  • Got an idea for an enhancement? Create an issue.
  • Something broken that wasn't before? Create an issue.
  • Something missing from the docs? Create an issue.

Rules

  1. Describe how to reproduce the issue in detail. Be descriptive — err on the side of more details.
  2. Provide relevant logs, code, etc.
  3. Screenshots are great!
  4. Screencasts are even better!

Troubleshooting

Parcel is building successfully, but I'm getting obscure errors in my browser console and a blank screen.

If the frontend suddenly serves a blank page, try deleting the .cache folder and re-running npm start (or you can run npm run fixparcel as a shortcut) — there's currently an occasional issue with Parcel that may cause this. It doesn't happen often, and typically only occurs when installing new packages (but not every time ¯\_(ツ)_/¯).

I'm getting a Command not found error when attempting to run a script from a package that is installed in package.json

Sometimes you may want to run parcel as a standalone command in your shell. If you get a Command not found error, double check the package is installed globally. For example, if you're trying to run parcel, you can run npm install -g parcel to install Parcel globally.

If that doesn't fix the issue, try running nodenv rehash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment