React Project - Idea to Production - Part One - Wireframes and Project Setup

Tue May 12 20209 min read

What are trying to achieve

We as developers like writing code. Given a choice I will write code whole day emoji-computer. But writing code is only part of the job description. As engineers we are expected to build stuff and provide solutions. Writing code is only a part of it. I have met amazing developers who can write React way better than me. I have met designers and product guys who can come up with innovative ideas and design it to pixel perfect detail.

All of them being good in what they do, struggle in understanding how all this fits together in a software.

This is NOT a frontend tutorial about React, Design Systems or JavaScript. There are smarter people with better tutorials than this post.

What we are trying to do is to see how to take an idea from wireframe to production with automated tests and Continous Integration and Continous Deployment (CI / CD). emoji-rocket

TL;DR

This is a 4 part post

Source Code is available here

Component Library Demo is available here

Movie App Demo is available here

The Idea emoji-bulb

Lets say we came up the brilliant idea to build a movie app. We have no idea something like IMDB exists. So we get together an awesome team to build this Web application.

The Requirements

So the team wants to start simple, so we agree on building only 3 features for the MVP.

The Landing Page

This will be the face of our product. The user should be able to see these features

  • Search Functionality: User should be able to search any movie
  • Featured Movies: App should be able to promote some movies
  • Popular People: Show the most popular people this week in the entertainment industry

The Movie Profile Page

The user can navigate to this page to see the details of the movie. This page should highlight these basic details about the movie

  • Movie Details and Metadata
  • Movie Rating
  • Movie Poster
  • Movie Trailer
  • Movie Cast
  • Similar Movies

The Actor Bio Page

This user can navigate to this page to see the details of an Movie Actor. This page should highlight the basic details of the actor.

  • Actor Details and Info
  • Actor Photo
  • Actor Bio
  • Movie Acted

The Wireframes

Before we start hacking code, a lot of work goes in design phase where our awesome UX designers come up the designs which we will be building. As I am not a UX designer, I will spare you from my horrible sketch skills and proceed with wireframes for now.

Landing Page Wireframe

Movie App Landing Page Wireframe

Movie Profile Page Wireframe

Movie Profile Page Wireframe

Actor Bio Page Wireframe

Actor Bio Page Wireframe

Project Setup

Now we have the wireframes ready, lets get our project setup.

Create a Github Project

Github Project Page

Setting up Project on our development machine

So there are many ways to skin the chicken. I personally prefer a Monorepo. Some of you may hate monorepo and some of you may love it, the war is never ending. Lengths of blogs and documents are written on the benefits and perils of using a monorepo. Sometimes pros outweigh the cons, and sometime it is the other way round. For your next company project, I would suggest to figure out whether mono or multi repo fits your requirement.

For the sake of this demo let’s go ahead with a monorepo.

For our monorepo we are going to use Lerna for high-level management, and yarn workspaces for low level package management. Again there is pretty good literature available for this setup which I would strongly suggest to read.

If yarn workspaces are not enabled, lets first enable it.

yarn config set workspaces-experimental true

Lets clone the repository

git clone git@github.com:debojitroy/movie-app.git
cd movie-app

Lets not pollute the master and move to a separate branch

git checkout -b setting-it-up

Initialize the project

yarn init

Add Lerna as a dev dependency

yarn add lerna --dev

Once Lerna is added, it is time to initialize Lerna

lerna init

This should create packages folder and lerna.json

Now as we don’t want to publish everything to npm simulataneously and would prefer yarn as our default client. We would also be using yarn workspaces, so we need to make some changes to lerna.json

{
  "packages": ["packages/*"],
  "version": "independent",
  "npmClient": "yarn",
  "useWorkspaces": true
}

Now we gotta enable yarn workspaces, so we need to add these few lines to our root package.json

"workspaces": [
     "packages/*"
  ]

Point to note, packages is the default name for the folder and you can name it anything you want. If you are changing the name, then make sure to update both lerna.json and package.json

Ok so our root project is setup now, lets commit our work and sync it to github. Always a good idea to do it.

git add .
git commit -m "Setting up root project"
git push --set-upstream origin setting-it-up

Setting up Linting and Commit Hooks

Before we move ahead and start writing code, we should take care of one more necessary evil - Linting and Commit Hooks.

We always end up adding lint rules and commit hooks way down the line in our developement cycle and then spend ages fixing the errors. So in my recent projects I have decided to turn the tables around and set it up before I start writing code. You can always add more checks as the project progresses, but based on what we know, we should have the baseline rules in place.

So what we know about our Application

  • It will be a React Application
  • We will be using TypeScript
  • We may have a mix of JS and TS Files

So with the starting knowledge of how our application will look like, we can decided on our tools.

Tools we are going to use

As with any frontend project, there are so many ways to implement coding standards across the team. Tools for the job also differ based on the requirements. I have found a combination of tools to work best for me, and as I have the luxury to choose my tools, I will be using these

Now lets go ahead and add these tools

yarn add eslint --dev

When you will run this command, you will see this error

error Running this command will add the dependency to the workspace root rather than the workspace itself, which might not be what you want - if you really meant it, make it explicit by running this command again with the -W flag (or --ignore-workspace-root-check).

This is yarn warning us that we should not be adding dependencies in the root project. The warning is perfectly valid as we shouln’t add packages to the root project. But this a special case, where we want to enforce project level rules, so it is safe to override the warning and go ahead with -W flag.

So running it again

yarn add eslint --dev -W

Adding Prettier and Husky as well

yarn add prettier husky --dev -W

Adding ESLint Plugins

Now as we want to use ESLint with custom setup, we need to add plugins.

We want to run linting whenever some file is staged.

yarn add lint-staged --dev -W

We want to ESLint to behave nicely with Prettier.

yarn add eslint-config-prettier eslint-plugin-prettier --dev -W

We want to ESLint to understand React syntax and JSX format.

yarn add babel-eslint eslint-plugin-react eslint-plugin-react-hooks --dev -W

Finally, we want TypeScript and ESLint to understand our TypeScript syntax.

yarn add typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser --dev -W

Nearly there…

Now lets configure our linter and formatter

Configuring Prettier

Now to configure Prettier, lets create a .prettierrc file and add these rules. Again, these are my rules, feel free to configure it as per your requirement.

{
  "bracketSpacing": true,
  "jsxBracketSameLine": false,
  "printWidth": 80,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "useTabs": true
}

Configuring ESLint

Re-visiting the rules again

  • Our code base will be mostly TypeScript
  • We will be writing React Code
  • We will be using latest React stuff including Hooks
  • We may have some .js and .jsx files as well
  • We want Prettier to work with ESLint.

With these rules in place, let’s go ahead an create a .eslintrc.js file.

module.exports = {
  parser: "@typescript-eslint/parser",
  extends: [
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier/@typescript-eslint",
    "plugin:prettier/recommended",
  ],
  parserOptions: {
    ecmaVersion: 2018,
    sourceType: "module",
  },
  plugins: ["react-hooks"],
  rules: {
    "react/prop-types": [0],
    "react/forbid-prop-types": [0],
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn",
    "@typescript-eslint/explicit-function-return-type": "off",
    "@typescript-eslint/no-explicit-any": "off",
  },
  settings: {
    react: {
      version: "detect",
    },
  },
  overrides: [
    {
      files: ["**/*.js", "**/*.jsx"],
      parser: "babel-eslint",
      extends: ["plugin:react/recommended", "plugin:prettier/recommended"],
      plugins: ["react-hooks"],
      rules: {
        "react-hooks/rules-of-hooks": "error",
        "react-hooks/exhaustive-deps": "warn",
      },
      settings: {
        react: {
          version: "detect",
        },
      },
    },
  ],
}

We have turned off some of the TypeScript lint checks for our project. This is optional and you can remove them if you want.

Now we dont want ESLint to lint our CSS and compiled files. So we will add .eslintignore file and add ignored paths.

dist
lib
cdn
src/styles
*.d.ts

Getting our lint together

Ok we are nearly there. Final step is to get everything together. Now moving on to our package.json

Let’s add our rules for staged files. Add a section to package.json

"lint-staged": {
    "packages/**/*.{js,ts,jsx,tsx}": [
      "eslint --color --fix"
    ]
  }

Finally adding our pre-commit hook using husky

"husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  }

Testing it all works together

Now is the time of truth. Lets see if everything works together.

git add .
git commit -m "Setting up Code Standards and Lint Rules"

If everything was setup correctly, you should be seeing a message like this

husky > pre-commit (node v12.11.1)
ℹ No staged files match any configured task.

If you see this message, congratulations you have setup linting and code formatting with commit hooks correctly emoji-tada emoji-tada emoji-tada

Push your changes to Github and lets continue with writing some code.

To find out what happens next, continue to Part Two : Breaking Wireframes to Components and setting up a Component Library

javascript

reactjs

typescript

monorepo

Built using Gatsby