Thanks for showing interest to contribute to Blockscout. The following steps will get you up and running.
-
Fork the repo by clicking Fork button at the top of the repo main page and name it appropriately
-
Clone your fork locally
git clone https://github.com/<your_github_username>/<fork_name>.git cd <fork_name>
-
Make sure you're running Node.js 20+ and NPM 10+; if not, upgrade it accordingly, for example using nvm.
node -v npm -v
-
Install dependencies
yarn
We are using following technology stack in the project
- Yarn as package manager
- ReactJS as UI library
- Next.js as application framework
- Chakra as component library; our theme customization can be found in
/theme
folder - TanStack Query for fetching, caching and updating data from the API
- Jest as JavaScript testing framework
- Playwright as a tool for components visual testing
And of course our premier language is Typescript.
To develop locally, follow one of the two paths outlined below:
A. Custom configuration:
- Create
.env.local
file in the root folder and include all required environment variables from the list - Optionally, clone
.env.example
and name it.env.secrets
. Fill it with necessary secrets for integrating with external services. Include only secrets your need. - Use
yarn dev
command to start the dev server. - Open your browser and navigate to the URL provided in the command line output (by default, it is
http://localhost:3000
).
B. Pre-defined configuration:
- Optionally, clone
.env.example
file intoconfigs/envs/.env.secrets
. Fill it with necessary secrets for integrating with external services. Include only secrets your need. - Choose one of the predefined configurations located in the
/configs/envs
folder. - Start your local dev server using the
yarn dev:preset <config_preset_name>
command. - Open your browser and navigate to the URL provided in the command line output (by default, it is
http://localhost:3000
).
For all types of dependencies:
- Do not add a dependency if the desired functionality is easily implementable
- If adding a dependency is necessary, please be sure that is is well-maintained and trustworthy
Note, if the variable should be exposed to the browser don't forget to add prefix NEXT_PUBLIC_
to its name.
These are the steps that you have to follow to make everything work:
- First and foremost, document variable in the /docs/ENVS.md file; provide short description, its expected type, requirement flag, default and example value; do not skip this step otherwise the app will not receive variable value at run-time
- Make sure that you have added a property to React app config (
configs/app/index.ts
) in appropriate section that is associated with this variable; do not use ENV variable values directly in the application code; decide where this variable belongs to and place it under the certain section:app
- the front-end app itselfapi
- the main API configurationchain
- the Blockchain parametersUI
- the app UI customizationmeta
- SEO and meta-tags customizationfeatures
- the particular feature of the appservices
- some 3rd party service integration which is not related to one particular feature
- If a new variable is meant to store the URL of an external API service, remember to include its value in the Content-Security-Policy document header. Refer to
nextjs/csp/policies/app.ts
for details. - For local development purposes add the variable with its appropriate values to pre-defined ENV configs
configs/envs
where it is needed - Add the variable to CI configs where it is needed
deploy/values/review/values.yaml.gotmpl
- review development environmentdeploy/values/review-l2/values.yaml.gotmpl
- review development environment for L2 networks
- If your variable is meant to receive a link to some external resource (image or JSON-config file), extend the array
ASSETS_ENVS
indeploy/scripts/download_assets.sh
with your variable name - Add validation schema for the new variable into the file
deploy/tools/envs-validator/schema.ts
- Check if modified validation schema is valid by doing the following steps:
- change your current directory to
deploy/tools/envs-validator
- install deps with
yarn
command - add your variable into
./test/.env.base
test preset or create a new test preset if needed - if your variable contains a link to the external JSON config file:
- add example of file content into
./test/assets
directory; the file name should be constructed by stripping away prefixNEXT_PUBLIC_
and postfix_URL
if any, and converting the remaining string to lowercase (for example,NEXT_PUBLIC_MARKETPLACE_CONFIG_URL
will becomemarketplace_config.json
) - in the main script
index.ts
extend arrayenvsWithJsonConfig
with your variable name
- add example of file content into
- run
yarn test
command to see the validation result
- change your current directory to
- Don't forget to mention in the PR notes that new ENV variable was added
Every feature or bugfix should be accompanied by tests, either unit tests or component visual tests, or both, except from trivial fixes (for example, typo fix). All commands for running tests you can find below.
If your changes only related to the logic of the app and not to its visual presentation, then try to write unit tests using Jest framework and React Testing Library. In general these tests are "cheaper" and faster than Playwright ones. Use them for testing your utilities and React hooks, as well as the whole components logic.
Place your test suites in .test.ts
or .test.tsx
files. You can find or add some mocks or other helpful utilities for these tests purposes in the /jest
folder.
Note, that we are using custom renderer and wrapper in all test for React components, so please do not import package @testing-library/react
directly in your test suites, instead use imports from jest/lib
utility.
For changes associated with the UI itself write components visual tests using Playwright framework and its experimental Components test library. Please be aware of known issues and limitations of this library.
Your tests files should have .pw.tsx
extension. All configs, mocks, fixtures and other utilities for these tests live in /playwright
folder.
We have 3 pre-configured projects. You can run your test with the desired project by simply adding its tag to the test name:
default
- default project for all test, uses desktop Chrome desktop device; don't need to specify its tag, instead use-@default
tag to skip test run with this projectmobile
- project for testing on mobile devices, uses Safari mobile browser; add tag+@mobile
to run test with this projectdark-color-mode
- project for testing app in the dark color mode, uses desktop Chrome desktop device with forced dark color mode; add tag+@dark-mode
to run test with this project.
Note that, since we are developing not on the same operating system as our CI system, we have to use Docker to generate or update the screenshots. In order to do that use yarn test:pw:docker <path-to-file> --update-snapshots
command. Please do not commit any screenshots generated via yarn test:pw:local
command, their associated tests will fail in the CI run.
-
Make sure that you fork and clone repo; check if the main branch has all recent changes from the original repo
Tip: Keep your
main
branch pointing at the original repository and make pull requests from branches on your fork. To do this, run:git remote add upstream https://github.com/blockscout/frontend.git git fetch upstream git branch --set-upstream-to=upstream/main main
This will add the original repository as a "remote" called "upstream," Then fetch the git information from that remote, then set your local
main
branch to use the upstream main branch whenever you rungit pull
. Then you can make all of your pull request branches based on thismain
branch. Whenever you want to update your version ofmain
, do a regulargit pull
. -
Create a branch for your PR with
git checkout -b <your-branch-name>
; we do not follow any branch name convention just yet -
Commit your changes. Commits should be one logical change that still allows all tests to pass. Prefer smaller commits if there could be two levels of logic grouping. The goal is to allow contributors in the future (including your future self) to determine your reasoning for making changes and to allow them to cherry-pick, patch or port those changes in isolation to other branches or forks. Again, there is no strict commit message convention, but make sure that it clear and fully describes all changes that were made
-
If during your PR you reveal a pre-existing bug, try to isolate the bug and fix it on an independent branch and PR it first
-
Where possible, please provide unit tests that demonstrate new functionality or bug fix is working
- Push your changes and create a Pull Request. If you are still working on the task, please use "Draft Pull Request" option, so we know that it is not ready yet. In addition, you can add label "skip checks" to your PR, so all CI checks will not be triggered.
- Once you finish your work, remove label "skip checks" from PR, if it was added before, and publish PR if it was in the draft state
- Make sure that all code checks and tests are successfully passed
- Add description to your Pull Request and link an existing issue(s) that it is fixing
- Request review from one or all core team members: @tom2drum, @isstuev. Our core team is committed to reviewing patches in a timely manner.
- After code review is done, we merge pull requests by squashing all commits and editing the commit message if necessary using the GitHub user interface.
Note, if you Pull Request contains any changes that are not backwards compatible with the previous versions of the app, please specify them in PR description and add label "breaking changes" to it.
Command | Description |
---|---|
Running and building | |
yarn dev |
run local dev server with user's configuration |
yarn dev:preset <config_preset_name> |
run local dev server with predefined configuration |
yarn build:docker |
build a docker image locally |
yarn start:docker:local |
start an application from previously built local docker image with user's configuration |
yarn start:docker:preset <config_preset_name> |
start an application from previously built local docker image with predefined configuration |
Linting and formatting | |
yarn lint:eslint |
lint project files with ESLint |
yarn lint:eslint:fix |
lint project files with ESLint and automatically fix problems |
yarn lint:tsc |
compile project typescript files using TypeScript Compiler |
yarn svg:format |
format and optimize SVG icons in the /icons folder using SVGO tool |
yarn svg:build-sprite |
build SVG icons sprite |
Testing | |
yarn test:jest |
run all Jest unit tests |
yarn test:jest:watch |
run all Jest unit tests in watch mode |
yarn test:pw:local |
run Playwright component tests locally |
yarn test:pw:docker |
run Playwright component tests in docker container |
yarn test:pw:ci |
run Playwright component tests in CI |
There are some predefined tasks for all commands described above. You can see its full list by pressing cmd + shift + P and using command Task: Run task
Also there is a Jest test launch configuration for debugging and running current test file in the watch mode.
And you may find the Dev Container setup useful too.