- Yarn 1.15 or newer
- Node 13.11 or newer (you can use NVM to manage Node versions)
It's important to use Yarn instead of NPM, because we use Yarn Workspaces not supported by NPM.
The frontend side of the project consists of tho main applications: app and admin.
If you want to quickly start introducing changes to the app:
-
Create an
.envfile with environment variables insideappandadmindirectories (seeapp/.env.exampleandadmin/.env.examplefor required configuration and explanation). -
Run set of commands from the root directory of the project.
# Skip this if you have correct Node version installed globally.
> nvm use
# Install and link dependencies, register pre-commit hooks.
> yarn
# Run build process in packages that need compilation steps to work.
> npx lerna run lib
# Run app and/or admin in development mode.
> (cd app && yarn dev)
> (cd admin && yarn dev)The main technologies used are: React, Next.js, Typescript and Tailwind (as a styling library).
Javascript part of project is organised into separate packages. We use Yarn Workspaces to enable code sharing between them. An example can be an ESLint package that is abstracted to a reusable module that can be used for linting source code enforcing identical rules for each part of the project.
This is a Next.js app that serves landing page, developers page, and students page for the project.
The development server runs on port 3001 by default. You can change the port from the command line:
# Assuming you are in app directory.
> PORT=4000 yarn devThis is a Next app powered by React Admin that serves the teachers page, also called admin page, for the project.
The development server runs on port 3002 by default. You can change the port from the command line:
# Assuming you are in admin directory.
> PORT=4000 yarn devHere we have an ESLint config along with a CLI for linting a Typescript/Javascript modules. The main purpose of this is to have a single configuration file that can be reused in many places, when the application grows.
# Install it in package where you want to use it.
> yarn add --dev --exact @project/eslint@1.0.0
# Lint the source code using predefined rules.
> npx project-eslint --ext '.js,.ts' srcBasically it has the same purpose as
packages/eslintbut for running unit tests.
# Install it in package where you want to use it.
# This will also install some external dependencies, like @testing-library/react,
# so you can test React components without any extra steps.
> yarn add --dev --exact @project/jest@1.0.0
# Run unit tests with predefined configuration.
# It requires tests to be placed in .spec.js (or .spec.jsx) files.
> npx project-jestIf you need, for some reason, customised configuration for your package, you can just create a jest.config.js file and setup Jest from there. Like in this example:
const config = require("@project/jest");
module.exports = Object.assign({}, config, {
collectCoverage: false,
});Always try to consider updating reusable config if the changes can be applied for the whole project.
Changes to app and admin project are automatically deployed to Heroku App and Heroku Admin after a pull request is merged to master branch. It's worth pointing out that changes not related to the above-mentioned (like updating API code) do not trigger a new deployment.
You can create production build locally for both admin and app by running the
yarn build script
in both of these directories
Here we describe some convention we want to have for the Javascript codebase.
⚠️ Be aware that this list will be constantly updated, so make sure you follow the changes.
Think about reusability, not only in terms of React components, but also on a higher level. If something make sense to be extracted to a separate module or even workspace and reused, feel free to make it happen. But also try to not overengineer stuff.
Don't introduce unnecessary libraries, choose those that are not very heavy (use Bundlephobia), use dynamic imports where it's beneficial to split code into chunks. It's good to use Lighthouse to audit the performance of the page load.
Use --exact flag when doing yarn add, so the version of package is locked. This is a good practice, because we avoid differences in used dependencies across two copies of the project.
# Build production-ready version of package.
> yarn build
# Clean up current workspace after running some compilation steps.
# Mainly used to clean up the codebase and setup it from the beginning if something breaks.
> yarn cleanup
# Spin up development server for given module/ package.
> yarn dev
# Lints the source code (now only ESLint, but Stylelint is also allowed here).
# Use project-eslint instead of eslint for reusable preconfigured rules.
> yarn lint
# Run some check and autofixing before commiting changes.
# Good idea is to have Typescript checks, ESLint autofix and Prettier formatting.
# Use lint-staged to lint only those files that have been staged for commit.
> yarn pre-commit
# Run unit tests.
> yarn testIn the app we sort imports in the following order:
- libraries
- components
- constants
- containers
- types
- utils
- relative paths