Crema App - Web 🌐

Build Status codecov License: MIT

This project includes configuration and tooling that conforms to Crema's baseline best-practices for a Web Application.

🧰 Tools Used

🏗 Setup

  1. Install Node/NPM
  2. Install NVM (Node Version Manager)
  3. nvm install 'lts/*' && nvm use
  4. npm i (install project dependencies)
  5. Install the ESLint plugin for your editor VS Code
  6. Enable "Auto-Fix on Save" in settings.json:
// There will likely be other settings within this JSON object...
{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ]
}
  1. Install Docker Desktop

👟 Run

Run the following scripts with npm run <SCRIPT_HERE>:

  • start - start app
  • new:component - generate a new component
  • new:util - generate a new util(ity)
  • test:analyze - run bundle analyzer
  • test:deps - run dependency validation tests
  • test:e2e - run end-to-end tests
  • test:lint:fix - run linter and fix if possible
  • test:lint - run linter
  • test:playground - run component playground (storybook)
  • test:unit:coverage - run unit tests with coverage
  • test:unit - run unit tests
  • test:visual:approve - approve visual changes
  • test:visual:update - update or create visual references
  • test:visual - run visual tests (loki)
  • deps:graph - run dependency validation and generate an SVG representing the dependency graph (requires graphviz to be installed on your device)
  • deps:report - run dependency validation and generate an HTML report

These scripts are located in package.json and do not represent the entirety of available scripts, but are the most commonly used.

🏛 Structure

The src directory is where the meat of your app is located. Below is a printout of its file-tree with a description for each part.

src
├── assets // Fonts, Images, Etc.
│   └── logo.svg
├── components // Create a new one with `npm run new:component`
│   └── App
│       ├── __snapshots__ // Generated by Jest from `test.tsx`
│       │   └── test.tsx.snap
│       ├── README.md // Documentation
│       ├── index.css // Styles
│       ├── index.tsx // Main Module Code
│       ├── stories.tsx // Playground stories (npm run test:playground)
│       └── test.tsx // Unit Tests (Jest)
├── types // Centralize Type Definitions
│   ├── Entity.ts // Base Type
│   ├── EntityThing.ts // A Sub-Type
│   ├── Id.ts // A Type Alias of `string`
│   ├── MapStateToProps.ts // Includes our `State`
│   ├── State.ts // Redux state interface
│   └── Thing.ts // Silly example used by `EntityThing`
├── utils // Create a new one with `npm run new:util`
│   ├── mySpecialUtil
│   │   ├── __snapshots__ // Generated by Jest from `test.ts`
│   │   │   └── test.tsx.snap
│   │   ├── README.md // Documentation
│   │   ├── index.tsx // Main Module Code
│   │   └── test.tsx // Unit Tests (Jest)
│   ├── decoratorCentered // Used in stories.tsx
│   └── shallowRender // Used to render components in test.tsx
├── index.css // Root Styles
├── index.tsx // Root Module
├── react-app-env.d.ts // Definitions from create-react-app
└── serviceWorker.ts // Documentation

🥇 Best Practices

  • Use the code generators:
    • npm run new:component
    • npm run new:util
    • When prompted for a name, prefer camelCase for utils and CamelCase for components
  • Fill out the README.md to describe what your code does
  • Run your unit tests npm run test:unit while working to see immediate feedback
  • If you get stuck at any point, just log an issue and we'll figure it out together 👭.