Getting Started with Front-end Development
This page will show you how to contribute to MetaGrid's front-end. You'll learn about the technologies used, the file structure scheme, and the style guide. Resources are also provided to get new contributors up to speed in the technologies.
Technologies
Core
React UI Library
Formatter and Linter
- Formatter: Prettier
- Linter: ESLint + Airbnb config
Testing/QA
- Jest (with code coverage via Istanbul)
- React Testing Library
DevOps
File Structure
Adapted from sources:
- An Opinionated Guide to React Folder Structure & File Naming
- Optimal File Structure for React Applications
Root
frontend
├── public
│ ├── changelog
│ │ ├── ...previous changelogs
│ │ └── v1.3.4.md
│ ├── messages
│ │ └── metagrid_messages.md
│ ├── favicon.ico
│ ├── index.html
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── api
│ │ ├── index.test.ts
│ │ ├── index.ts
│ │ └── routes.ts
│ ├── assets
│ │ └── img
│ ├── common
│ │ ├── JoyrideTour.test.ts
│ │ ├── JoyrideTour.ts
│ │ ├── reactJoyrideSteps.test.ts
│ │ ├── reactJoyrideSteps.ts
│ │ ├── TourTargets.test.ts
│ │ ├── TourTargets.ts
│ │ ├── types.ts
│ │ ├── utils.test.ts
│ │ └── utils.ts
│ ├── components
│ │ ├── App
│ │ │ ├── recoil
│ │ │ │ └── atoms.ts
│ │ │ ├── App.css
│ │ │ ├── App.test.tsx
│ │ │ └── App.tsx
│ │ ├── Cart
│ │ └── ...
│ ├── contexts
│ │ ├── AuthContext.test.ts
│ │ ├── AuthContext.tsx
│ │ ├── ReactJoyrideContext.test.ts
│ │ ├── ReactJoyrideContext.tsx
│ │ └── types.ts
│ ├── lib
│ │ ├── axios
│ │ │ ├── axios.d.ts
│ │ │ └── index.ts
│ │ ├── keycloak
│ │ │ └── index.ts
│ ├── test
│ │ ├── __mocks__
│ │ │ ├── assetFileMock.js
│ │ │ ├── js-pkce.ts
│ │ │ ├── keycloak-js.tsx
│ │ │ └── ReactMarkdownMock.tsx
│ │ ├── mock
│ │ │ ├── fixtures.ts
│ │ │ ├── mockStorage.ts
│ │ │ ├── server-handlers.test.ts
│ │ │ ├── server-handlers.ts
│ │ │ ├── server.ts
│ │ │ └── setup-env.ts
│ │ ├── custom-render.tsx
│ │ └── jestTestFunction.tsx
│ ├── types
│ │ └── globals.ts
│ ├── index.css
│ ├── index.tsx
│ └── setupTests.ts
├── .dockerignore
├── .eslintrc.js
├── .gitignore
├── .prettierignore
├── .prettierrc
├── Dockerfile
├── index.html
├── Makefile
├── messageData.json
├── nginx.conf
├── package.json
├── README.md
├── tsconfig.json
├── vite.config.js
└── yarn.lock
Dockerfile- The Dockerfile used by docker compose for the frontendpublic/- stores static files used before app is compiledsrc/- where dynamic files reside, the bulk of your work is done hereapi/- contains API related filesindex.ts- contains promise-based HTTP client request functions to APIs, referencesroutes.tsfor API URL endpointsroutes.ts- contains routes to APIs and error-handling
assets/- stores assets used when the app is compiledcommon/- stores common code used between components such as utility functionscomponents/- contains React components and related files. Follow React Components File Structurecontexts/- stores React Context components, such as for authentication statelib/- stores initialized instances of third party library that are exported for use in the codebase (e.g. Axios, Keycloak)test/- contains related files and functions shared among tests__mocks__/- Directory containing mock versions of required dependencies to ensure they work with testsjs-pkce.ts- A mock of the js-pkce.ts library used for Globus transfer stepskeycloak-js.tsx- A mock of the keycloak-js library used for Keycloak authentication
mock/- API mocking using mock-service-worker package to avoid making real requests in test suites. More info herefixtures.ts- stores objects that resemble API response datamockStorage.ts- functions and code that handles persistent storage requests for the test suiteserver-handlers.ts- handles requests to routes by mapping fixtures as responses to each route endpointserver.ts- sets up mock service worker server with server-handlers for tests. Essentially, it creates a mock server that intercepts all requests and handle it as if it were a real server
custom-render.tsx- wraps the react-testing-library render method with contexts from/contextjestTestFunctions.tsx- contains a set of helper functions that are used by various tests
setupTests.ts- configuration for additional test environment settings for jest
.dockerignore- files and folders to ignore when building docker containers.eslintrc.js- configuration file for ESLint.prettierignore- files and folders to ignore when running prettier.prettierrc- configuration file for prettiertsconfig.json- configuration file for TypeScriptyarn.lock- the purpose of a lock file is to lock down the versions of the dependencies specified in a package.json file. This means that in a yarn.lock file, there is an identifier for every dependency and sub dependency that is used for a project
React Components
Below is an example of how MetaGrid scaffolds React components.
frontend
└── src
└── components
├── AComponentWithoutChildren.tsx
└── Facets
├── FacetsForm.test.tsx
├── FacetsForm.tsx
├── index.test.tsx
├── index.tsx
├── ProjectForm.test.tsx
├── ProjectForm.tsx
└── types.ts
File Naming
- React component file names should be PascalCase, descriptive, and relate to the parent component if applicable
- Use named exports over default exports to make searching easier
Grouping/Nesting
- Use a folder to nest child components related to a parent component (e.g.
FacetsForm.tsxis underFacets) -
Use
index.tsxas the file name for the parent component in the group components. This allows you to import the component just by referencing the folder.- If you named the parent component
Facets.tsx, you have to import using:import Facets from '../Facets/Facets.tsx';Avoid this.
- Otherwise, you avoid redundancy by naming the parent component
index.tsx:import Facets from '../Facets';
- If you named the parent component
- Why not nest child components even further in their own directories? Because too much nesting makes the
/componentsdirectory complicated to navigate.
Test Files
- Each testable file and component typically has an associated
.ts/.tsxfile (e.g.FacetsForm.test.tsx). This is determined by what you need to test via the code coverage report.
Style Guide
The MetaGrid front-end follows the Airbnb JavaScript and React/JSX style guides. Please spend some time to read through the style guides.
Style guide and linting rules are enforced in CI test builds.
Useful React Commands
Run a command inside the docker container:
docker compose run --rm react [command]
yarn start
Runs the app in the development mode using the Vite dev server
Open http://localhost:9443 to view it in the browser.
The page will reload if you make edits.
You will also see any lint errors in the console.
yarn test
Launches the test runner for a single run without coverage report.
See the section about running tests for more information.
yarn test:coverage
Launches the test runner for a single run with coverage reporting.
See the section about running tests with coverage for more information.
yarn test:watch
Launches the test runner in the interactive watch mode.
See the section about running tests for more information.
yarn lint
Runs linters to display violations.
yarn precommit
Runs linters against staged git files and attempts to fix as many issues as possible.
https://github.com/okonet/lint-staged
yarn run build
Builds the app for production to the build folder.
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.
Your app is ready to be deployed!
See the section about deployment for more information.
New Contributor Resources
Here are some resources to get you up to speed with the technologies.
Documentation
Courses
- Free React Bootcamp - a four day course that covers the in's and out's of React, starting from a high level overview
- React team's recommended courses list