Criando meu project starter com Next.JS
Tags: nextjs, tutorial
Published: 2020-11-18 01:29:47

Minha motivação para dar início ao projeto foi devido a um insight que tive durante uma situação em minha vida de desenvolvedor, estava passando por alguns problemas na empresa que estou trabalhando e pensei em olhar o que o mercado estava buscando, me deparei com uma procura absurda por profissionais com proficiência em React e suas stacks. 

Decidi parar para estudar de fato e conheci o Next.js logo em seguida, me apaixonei pela tecnologia e suas funcionalidades (que ainda nem sei todas). 

Assim que comecei a estudar vi que era importante entender todo o eco sistema de uma aplicação que foi, esta sendo ou vai ser construída e reparei que nunca tive a experiência de criar e me preocupar com um ecossistema desses. Foi aí que decidi dar o pontapé nessa direção e comecei a estudar sobre quais tecnologias um projeto next.js deveria ter para ser sustentável, escalável e de fácil manutenção.

Inicialmente não pensei que poderia ser tao extenso a criação do projeto, mas foi, e hoje fico grato por passar por essa experiencia, com isso decidi dividir isso com quem quer que esteja lendo esse artigo, agradeço desde já por consultar aqui e espero que tenha ajudado de alguma forma.


## Começando

Inicialmente vamos criar um projeto base do Next.js:

> Lembrando que vamos precisar ter instalado uma versão do [node](https://nodejs.org/en/) a partir da versão 10.13.
	
	
Vamos rodar o **create next app** no terminal:
	
```sh
npx create-next-app nome_do_seu_projeto
```

Ele vai criar uma estrutura como essa:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/iecl0h83grnfxvekw47o.png)

Vamos entrar na pasta criada:

```sh
cd nome_do_seu_projeto
```

*Caso queira ver o que o comando criou é só rodar no terminal:*

```sh
yarn run dev
```

*e no seu navegador, entrar no [localhost:3000](http://localhost:3000)*


Vamos excluir os arquivos que inicialmente não vamos utilizar:

**pasta styles** -> vamos criar ela dentro do src, na minha opinião e mais organizado.

**Arquivos dentro da pasta public** -> São assets da Vercel que não vamos usar.

**pasta API dentro de pages** -> Essa pasta serve para escrevermos funções que vão ser executadas no servidor da Vercel caso você queira hospedar seu projeto lá.

Vamos ficar com uma estrutura parecida com essa:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7x58trbgb7rjmliy71oe.png)

### Typescript

Escolhi usar typescript devido aos benefícios que ele trás atualmente como o Intellisense, permitindo pegar erros na hora, sem falar das funcionalidades que ainda não estão disponíveis no ES.

Vamos adicionar o typescript com os types dele e do node.js dado que estamos utilizando o Next.js e o mesmo utiliza o node:

```sh
yarn add typescript @types/react @types/node -D 
```

Em seguida vamos trocar os formatos de alguns arquivos para os do typescript:

**pages/_app.js -> pages/_app.tsx**
> Vamos remover a importação do styles nesse arquivo, ficaremos com algo assim:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/e7aacwpbmdqbe73ynnn4.png)

**pages/index.js -> pages/index.tsx**
> Vamos remover a importação do styles aqui também e no meu caso removi tudo o que eu não fosse usar para esse exemplo:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/524soc61z5kj90qtdrl6.png)

Agora vamos rodar o projeto, e o yarn vai entender que estamos usando typescript e criar as configurações dele e as tipagens que o next vai precisar automaticamente. 

Quando ele terminar de rodar teremos uma estrutura parecida com essa:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0rqe4g6lvo964m91dea4.png)

Abrindo no seu navegador o [localhost:3000](http://localhost:3000)
vamos ter algo parecido com isso:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bgiflxb5jgnbw39dhnnc.png)

Com isso colocamos o typescript no nosso projeto!

### EsLint

Primeiramente vamos instalar ele como dependência:

```sh
yarn add eslint -D
```

Em seguida vamos rodar o init:

```sh
yarn init eslin
```

Com isso vamos fazer a configuração com o CLI do Eslint:

* Vamos escolher a terceira opção, *checar sintaxe, encontrar problemas e forçar um estilo de código*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ikwwm0tmnnqj0zdu6u3q.png)

* Aqui vamos selecionar a primeira opção, pôs estamos utilizando import/export

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/avrfpe48ep08443iqqyn.png)

* Aqui também vai ser a primeira opção, estamos utilizando React

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vzy4b0jkb51j8fqcl5sb.png)

* Vamos dizer que **sim**, o projeto utiliza Typescript

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/hfcu4ou3rvxwvu9pqvbs.png)

* Agora vamos selecionar às duas opções com a **barra de espaço**, vamos rodar o projeto no navegador, mas o Next também utiliza o Node, logo nos queremos que os dois sejam vistos

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4jm4uj8e0b7lnt3vgx1c.png)

* Aqui vamos escolher a primeira opção, utilizar um **guia de estilo popular**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jslw3oyph2f9ta71sgem.png)

* Vamos escolher o guia do Airbnb

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/928a35r62igi61vatphh.png)

* Aqui vamos escolher a terceira opção **JSON** como arquivo de configuração para o eslint

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ypw7r2ormfc5mj7tyb1b.png)

* Por final, vamos escolher sim, para instalar as dependências necessárias

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zf41xg071t8uhdn2zk7r.png)

As opções acabaram, mas vamos precisar de mais uma dependência o **eslint-config-airbnb-typescript**, precisaremos instalar ele com o Yarn: 

```sh
yarn add eslint-config-airbnb-typescript -D
```

> Vamos perceber que ele vai gerar um **package-lock.json**, porque ele instala via **NPM**, logo após de terminar de instalar vamos **deletar** o package-lock.json e rodar no terminal **yarn** para ele adicionar no yarn-lock

Terminando de instalar tudo pelo Yarn, teremos uma estrutura parecida com essa:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/z6j6j8fnxqwpbnqrn1pe.png)

E vamos ver que o Eslint já esta acusando alguns erros no projeto.

Calma vamos resolver tudo!

Mas antes vamos alterar algumas coisas nas configurações do Eslint, **.eslintrc**.

Eu tive bastante dificuldade para configurar o Eslint estendido do AirBnB, pedi ajuda a alguns amigos e decidi ter poucas regras e extensões, então basicamente eu vou estender do **airbnb-typescript** e passar o projeto para ele.

Ficaremos com um **.eslintrc** parecido com:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/i9d4bsxa7whtojpcb8vq.png)

Agora vamos criar o arquivo de ignore do Eslint **.eslintignore** na raiz do projeto e vamos ignorar os arquivos **node_modules .next e arquivos .js no projeto**.

Teremos uma configuração assim:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qli3jb3u4edgkbnwrw7p.png)

Inicialmente vamos à pasta **pages/**, no arquivo **_app.tsx**
vamos salvar, e ele já vai fixar alguns erros. 

*Lembrando que para isso acontecer se o seu VSCode estiver com a configuração de [editor.codeActionsonSave](https://github.com/microsoft/vscode-eslint) configurada para o EsLint fixar os erros que ele consegue*.

E em seguida vamos ver o seguinte erro, **'React' must be in scope when using JSX** basicamente o lint pede para importarmos o React quando o escopo for JSX, conseguimos retirar isso desabilitando essa regra, em um projeto Next essa importação não é necessária, mas eu decidi manter por estar acostumado.

Por fim vamos converter a function MyApp para um componente. Teremos algo parecido com:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/me2iljx0js6ljjcc9yzl.png)

Porém, ainda temos um error, o Eslint não vai entender que o nosso componente esta recebendo as propriedades e para isso o Next possui um type que garante a tipagem e afins para nós. No final teremos algo assim:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dx5k4y534cg2r68dyaag.png)

Agora no arquivo **index.tsx** vamos fazer as mesmas coisas, vamos salvar o arquivo, em seguida importar o React e converter a function. Ficaremos com algo assim:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/j4hmup6ecjwvadg2n3ut.png)

E finalizamos essa etapa de Eslint. Você pode rodar o **yarn run dev** para ver se esta tudo ok com o projeto.

### Styled Components

Eu escolhi styled components para estilização, por simples curiosidade, como eu disse estou aprendendo e vi que era muito utilizado no mercado :).

Bom para adicionar a estilização eu segui um [modelo](https://github.com/vercel/next.js/tree/master/examples/with-styled-components) do próprio next.JS.

Inicialmente vamos instalar o **styled-components** e o **@types/styled-components**

```sh
yarn add styled-components
```
e 
```sh
yarn add @types/styled-components -D
```

Vamos criar um arquivo [babelrc](https://github.com/vercel/next.js/blob/master/examples/with-styled-components/.babelrc) na raiz do projeto e adicionar a configuração dele, vamos criar um arquivo chamado [__document.tsx](https://github.com/vercel/next.js/blob/master/examples/with-styled-components/pages/_document.js) na pasta **./pages/** e adicionar a configuração dele também.

Agora vamos precisar alterar algumas coisas dentro do arquivo **__document.tsx**, devido a utilizarmos o TS, provavelmente ele deve reclamar do retorno da função **getInitialProps**, vamos tipar o retorno dela da seguinte forma:

Vamos importar de **next/document** o tipo pronto desse retorno que o next disponibiliza para usarmos, o **DocumentinitialProps**
ele será o tipo da promessa que a função assincronia vai retornar, e teremos que tipar o **contexto** ("ctx" passado como argumento da função) também, vamos importar do mesmo cara o **DocumentContext**. Ficaremos com um arquivo parecido com isso:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1w8s2ysrfjqqlu8ve0h7.png)

Pronto, temos o styled-componentes configurado, porém precisamos usa-lo, para isso vamos fazer umas alterações na nossa estrutura.

Vamos criar um arquivo **src** na raiz do projeto e dentro dela outra pagina chamada **styles** e vamos criar um arquivo de estilos globais, **esse arquivo é criado para fins de exemplos não uma regra**. E por fim vamos mover a pasta **pages** para dentro da pasta **src**. Teremos algo assim no final:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/v43f87ad532vtpxs2hkg.png)

Agora vamos colocar nosso arquivo de configuração de estilos globais pra fazer efeito na aplicação. Inicialmente vamos importar nele a função **createGlobalStyle** do **styled-components**, 
vamos exportar ele de forma default, ele vai criar a nossa tag de estilização global para usarmos no início da aplicação.
Vamos adicionar alguns estilos padrão para a aplicação e para a tag **body**: 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/z5ignl0qoe6q1e88dssl.png)

Vamos adicionar o nosso componente na aplicação, no arquivo **__app.tsx** vamos importar ele e adicionar no retorno da função **MyApp**:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8s39ujygcpk4fn8hkd9n.png)

Rodando o **yarn dev** podemos ver as estilizações funcionando!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/mzhzd1mg757qhffcvnbm.png)

E pronto, mais uma etapa chega ao fim, configuramos o styled- components no nosso projeto!

> *Uma ressalva aqui sobre o styled-component no Next.JS, Toda a estilização esta sendo feita no serve side, no servidor node que o next cria, se desabilitarmos o javascript no browser e dermos um F5 vamos ver que a estilização continua, por mais que estejamos usando o styled-components que funciona de forma dinamica com o JS*.

### Next Images

Eu quis trazer esse plugin do Next para o artigo pôs enquanto estava estudando vi que ele tem algumas limitações para lidar com imagens, ele pede para que coloquemos as imagens que vamos usar na pasta **./public**, e não conseguiríamos utilizar de outra pasta, por exemplo,  e não conseguiríamos tratar as imagens, mas com o plugin [Next images](https://www.npmjs.com/package/next-images) isso muda, vamos conseguir lidar melhor.

Para instalar vamos começar com:

```sh
yarn add next-images
```

Vamos precisar criar um arquivo na raiz chamado **next.config.js**
e nele vamos adicionar essas linhas de código como configuração:

```javascript
const withImages = require('next-images')
module.exports = withImages({
  esModule: true,
})
```

Por último, como estamos utilizando Typescript vamos precisar adicionar mais uma linha de código no arquivo **next-env.d.ts**, para que o Next entenda os arquivos de imagem:

```html
/// <reference types="next-images" />
```
Agora para ver se funcionou, vamos criar uma pasta de **assets** dentro de **./src** e colocar um SVG para usarmos, ficaremos com uma estrutura assim:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/grbt2tritr9bz8gft7vz.png)

Agora vamos usar a imagem na nossa pagina inicial:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jtodrfnxwv9bso949rup.png)

E dependendo da sua imagem, teremos algo assim:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jtodrfnxwv9bso949rup.png)

Porem se inspecionarmos a imagem, vamos ver que ela foi convertida para **base64**:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nrdxr7pnwm1ibr9jfk7z.png)

Essa conversão não e legal para imagens grandes, elas podem aumentar bastante de tamanho. Podemos melhorar isso com o plugin do babel [inline-react-svg](https://github.com/airbnb/babel-plugin-inline-react-svg)

vamos instalar o plugin:

```sh
yarn add babel-plugin-inline-react-svg -D
```

Em seguida vamos usar ele nas configurações do babel, no arquivo **./babel.rc**:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dowm5mgnsg985l3n3huz.png)

E vamos usar agora a imagem como uma tag mesmo. Bem mais simples, não?

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ks776qe12nzwvjqqwaw0.png)

Agora vamos rodar o projeto de novo e ver a diferença:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/q38s4164r98bzliw4w10.png)

Pronto, configuramos a utilização de imagens e o tratamento dos SVG's.

> lembrando que esse tratamento da base64 serve somente para os SVG's.

### Jest

Bom agora, vamos aos testes!

Eu escolhi o [Jest](https://jestjs.io/) por ter uma certa familiaridade e querer aprender um pouco mais como testar unitariamente com ele.

Vamos precisar instalar algumas dependências para o Jest funcionar no nosso projeto:

```sh
yarn add jest @testing-library/react @types/jest @testing-library/jest-dom babel-jest @babel/core -D
```

Em seguida nós vamos criar na raiz do projeto o arquivo de configuração do Jest, **./jest.config.js**, ficaremos com uma estrutura parecida com essa:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/o3mvpsnimdrr2izugr91.png)

Vamos adicionar a configuração:

```javascript
module.exports = {
  testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'],
  bail: 1,
  clearMocks: true,
  collectCoverage: true,
  collectCoverageFrom: ['components/**/*.tsx', 'pages/**/*.tsx'],
  coverageReporters: ['lcov', 'text'],
};
```

Agora vamos adicionar ao **babel.rc** o **presset** para o Jest:

```JSON
"presets": ["next/babel"]
```

> No meu caso, na configuração que fizemos anteriormente, já havíamos colocado esse presset, porem pode ser que isso não aconteça com você então é bom lembrar!

Com a configuração feita,  estamos prontos para rodar os testes! Vamos adicionar dois comandos no **./package.json** para deixar pronto para rodar:

```JSON
"test": "jest --watch",
"coverage": "jest --coverage"
```

Agora vamos adicionar um teste simples do arquivo **./pages/index.tsx** para vermos o Jest em funcionamento.

Dentro da pasta pages vamos criar um arquivo chamado **index.test.tsx** e vamos adicionar esse teste simples:

```javascript
import React from 'react';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import Home from './index';

it('should render Header', () => {
  const { getByText } = render(<Home />);
  expect(getByText('Pagina inicial')).toBeTruthy();
});
```

> Aqui nos estamos vendo se o texto *Pagina inicial* vai ser renderizado.

Vamos para o terminal e rodar o comando de teste:

```sh
yarn test
```

Se a instalação e a configuração estiverem certas, vamos ter um resultado assim:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/cj61ete9i68brtx47bz9.png)

E pronto! Podemos testar o projeto sempre que quiser.

> Uma ressalva, existem varias convenções de estruturas e formas de organizar os testes, eu particularmente prefiro, em projetos Next.JS a utilização da pasta `__test__` para organizar os testes, e mantenho eles sempre no escopo do que eu to testando, por exemplo, como estamos testando o index dentro de **./pages** teríamos uma pasta `__test__`, o Jest vai conseguir entender tudo e rodar os nossos testes. Decidi fazer dessa forma, pôs é mais simples de entender, na minha opinião.

> Gostaria de Incentivar você a testar o máximo que puder do seu projeto, existem vários conteúdos sobre testes com ou sem o Jest e afins então manter sempre seu projeto testado torna mais seguro para você e para seu possível cliente.

### Cypress

Para os testes e2e eu decidi usar o [Cypress](https://www.cypress.io/) para aprender e conhecer a ferramenta.

Vamos instalar o Cypress:

```sh
yarn add cypress --dev
```

Agora vamos abrir o Cypress:

```
yarn run cypress open
```

O Cypress vai criar o arquivo de configuração dele, **cypress.json**, a pasta na raiz do projeto e alguns testes de exemplo, não vamos precisar deles, vamos deletar o que for exemplo e ficaremos com uma estrutura assim:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qtlw22sz2jvnyw7vhcwv.png)

Agora vamos adicionar um teste simples, para vermos o Cypress funcionando. Dentro da pasta **cypress/integrations** vamos adicionar um novo arquivo, **index_spec.ts** e adicionar as seguintes linhas de código:

```javascript
describe('The Home Page', () => {
  beforeEach(() => {
    cy.visit('/');
  });
  it('successfully loads title', () => {
    cy.contains('Pagina inicial');
  });
});

export {};
```

Vamos perceber que ele vai acusar um erro no **cy**, basicamente o Typescript não esta entendendo o tipo dele, vamos adicionar o **cypress** nos tipos do TS no arquivo, **tsconfig.json**:

```
"types": ["cypress"],
...
```

Agora vamos rodar o Cypress para ver se o teste esta funcionando. Vamos ver que não funcionou :/.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/058igzcavbwpp1nxs248.png)

O Cypress precisa acessar o nosso servidor local para conseguir visitar a nossa pagina, para isso acontecer precisamos configurar a URL base, vamos adicionar no arquivo **cypress.json** :

```JSON
{
  "baseUrl": "http://localhost:3000"
}
```

Agora vamos abrir outro terminal, e rodar a nossa aplicação, atualmente esta na **porta 3000**, e no outro terminal vamos rodar o **cypress open** e ver que agora os testes estão passando!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/l1gfeqx8mlhz8ol0bhfw.png)

Temos o Cypress configurado, como um bônus, vou usar o Github Actions para rodar o Cypress nos nossos pull requests e commits :)

Inicialmente vamos criar o repositório no GitHub e fazer um **git push**. Vamos à aba de repositórios do Git, clicar em **novo**:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wfwxx30ycamgmpzw3efx.png)

Em seguida vamos dar um nome ao repositório e desmarcar qualquer coisa, **além da opção de public**, que esteja marcada para não dar conflito e clicar em criar repositório:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/w3ccnthgyasmum39xzbg.png)

Agora vamos voltar ao terminal e adicionar o nosso repositório ao Git:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jy2qyuom3kagittfe5xi.png)

> Lembre-se de commitar as nossas alterações antes de fazer o push :)

Para você esse endereço na caixa vermelha vai ser outro, não tem problema algum, isso SO quer dizer que o projeto esta na minha conta do Github e o seu vai estar no seu Git.

Com isso vamos ter o nosso projeto no GitHub, dai para frente você pode alterar do jeito que quiser o projeto, deixar com a sua cara no Git!

Agora vamos adicionar o Cypress ao nosso projeto:

* vamos ir na [dashboard do cypress](https://dashboard.cypress.io/)

* ao logar, vamos precisar autorizar o Cypress no nosso github:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/so7vva7flzois4u78n0m.png)

* vamos criar uma organização nova:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/unfgmb6lte41p2u7orz1.png)

* vamos **pular** essa etapa de criação de times.

* vamos criar um projeto novo:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/l4m9imslds7pap2oxlut.png)

* selecione a opção **public**:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/c6kqleqko1mcag8tp3xn.png)

* Vamos adicionar o **projectId** gerado no arquivo **cypress.json** no nosso projeto.

* Vamos **guardar essa chave que nos permite enviar os vídeos para o dashboard do Cypress**

Pronto temos um projeto no Cypress.io, agora vamos criar uma ligação entre ele e o nosso projeto no GitHub

Vamos entrar na aba **Project Settings**:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/i3it52vzkhbb7e7z2f5m.png)

Vamos descer ate a parte de **GitHub Integration** e clicar em **Install the Cypress GitHub App**:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qsr8gyl5kxkjpwytyzb8.png)

Selecione o seu GitHub:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8z574oa391y9z0c8dre7.png)

Vamos descer ate a parte de **Repository acess** e selecionar o nosso repositório:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wbdsi3kuatkbl4xr3kj0.png)

Vamos salvar e seremos redirecionados para o Cypress de novo,
em seguida vamos selecionar o repositório que vamos usar do github:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/u499a3sdlz3545j6n5ph.png)

O Cypress vai fazer a configuração necessária para o hook funcionar no Git, só vamos precisar ativar no GitHub.

Vamos Agora na aba **settings** do projeto no GitHub:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3qpzs8rl451odirtfsqb.png)

Vamos selecionar a opção **Branches** depois **Add Rule**, vamos adicionar um nome para a regra, e selecionar a opção de **status checks**:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/aofu5pxaavf7o9txcr25.png)

E já vamos ver o Cypress checando os commits que subimos para o GitHub:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gtyw489jlm9gmuaahwnw.png)

Bom Agora vamos à aba de **actions** e selecionar a opção **set up a workflow yourself**:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ztve1q5o8m6f9gmi4djz.png)

Agora vamos adicionar o workflow do cypress no script:

```yml
name: End-to-end tests
on: [push]
jobs:
  cypress-run:
    runs-on: ubuntu-16.04
    steps:
      - name: Checkout
        uses: actions/checkout@v1
      - name: Cypress run
        uses: cypress-io/github-action@v2
        with:
           record: true
           start: yarn run dev
        env:
          # pass the Dashboard record key as an environment variable
          CYPRESS_RECORD_KEY: <SUA CHAVE GERADA PELO CYPRESS>
```

E se abrirmos um pull request, vamos ver que só vamos poder fazer merge, quando o status do Cypress liberar:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/h531ap62fudgh8d8t07m.png)

E uma coisa legal e que o Cypress sempre reporta no pull request:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/s18e6ticqdq7ls0lxl3g.png)

E assim finalizamos a questão do Cypress!

### Travis

Eu considerei colocar o Travis CI como processo de CI aqui para deixar mais completo o projeto e se você quiser aprender mais sobre CI/CD recomendo muito a [documentação](https://docs.travis-ci.com/user/tutorial/) deles, e bem completa!
Não vou configurar um processo de CD pôs o projeto tem a finalidade de ser um inicial, o CD fica a critério da evolução do projeto.

Inicialmente vamos entrar na dashboard do [Travis CI](https://travis-ci.com/), assim como no Cypress, vamos precisar **instalar** a App no Git e autorizar o mesmo.

Agora vamos adicionar a integração no nosso projeto, vamos clicar no **+** para adicionar uma integração nova, em seguida precisamos buscar pelo nosso projeto:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/grhlal27ewvf42ktnom9.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/i3ongabxlwcdvjkbcfna.png)

Vamos ser redirecionado para a tela anterior porem nao teremos configuração:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zm0ov7ezf8egpiol0nsp.png)

Vamos precisar criar um arquivo novo no nosso projeto, o **.travis.yml**, e vamos adicionar a ele as seguintes linhas de código:

```yml
language: node_js
node_js:
  - "10"

install: yarn install --frozen-lockfile

cache:
  - yarn

script:
  - yarn run test
```

Em seguida, vamos remover o **--watch** do script de testes, ficando com ``"test": "jest"`, para que o Travis não fique travado quando rodar os testes na pipeline, podemos também fazer um script novo para o Travis na pipeline, fique a vontade.

Vamos comitar e fazer o **git push**, já vamos perceber que o Travis esta rodando automaticamente:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/w1s912c72tcfj9e1bhx4.png)

Vamos fazer a mesma configuração nas **regras** que fizemos com o Cypress, vamos à aba de **Settings**, depois em **Branches**, precisamos editar a regra que já tínhamos adicionando mais um **status check**:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/r6rwjuchz8nnk1ww1f6h.png)

E com isso, configuramos o Travis para rodar nossos testes unitários no momento do pull request:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/igpvz73emkss0ghkegv9.png)

### Conclusão

Bom, chegamos ao fim, eu queria concluir dizendo que sei que o texto ficou longo, espero que não massivo, mas minha intenção é expor o que estou aprendendo e aperfeiçoando, ao longo do meu aprendizado, vi poucos conteúdos em português dos assuntos que eu abordei aqui então espero que ajude a comunidade Brasileira nesse sentido, qualquer dúvida é só entrar em contato comigo pelo [Twitter](https://twitter.com/caiomdias_). 

Vou deixar o link para o repositório do projeto que construímos e as referências que usei para construção do projeto:

[projeto de exemplo](https://github.com/caiomdias/starter-next-example)

[Next](https://nextjs.org/docs/getting-started)
[Configuração de projeto Next pela rocketseat](https://www.youtube.com/watch?v=1nVUfZg2dSA&ab_channel=Rocketseat)

[Typescript](https://www.typescriptlang.org/)

[EsLint](https://eslint.org/docs/user-guide/getting-started)

[StyledComponents](https://styled-components.com/docs)
[vantagens do styled components pelo Dev Soutinho](https://www.youtube.com/watch?v=QdfjWRc4ySA&t=645s&ab_channel=DevSoutinho)

[Template do Next.JS usando styled components](https://github.com/vercel/next.js/tree/master/examples/with-styled-components)

[Next Image](https://github.com/twopluszero/next-images)

[React inline SVG](https://github.com/airbnb/babel-plugin-inline-react-svg)

[Jest](https://jestjs.io/docs/en/getting-started)
[Artigo - Configurar testes no Next.JS](https://segredo.dev/configurar-testes-no-nextjs/)

[Cypress](https://docs.cypress.io/guides/overview/why-cypress.html#In-a-nutshell)
[Cypress pelo Agilize](https://www.youtube.com/watch?v=gTRMuWCp8mE&t=1593s&ab_channel=Agilizei)

[Travis CI](https://docs.travis-ci.com/)

Mais uma vez obrigado a todos que gostaram e espero ter ajudado, não esqueça de deixar seu feedback.