Skip to content

topheman/nextjs-github-browser

Repository files navigation

nextjs-github-browser

ci e2e nextjs-github-browser Storybook Demo

This project is a reimplementation of the main features of the github.com website in NextJS.

Prerequisites

  • Nodejs >=14
  • npm >=6

Install

git clone https://github.com/topheman/nextjs-github-browser.git
cd nextjs-github-browser
npm install

Setup

This project uses the Github GraphQL Apis. You will need to generate a personal access token.

  • Create a .env.local file
  • Add GRAPHQL_API_TOKEN=*** to the file with your own token

Create a token

Development

npm run dev

This will start a development server on http://localhost:3000.

Mocking

This project is shipped with built-in mocking for the graphql layer. It works for both client-side and server-side rendering.

  • MOCKS_MODE=record npm run dev : will record any graphql request into .tmp/mocks
  • MOCKS_MODE=replay npm run dev : will replay the mocks if available (if not, will let the request through)

You can use MOCKS_MODE with record / replay also on npm start.

You can override the target of the folder where the mocks are recorded by using MOCKS_TARGET=./tmp/my/specific/folder for example.

Storybook

npm run storybook

This will start the storybook server on http://localhost:6006.

Build

npm run build

This will build the a production version of the website in the .next folder.

For production, we want to expose the storybook, to do that:

npm run build:all

Production

First, you need to build your project running npm run build:all, then:

npm start

This will launch a production server on http://localhost:3000.

You can change the port passing a PORT env var like: PORT=8080 npm start.

Test

Unit

The project contains unit tests run with jest (the react part is relying on @testing-library/react)

npm run test

Cypress

To run the cypress end-to-end test, launch a server in a terminal (in dev mode or production mode).

Then start the cypress test either:

  • In gui mode: npm run cy:open
  • In headless mode: npm run cy:run

Linter

Please checkout eslintrc.js for the linting configuration:

  • TypeScript
  • Prettier
  • Next
  • React
  • Tailwind
  • Cypress
  • ...

Continuous Integration

Each git push / PR triggers a test suite on github/actions. The following will be ran:

  • linting
  • type checking
  • unit tests
  • end to end test with cypress

The end to end test sessions are recorded, you can check them here.

FAQ

GraphQL Schema in TypeScript

Thanks to @octokit/graphql-schema and @graphql-codegen/cli, we can generate type definitions for the GraphQL queries we use.

The queries used in this project are in src/graphql.

The generated types and utils are in src/generated/graphql.ts.

When you modify/add a query/fragment, run npm run graphql-codegen to generate the types and utils.

Http Caching

The /api/github/graphql handler is available by POST requests to both client and server (because it's needed for both SSR and some use cases where we call directly graphql from the client).

You have the following use cases:

  1. full page render: browser -> nextjs(server) -> getServerSideProps -> /api/github/graphql -> github graphql api
    • GET request issued by browser
  2. partial page render: browser(onRouteChange) -> nextjs(getServerSideProps) -> /api/github/graphql -> github graphql api
    • GET request issued by nextjs router
  3. direct call to graphql from client: browser(apollo) -> /api/github/graphql -> github graphql api
    • POST request, cache is manage client side by Apollo

I fixed the problematic of caching for the 2nd case by adding http header Cache-Control: private, max-age=120, must-revalidate.

You can activate it in local by using npm run start:cache.

A better way would be to use some database like redis and store the payloads indexed by serialized graphql variables - this is a personal project 😉.

Resources

This project is based on previous work:

Releases

No releases published

Packages

No packages published