Guia de Contribuição para Desenvolvedores Sentry - Ecossistema ReactJS

Manual Front end

Este guia aborda práticas de desenvolvimento frontend no Sentry, com foco nos repositórios Sentry e Getsentry. Pressupõe o uso das regras ESLint definidas no eslint-config-sentry.

Estrutura de Diretórios

O código frontend está localizado em src/sentry/static/sentry/app e static/getsentry.

Organização de Pastas e Arquivos

Nomenclatura de Arquivos

Nomeie arquivos de forma descritiva conforme sua funcionalidade. Evite prefixos desnecessários.

Uso de index.(j|t)?(sx)

Utilize arquivos index apenas quando representarem pontos de entrada de componentes agrupados. Não crie re-exports desnecessários.

React

Definição de Componentes

class Observacao extends React.Component {
  static propTypes = {
    autor: PropTypes.object.isRequired,
    aoEditar: PropTypes.func.isRequired,
  };

  manipularMudanca = valor => {
    const usuario = ConfigStore.obter('usuario');
    if (usuario.ehSupervisor) {
      this.props.aoEditar(valor);
    }
  };

  render() {
    const { conteudo } = this.props;
    return <div onChange={this.manipularMudanca}>{conteudo}</div>;
  }
}

Componentes vs Views

components/ contém elementos reutilizáveis, enquanto views/ agrupa componentes específicos de UI.

PropTypes

Use formatos explícitos e prefira tipos personalizados compartilhados:

PropTypes.shape({
  usuario: PropTypes.string.isRequired,
  email: PropTypes.string
})

CSS e Emotion

import styled from '@emotion/styled';

const ComponenteEstilizado = styled('div')`
  border-radius: 1.45em;
  z-index: ${p => p.tema.zIndex.modal};
  color: ${p => p.tema.roxo};
`;

Gerenciamento de Estado

Utilizamos Reflux para estado global, mas avaliamos alternativas.

Testes

Estamos migrando para React Testing Library. Exemplo básico:

import { render, screen } from 'sentry-test/reactTestingLibrary';

test('exibe mensagem de erro', async () => {
  render(<Componente />);
  expect(await screen.findByRole('alert')).toBeInTheDocument();
});

Novos Recursos de JavaScript

Encadeamento Opcional

const cidade = usuario?.endereco?.cidade;

Operador de Coalescência

const volume = config.volume ?? 0.5;

TypeScript

DefaultProps em Componentes

type Props = {
  nome: string;
  tamanho?: 'P' | 'M' | 'G';
};

const Planeta = ({ nome, tamanho = 'M' }: Props) => {
  return <p>{nome} é um planeta {tamanho.toLowerCase()}</p>;
};

Hooks

Prefira hooks para nova lógica de estado:

const [estado, definirEstado] = useState(null);

useEffect(() => {
  buscarDados().then(definirEstado);
}, []);

Migração Grid-Emotion

Substitua componentes por equivalentes Emotion:

const Flex = styled('div')`
  display: flex;
`;

const Box = styled('div')``;

Tags: ReactJS TypeScript Emotion Jest ReactTestingLibrary

Publicado em 6-17 18:13