Skip to content

Commit 5381151

Browse files
committed
feat: graphQL (#36)
* ci: bundle analyser and workflow --eslint config fix * ci: typo * ci: store next build * ci: multiple cache * ci: typo * feat: graphql * fix: useClientQuery * fix: sw cache post * fix: remove force sw on dev * style: update purge * test: update snapshot * refactor: cache, modern browser, lhci * chore(dep): update .lock * ci: cypress fix * perf: jit tailwind * ci: cache strategy update * ci: cache * ci: install * ci: conditional step * ci: conditional step update * ci: skip if catch with same lock found * ci: test without install parameter to false * ci(cypress): revert install & try without headless * ci: revert cypress config chore(release): 1.3.0 docs: typo refactor: hoc link refactor
1 parent bf61341 commit 5381151

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+3556
-2032
lines changed

.eslintrc.json

+10-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@
33
"browser": true,
44
"es2021": true
55
},
6-
"extends": ["plugin:react/recommended", "airbnb", "plugin:react-hooks/recommended", "plugin:prettier/recommended"],
6+
"extends": [
7+
"airbnb",
8+
"plugin:react/recommended",
9+
"plugin:react-hooks/recommended",
10+
"plugin:prettier/recommended",
11+
"plugin:@typescript-eslint/recommended"
12+
],
713
"parser": "@typescript-eslint/parser",
814
"parserOptions": {
915
"ecmaFeatures": {
@@ -24,6 +30,7 @@
2430
}
2531
},
2632
"plugins": ["react", "@typescript-eslint"],
33+
"ignorePatterns": ["**/*.js"],
2734
"rules": {
2835
"import/extensions": [
2936
0,
@@ -59,6 +66,7 @@
5966
"@typescript-eslint/no-shadow": 0,
6067
"no-shadow": 0,
6168
"react-hooks/rules-of-hooks": 2,
62-
"react-hooks/exhaustive-deps": 1
69+
"react-hooks/exhaustive-deps": 1,
70+
"@typescript-eslint/explicit-module-boundary-types": 0
6371
}
6472
}

.github/workflows/tests.yml

+70-28
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,38 @@ name: Tests
33
on: [push]
44

55
jobs:
6-
perf:
6+
coverage:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- name: Checkout
10+
uses: actions/checkout@v2
11+
12+
- name: Caches
13+
uses: actions/cache@v2
14+
id: yarn-node-module-cache
15+
with:
16+
path: node_modules
17+
key: ${{ runner.os }}-node_modules-${{ hashFiles('**/yarn.lock') }}
18+
19+
- name: Node14
20+
uses: actions/setup-node@v2
21+
with:
22+
node-version: '14'
23+
24+
- name: Install
25+
if: steps.yarn-node-module-cache.outputs.cache-hit != 'true'
26+
run: yarn install
27+
28+
- name: Jest
29+
run: yarn coverage
30+
31+
- name: Store Artifact
32+
uses: actions/upload-artifact@v2
33+
with:
34+
name: coverage
35+
path: coverage
36+
build:
37+
needs: coverage
738
runs-on: ubuntu-latest
839
steps:
940
- name: Checkout
@@ -14,27 +45,34 @@ jobs:
1445
id: yarn-build-cache
1546
with:
1647
path: |
17-
.next/cache
48+
.next
1849
node_modules
1950
~/.cache/Cypress
20-
build
21-
key: ${{ runner.os }}-node_modules-build-${{ hashFiles('**/yarn.lock') }}
51+
key: ${{ runner.os }}-build-
2252
restore-keys: |
23-
${{ runner.os }}-node_modules-build-
53+
${{ runner.os }}-node_modules-
2454
2555
- name: Node14
2656
uses: actions/setup-node@v2
2757
with:
2858
node-version: '14'
2959

3060
- name: Install
31-
run: npm install && npm install -g @lhci/cli@0.7.x
61+
if: steps.yarn-build-cache.outputs.cache-hit != 'true'
62+
run: yarn install
3263

33-
- name: Lhci
34-
run: lhci autorun
35-
env:
36-
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
37-
coverage:
64+
- name: Build
65+
run: yarn build
66+
67+
- name: Store Artifact
68+
uses: actions/upload-artifact@v2
69+
with:
70+
name: Bundle analyzer
71+
path: |
72+
.next/analyze
73+
.next/server/analyze
74+
perf:
75+
needs: build
3876
runs-on: ubuntu-latest
3977
steps:
4078
- name: Checkout
@@ -45,31 +83,31 @@ jobs:
4583
id: yarn-build-cache
4684
with:
4785
path: |
48-
.next/cache
86+
.next
4987
node_modules
5088
~/.cache/Cypress
51-
build
52-
key: ${{ runner.os }}-node_modules-build-${{ hashFiles('**/yarn.lock') }}
89+
key: ${{ runner.os }}-build-
5390
restore-keys: |
54-
${{ runner.os }}-node_modules-build-
91+
${{ runner.os }}-build-
5592
56-
- name: Node12
93+
- name: Node14
5794
uses: actions/setup-node@v2
5895
with:
5996
node-version: '14'
6097

6198
- name: Install
99+
if: steps.yarn-build-cache.outputs.cache-hit != 'true'
62100
run: yarn install
63101

64-
- name: Jest
65-
run: yarn coverage
102+
- name: Install Lhci
103+
run: npm install -g @lhci/cli@0.7.x
66104

67-
- name: Store Artifact
68-
uses: actions/upload-artifact@v2
69-
with:
70-
name: coverage
71-
path: coverage
105+
- name: Lhci
106+
run: lhci autorun
107+
env:
108+
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
72109
e2e:
110+
needs: build
73111
runs-on: ubuntu-latest
74112
steps:
75113
- name: Checkout
@@ -80,27 +118,31 @@ jobs:
80118
id: yarn-build-cache
81119
with:
82120
path: |
83-
.next/cache
121+
.next
84122
node_modules
85123
~/.cache/Cypress
86-
build
87-
key: ${{ runner.os }}-node_modules-build-${{ hashFiles('**/yarn.lock') }}
124+
key: ${{ runner.os }}-build-
88125
restore-keys: |
89-
${{ runner.os }}-node_modules-build-
126+
${{ runner.os }}-build-
90127
91128
- name: Node14
92129
uses: actions/setup-node@v2
93130
with:
94131
node-version: '14'
95132

96133
- name: Install
134+
if: steps.yarn-build-cache.outputs.cache-hit != 'true'
97135
run: yarn install
98136

137+
- name: Build
138+
if: steps.yarn-build-cache.outputs.cache-hit != 'true'
139+
run: yarn build
140+
99141
- name: Cypress run
100142
uses: cypress-io/github-action@v2
101143
with:
102-
build: yarn build
103144
install: false
145+
headless: true
104146
start: yarn start
105147
wait-on: 'http://localhost:3000'
106148
wait-on-timeout: 120

.gitignore

+7-1
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,10 @@ yarn-error.log*
6363
.vercel
6464

6565
# vscode
66-
*.code-workspace
66+
*.code-workspace
67+
68+
# apollo
69+
graphql-schema.json
70+
71+
# lhci
72+
.lighthouseci

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5+
## 1.3.0 (2021-04-10)
6+
7+
### Features
8+
9+
- graphQL ([#36](https://github.com/FabienGreard/front-end-rocks-boilerplate/issues/36)) ([3083241](https://github.com/FabienGreard/front-end-rocks-boilerplate/commit/30832414a87a786d6ba429e456432cd9c66c5318))
10+
511
## 1.2.0 (2021-03-22)
612

713
### Features

README.md

+28-19
Original file line numberDiff line numberDiff line change
@@ -31,31 +31,34 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the
3131

3232
## Commands
3333

34-
| Commands | Info | Description |
35-
| ------------ | :---------------------------------------------: | --------------------------------------------: |
36-
| dev | next dev | Launch app in dev mode |
37-
| dev:test | jest --watch | Launch test |
38-
| dev:coverage | jest --coverag --watch | Generate a coverage from test |
39-
| dev:e2e | cypress run | Launch e2e test |
40-
| build | next build | Build the app for production use |
41-
| start | next start | Launch app from build |
42-
| format | prettier --write . | Format project |
43-
| lint | eslint --fix . | Lint project |
44-
| test | jest --silent | Launch test |
45-
| coverage | jest --coverage --silent | Generate a coverage from test |
46-
| e2e | cypress run --headless | Launch e2e test |
47-
| storybook | start-storybook -p 6006 | Launch storybook (design-system) |
48-
| bump:patch | standard-version --release-as patch --no-verify | v.0.0.0 => v.0.0.1 |
49-
| bump:minor | standard-version --release-as minor --no-verify | v.0.0.0 => v.0.1.0 |
50-
| bump:major | standard-version --release-as major --no-verify | v.0.0.0 => v.1.0.0 |
51-
| clear | node scripts/clear.js | clear node_modules and \*lock |
52-
| prepare | husky install | This is need from husky to set up the project |
34+
| Commands | Info | Description |
35+
| --------------- | :-------------------------------------------------------------------------------------------------------------------------------------------: | ----------------------------------------------------: |
36+
| dev | next dev | Launch app in dev mode |
37+
| dev:test | jest --watch | Launch test |
38+
| dev:coverage | jest --coverag --watch | Generate a coverage from test |
39+
| dev:e2e | cypress open | Launch e2e test |
40+
| build | next build | Build the app for production use |
41+
| start | next start | Launch app from build |
42+
| format | prettier --write . | Format project |
43+
| lint | eslint --fix . | Lint project |
44+
| test | jest --silent | Launch test |
45+
| coverage | jest --coverage --silent | Generate a coverage from test |
46+
| e2e | cypress run --headless | Launch e2e test |
47+
| storybook | start-storybook -p 6006 | Launch storybook (design-system) |
48+
| bump:patch | standard-version --release-as patch --no-verify | v.0.0.0 => v.0.0.1 |
49+
| bump:minor | standard-version --release-as minor --no-verify | v.0.0.0 => v.0.1.0 |
50+
| bump:major | standard-version --release-as major --no-verify | v.0.0.0 => v.1.0.0 |
51+
| apollo:download | npx apollo service:download --endpoint=http://localhost:3000/api/graphql graphql-schema.json | download a graphql schema from an endpoint |
52+
| apollo:generate | npx apollo codegen:generate types --localSchemaFile=graphql-schema.json --target=typescript --tagName=gql --outputFlat --tsFileExtension=d.ts | use for generating typing files from a graphql schema |
53+
| clear | node scripts/clear.js | clear node_modules and \*lock |
54+
| prepare | husky install | This is needed from husky to set up the project |
5355

5456
## Acknowledgement
5557

5658
This project is build with :
5759

5860
- [NextJs](https://nextjs.org/)
61+
- [Apollo](https://www.apollographql.com/)
5962
- [Tailwindcss](https://tailwindcss.com/)
6063
- [Typescript](https://www.typescriptlang.org/)
6164
- [react-intl](https://formatjs.io/)
@@ -105,6 +108,12 @@ Given the [conventionalcommits](https://www.conventionalcommits.org/en/v1.0.0/):
105108
[optional footer(s)]
106109
```
107110

111+
## Generate typing from graphql schema
112+
113+
You may need to look at [apollo-tooling](https://github.com/apollographql/apollo-tooling)
114+
115+
With the graphql endpoint running launch `yarn apollo:download` follow by `yarn apollo:generate`, this will create under `types` a typing file for each query under `apollo/operations`.
116+
108117
## Contributing
109118

110119
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

apollo.config.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
client: {
3+
service: 'apollo',
4+
localSchemaFile: '.graphql-schema.json',
5+
includes: ['apollo/operations/**/*.ts'],
6+
excludes: ['**/__tests__/**/*', '**/node_modules/**/*'],
7+
},
8+
};

apollo/client.ts

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/* eslint-disable global-require */
2+
/* eslint-disable @typescript-eslint/no-var-requires */
3+
import { ApolloClient, InMemoryCache, NormalizedCacheObject } from '@apollo/client';
4+
import { useMemo } from 'react';
5+
6+
let apolloClient: ApolloClient<NormalizedCacheObject>;
7+
8+
function createIsomorphLink() {
9+
if (typeof window === 'undefined') {
10+
const { SchemaLink } = require('@apollo/client/link/schema');
11+
const schema = require('apollo/schema');
12+
13+
return new SchemaLink({ schema: schema.default });
14+
}
15+
16+
const { HttpLink } = require('@apollo/client/link/http');
17+
18+
return new HttpLink({
19+
uri: '/api/graphql',
20+
credentials: 'same-origin',
21+
});
22+
}
23+
24+
function createApolloClient(): ApolloClient<Record<never, unknown>> {
25+
return new ApolloClient({
26+
ssrMode: typeof window === 'undefined',
27+
link: createIsomorphLink(),
28+
cache: new InMemoryCache(),
29+
});
30+
}
31+
32+
export function initializeApollo(initialState: Record<never, unknown> = null) {
33+
// eslint-disable-next-line no-underscore-dangle
34+
const _apolloClient = apolloClient ?? createApolloClient();
35+
36+
// If your page has Next.js data fetching methods that use Apollo Client,
37+
// the initial state gets hydrated here
38+
if (initialState) {
39+
// Get existing cache, loaded during client side data fetching
40+
const existingCache = _apolloClient.extract();
41+
42+
// Restore the cache using the data passed from
43+
// getStaticProps/getServerSideProps combined with the existing cached data
44+
_apolloClient.cache.restore({ ...existingCache, ...initialState });
45+
}
46+
47+
// For SSG and SSR always create a new Apollo Client
48+
if (typeof window === 'undefined') return _apolloClient;
49+
50+
// Create the Apollo Client once in the client
51+
if (!apolloClient) apolloClient = _apolloClient;
52+
53+
return _apolloClient;
54+
}
55+
56+
export default function useClient(initialState?: Record<never, unknown>) {
57+
const store = useMemo(() => initializeApollo(initialState), [initialState]);
58+
return store;
59+
}

apollo/operations/viewer.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { gql } from '@apollo/client';
2+
3+
export const ViewerQuery = gql`
4+
query ViewerQuery {
5+
viewer {
6+
id
7+
name
8+
}
9+
}
10+
`;
11+
12+
export default null;

apollo/resolvers.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default {
2+
Query: {
3+
viewer() {
4+
return { id: 1, name: 'John Smith' };
5+
},
6+
},
7+
};

apollo/schema.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { makeExecutableSchema } from 'apollo-server-micro';
2+
import typeDefs from './type-defs';
3+
import resolvers from './resolvers';
4+
5+
export default makeExecutableSchema({
6+
typeDefs,
7+
resolvers,
8+
});

0 commit comments

Comments
 (0)