Crema App - Web 🌐
This project includes configuration and tooling that conforms to Crema's baseline best-practices for a Web Application.
🧰 Tools Used
- Create React App for simple configuration 😅
- Cypress for end-to-end testing
- ESLint for code linting
- Hygen for component and util generators
- Jest for unit tests
- Loki for visual testing
- Prettier for code formatting (via ESLint plugin)
- Storybook for component playground (and used by Loki)
- TypeScript for Static Typing in JavaScript (Learn)
🏗 Setup
- Install NVM (Node Version Manager)
nvm install 'lts/*' && nvm use
npm i
(install project dependencies)- Install the ESLint plugin for
your editorVS Code and enable "Fix on Save" insettings.json
:{ "editor.codeActionsOnSave": { "source.fixAll.eslint": true } }
Go to settings (
⌘ + ,
), searchcodeActionsOnSave
and click "Edit in settings.json", then add"editor.codeActionsOnSave": {...}
within the existing JSON object."But I don't use VS Code." That's fine but you're on your own. 😅
- Install Docker Desktop
- Used by Loki
👟 Run
Run the following scripts with npm run <SCRIPT_HERE>
:
start
- start appnew:component
- generate a new componentnew:util
- generate a new util(ity)test:analyze
- run bundle analyzertest:deps
- run dependency validation teststest:e2e
- run end-to-end teststest:lint:fix
- run linter and fix if possibletest:lint
- run lintertest:playground
- run component playground (storybook)test:unit:coverage
- run unit tests with coveragetest:unit
- run unit teststest:visual:approve
- approve visual changestest:visual:update
- update or create visual referencestest:visual
- run visual tests (loki)deps:graph
- run dependency validation and generate an SVG representing the dependency graph (requiresgraphviz
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
Below is the project's file-tree with notes added as inline comments.
Uninteresting info is denoted by
...
.
├── .github # 👈 PR/Issue Templates, workflows, and Renovate config
├── .loki # 👈 Loki provides visual regression testing of Storybook files
│ ├── current # 👈 Images from current test run
│ │ └── chrome_App_Example.png
│ ├── difference # 👈 Differences from current test run
│ ├── reference # 👈 Approved reference images
│ │ └── chrome_App_Example.png
│ └── .gitignore # 👈 `./current` and `./difference` are not tracked
├── .storybook # 👈 Storybook config
├── cypress # 👈 Cypress integration testing
│ ├── fixtures # 👈 Test data
│ │ └── example.json
│ ├── integration # 👈 Tests go here
│ │ └── sample_spec.ts
│ └── ...
├── public # 👈 Static files
├── src
│ ├── assets # 👈 fonts, images, etc.
│ │ └── logo.svg
│ ├── components # 👈 Use `npm run new:component` to generate
│ │ ├── App
│ │ │ ├── README.md # 👈 Every component has a README
│ │ │ ├── index.tsx # 👈 Contains main implementation
│ │ │ ├── stories.tsx # 👈 Component stories; use `npm run test:playground` to run
│ │ │ ├── styles.css # 👈 Component styles (not included in generated code)
│ │ │ └── test.tsx # 👈 Component tests; use `npm run test:unit` to run
│ │ └── README.md # 👈 Every top-level directory in `src` has a README.md
│ ├── types # 👈 Type definitions go here; use `npm run new:type` to generate
│ │ └── README.md
│ ├── utils # 👈 Utilities go here; use `npm run new:util` to generate
│ │ └── README.md
│ ├── index.css # 👈 Root styles
│ ├── index.tsx # 👈 Root application file
│ ├── react-app-env.d.ts # 👈 Extends react-scripts TypeScript definitions
│ ├── reportWebVitals.ts # 👈 Useful, but not required
│ ├── serviceWorker.ts # 👈 Useful, but not required
│ └── setupTests.ts # 👈 Top-level setup for Jest test runs
├── .dependency-cruiser.js # 👈 Dependency Cruiser config
├── .eslintrc.js # 👈 ESLint - Run Commands
├── .gitattributes # 👈 Git meta information
├── .gitignore # 👈 Git ignore patterns
├── .nvmrc # 👈 Node Version Manager - Run Commands
├── .prettierrc.js # 👈 Prettier - Run Commands
├── LICENSE # 👈 LICENSE 😜
├── README.md # 👈 👈 👈 YOU ARE HERE
├── cypress.json # 👈 Cypress config
├── package-lock.json
├── package.json
└── tsconfig.json # 👈 TypeScript config and extends
🥇 Best Practices
- Use the code generators:
npm run new:component
npm run new:type
npm run new:util
- 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 👭.