Skip to content

Latest commit

 

History

History
336 lines (234 loc) · 8.85 KB

README.md

File metadata and controls

336 lines (234 loc) · 8.85 KB

Benefit Finder v2 React Application

/benefit-finder
  |-.husky
    |-git-hooks
  |-.storybook
  |-cypress
  |-nginx
  |-src
    |-App
    |-shared
      |-api
      |-components
        |-ComponentName
          |-__tests__
            |-__snapshots__
            index.spec.js
            indexComponentName.spec.cy.js
          _index.scss
          index.jsx
          index.stories.jsx
      |-hooks
      |-locales
      |-style-docs
      |-styles
      |-utils
    |-index.jsx
    |-setupTest.js
  |-vite-config
  |-README.md

Basics:

  • "Modules", like App should follow the structure of routes.
  • Files from one module can only import from ancestor folders within the same module or from src/components/shared.

File or folder Description
src/index.jsx Entry file.
index.html All scripts and styles injected here
src/App Main application routes, global / ancestor of all modules.
src/shared/api dev utils for interacting with data
src/shared/components Components, constants, machines, hooks, styles, utils etc;
src/shared/hooks Custom Hooks
src/shared/style-docs mdx files for !stories documentation
src/shared/styles scss partials
src/shared/utils custom Javascript utilities
vite-config.mjs vite bundler config, imports from vite-config dir
Any module is allowed to import from shared.

File Types:

file type Description
.jsx React functional components
.js ES
.stories.jsx Component Story Format files for storybook stories
.mdx Markdown files that accept ES imports for storybook docs
.md Markdown files for project docs
.mjs ES Module File
.spec.js Testing specification
.spec.cy.js Cypress testing specification
.spec.js.snap Testing snapshots
.hbs Handlebars (used in plop generated components)
.scss Syntactically awesome style sheets
.json JavaScript Object Notation
*rc Resource files
*sh Bash files

Getting Started

This project was bootstrapped with Create React App.

Get our packages.

npm install

Setup .env.local file

  1. Copy environment example file
cp .env.local.example .env.local
  1. Replace env variable as needed

Build and serve development environment.

There are three local build environments, one for our component workshop (Storybook), another for our Application (Vite), and finally a test e2e test env (Cypress).

Storybook

Run development workshop

npm run dev:storybook

Vite App

Run development server from vite.config.mjs

npm run dev

Storybook

Run e2e development config

npm cy:dev:storybook

Git Hooks

We use husky to manage git hooks.

husky is automatically installed after the packages are installed.

  • The pre-commit git hook leverages lint-staged to run a series of scripts on any staged files when a commit is made.

  • The pre-push git hook runs a series of scripts on the directory before pushing to the origin.

Coding Standards

We use a combination of linting and best practices to guide code consistency.


Our linters include

js-standard-style react/recommended prettier/recommended stylelint


Linting and Formatting Scripts

We include a few scripts in package.json that can be executed to interact with our standards.

Run eslint on .js and .jsx files

npm run lint:js

Auto-fix lint errors

npm run lint:js:fix

Format .js and .jsx files with prettier.

npm run format

Run stylelint on .scss files

npm run lint:scss

Auto-fix lint errors

npm run lint:scss:fix

Standards outside linting

We also carry the following working agreements that may fall outside of the linting.



1. Avoid functionality in JSX

If you have this...

<Foo onClick={​​​​​​​​function () {​​​​​​​​ alert("1337") }​​​​​​​​}​​​​​​​​ />

We prefer this

<Foo onClick={​​​​​​​​handleAlert}​​​​​​​​ />

2. Avoid inline styles

If you have this...

<Foo style={{ width: 100% }} />

We prefer this

<Foo class="full-width" />

3. PropTypes

Typecheck with PropTypes


4. Styles

We take a utility first approach. We do not have full control over our styles since a custom version of USWDS already exist in the usa.gov project.

  1. we establish uswds components with usa-<class> classes.
  2. this inherits global uswds css and js
  3. IF we need to overide, we clone the uswds class usa- and prepend bf-.
.bf-usa-<class> .usa-<class>
  1. custom classes do not include usa- but still include bf-
.bf-<class>

We use Sass and Sass Modules

Generally, it is recommend that you don’t reuse the same CSS classes across different components. For example, instead of using a .usa-button CSS class in <AcceptButton> and <RejectButton> components, it is recommended to create a <Button> component with its own .usa-button styles, that both <AcceptButton> and <RejectButton> can render (but not inherit).

We use composition, but leverage the https://designsystem.digital.gov/. We will attempt to use pre-processor methods when it makes sense to do so.


5. Code Documentation

We use inline documentation for functions, hooks, and functional components.

Example with function

/**
 * a boolean function that returns a component when true.
 * @function
 * @param {boolean} value - the inherited value, can be true || false
 * @return {component} returns a component if true
 */
const handleTruth = value => value === true && <Truth />

Example with hook

/**
 * a boolean that manages the state of truth.
 * @function
 * @param {boolean} value - the inherited value, can be true || false
 * @return {state} returns an updated state for value
 */
const [value, setValue] = useState(true)

Example with functional component

/**
 * a functional component that wraps form elements in a form element
 * @component
 * @param {node} children - inherited children
 * @return {html} returns a semantic html div element, with all its children
 */
function Value = ({ children }) => (<div className="wrapper">{children}</div>)

5. Testing

We use Vitest for Unit/DOM testing

npm run test

6. Components

We build each of our components with spec, scss, stories and jsx files

|-ComponentName
  |-__tests__
    |-__snapshots__
    index.spec.js
  _index.scss
  index.jsx
  index.stories.jsx

To generate a component with these files based on a name space, you can use plop

cd to the root of the application

npm run generate:component <component-name>

It's important to export components from the root of the shared index file. This is where you will import and destructure across other documents.