Os conceitos e petterns que sigo para minhas aplicações JS em Frontend

Olá! Como vai você? Eu gostaria de iniciar minha aventura aqui no TabNews da mesma forma que eu inicio qualquer um dos meus projetos: divulgando os conceitos e patterns que eu gostaria de aplicar no desenvolvimento.

Vou tentar explicar brevemente e de forma disruptiva o que é cada um pois podem parecer novidades para alguns, porém, não desejo fazer disso um tutorial, mas talvez um local de discussão dos principios utilizados e receber também o feedback e dicas de vocês!

Bom, vamos começar? :v


Como escolho qual tecnologia utilizar?

Acho que essa é a parte mais importante, hoje como top de mercado no frontend, temos o React, Angular, e Vue... O Svelte tá ganhando mercado agora, mas também da pra aplicar tudo o que for citado aqui nele.

  • O React é o cara faz-tudo, você cria qualquer estrutura com ele, acho que deve ser o mais flexível, mas tem que tomar cuidado que às vezes ele pode virar uma zona!

  • No Angular é o cara que já vem com tudo pronto e de forma bem parruda, quanto mais recursos dele mesmo você utilizar, mais performático seu projeto vai ser e é só tomar cuidado com as subscriptions dele rodando com pipes e dando unsubscribe no destroy do componente que vai ficar supimpa.

  • No VueJS é não é muito diferente do Angular, e o melhor de tudo é que todas as variveis do data, props, computed e etc todas reativas... Isso quer dizer que se mudar o valor de alguma variável, ele já renderiza o componente de novo sem precisar de hooks igual o React ou Observables/RXJS do Angular.

Os 3 chegam no mesmo resultado final, oferecem as mesmas soluções, só que de formas diferentes... Todos tem forma de fazer SSR, SSG, Reactive Forms, e por aí vai.

Eu sempre acabo optando pelo React, e gosto muito de utilizar o NextJS, que oferece um kit de ferramentas incrível para deixar o React tão completo quanto os outros e tudo num só "lugar", sem precisar ficar baixando várias libs.

Mas já trabalhei em empresa onde foi necessário me adaptar ao Angular, e tudo bem! Melhor pra mim, mais experiência com outras tecnologias.

E o melhor de tudo, é tudo JAVASCRIPT. Então você só precisar ver a documentação do "react way...", "angular way...", "vue way..." e por aí vai. isso se aplica até mesmo ao quase falecido jQuery 😂

SOLID

O conceito do SOLID, como o Deschamps mesmo já descreveu, é um robô maluco que cada membro faz uma coisa diferente na aplicação, e ele é totalmente modular conforme a necessidade de uso.

Pra mim a base geral mesmo é o próprio SOLID, que é onde vou conseguir criar toda a orientação a objeto do projeto de forma acessível e escalonável, principalmente no CORE do projeto.

Eu não tenho muito o que dizer nessa etapa mesmo, é apenas uma preferência que não sei explicar kkkkkkkkk.

Quer aprender mais sobre SOLID? Segue vídeozinho do Deschamps onde eu realmente consegui aprender esse conceito que explodiu a minha mente para conseguir aplicar em meus projetos! Assiste aí!

Componentização "extrema"

Não sei bem o nome disso, mas pra mim a coisa mais importante pra organizar o frontend, é criar TUDO em componentes. O que leva ao Design System abaixo:

Atomic Design / Atomic Components

Esse Pattern pode ser pouco conhecido por alguns, mas pra mim é a melhor opção de para organizarmos nossas pastas de componentes. Pra quem não sabe como funciona, uma explicação simples é que temos dividido a organização de componentes em até 5 pastas:

  • Atoms
  • Molecules
  • Organisms
  • Templates
  • Pages

Essa organização tem aver com a coletividade de atomos.

Átomos

Nós temos o elemento mais "cru" da UI dentro da pasta Atoms. Sabe aquele input com o estilo padrão que você cria pra usar em todo formulário do sistema? (e que o UX do seu time provavelmente vai mudar o estilo em cada página que ele prototipar) Pois bem, é lá que você vai colocar ele. Cada menor elemento da UX fica aí!

Moléculas

Um coletivo de atomos forma o que? Uma molécula... Então, sabe aquele mesmo input que eu disse acima, mas com um label com a formatação de texto certinho, ícone do input, e a mensagem de erro que aparece em baixo, já seguindo a validação :is-valid ou :is-invalid ? Pois bem, importa o label, o componente de icone, o input e o componente de erros que você criou nesse cara aí, e exporta ele como um todo, recebendo apenas as propriedades dos componente pai e passando para seus componentes filhos.

Organismos

Agora um coletivo de Moléculas forma o que? Exato, um Organismo! Então sabe o componente de "form-control" que você criou? está na hora de você usar ele para criar um componente do formulário.

Então é aí que você vai montar todo o formulário, schema de validação, importar o seu service de http client para enviar ele via post, e por aí vai. Todo o funcionamento DAQUELE formulário você faz ali.

Templates

Um coletivo de Organismos forma o que? um corpo humano Um template! Aqui você vai montar o seu TEMPLATE utilizando os componentes de UI que você criou nos Organismos. É aí que você vai importar o seu header, navbar, breadcrumbs, footer e outros componentes da UI, só esperando para receber via body content o conteúdo da página.

Pages

Agora aqui é aonde junta tudo e joga fora e faz a mágica acontecer, você importa aqui o template desejado e só passa para o content body o componente de organismo de conteúdo que você deseja apresentar na tela.

Ficou confuso? Segue aqui um tutorial bonitão de como aplicar o conceito criado pela Rocketseat! Clica aqui!

RESTful

Quando separamos as stacks backend e frontend, nossa aplicação só tem uma forma de se comunicar com o backend... Chamadas de endpoints via http que retornam um model via JSON. Se precisar armazenar algo temporariamente você pode usar o localstorage para algo permanente e os cookies para algo com validade. Simples assim.

Segue um bom tutorial da Rocketseat sobre REST e RESTful: É só clicar

Frontend BURRO / Frontend Passivo

Isso aqui eu bato na tecla em quase todo projeto... O Frontend deve ser o cara que só exibe a informação. Qualquer plano de negócio deve ser resolvido no BACKEND, chamando as apis via endpoints.

"Never else", "true vars" e "triple equals".

Esses caras eu também não sei o nome correto, mas eu gosto de chamar eles dessa forma.

Quando vamos criar um if/else, precisamos de uma condição TRUE, correto? Um programador Jr. normalmente faria:

if(varivel == true) {
    console.log('aqui caiu true')
} else {
    console.log('aqui caiu false')
}

Esse de cima é fácil, agora imagina um if com diversas condições, exemplo:

if((varivel1 == true && varivel2.includes('texto') == true ) || varivel3 == true) {
    console.log('aqui caiu true')
} else {
    console.log('aqui caiu false')
}

Cara, vai dar manutenção nesse código 3 meses depois, duvido que você vai saber o que rola ai kkkk

Tudo no JS pode ser "resumido" em uma varivel booleana para criar essas condições. Então, pq não deixar mais organizado como abaixo?

const var1IsTrue = !!varivel1 // o operador !! faz a variavel retornar uma negação da negação, ou seja... !true = false, !!true = not false (ou true)
const var2IncludesText = varivel2.includes('texto') // Ele já retorna boolean
const var3IsTrue = !!varivel3 // o mesmo do var1IsTrue

const nomeDaCondicaoDoVar1EVar2 = var1IsTrue && var2IncludesText
const nomeDaCondicaoFinal = nomeDaCondicaoDoVar1EVar2 || var3IsTrue

if(nomeDaCondicaoFinal) {
    console.log('aqui caiu true')
}

if(!nomeDaCondicaoFinal) {
    console.log('aqui caiu false')
}

Explicação bônus: O operador lógico !var não valida apenas boolean, ele atual dentro das especificações do toBoolean(), onde ele valida: false, 0, undefined, null, "" (string vazia), ou até mesmo {} (objeto vazio). Exemplo:

const teste1 = ""
const teste1IsTrue = !teste1
console.log(teste1IsTrue) // = false, pois teste1 está vazio

const teste2 = "nao estou vazio"
const teste2IsTrue = !teste2
console.log(teste2IsTrue) // = true, pois teste2 não está vazio

/* No operador !! você está basicamente negando a negação, ou seja, const teste1IsTrue = !!teste1 retorna true ao invés de false, e const teste2IsTrue = !!teste2 retorna false ao invés de true.

Ficou mais verboso né? mas pelos nomes das variaveis você sabe exatamente o que faz todas as partes da sua validação só de bater o olho.

E você não precisa validar (nomeDaCondicaoFinal === true), apenas (nomeDaCondicaoFinal), pois no if ele já precisa que seja true.

E se você utilizar o conceito de never-else, validando (!nomeDaCondicaoFinal), você já está dizendo que "é falso que essa condição é true", e isso retorna em true!

Hoje o JS é minificado, então não tenha medo de declarar variáveis, é até melhor para debugar!

Tá, mas e o triple equals com === ? No JavaScript por padrão não existe validação de tipagem da varivel, isso força a validação de tipagem, "blindando" cada vez mais o seu projeto. Exemplo:

const str = ""
console.log(str == false) // retorna true
console.log(str === false) // retorna false

Foreach, map, find, findIndex, reduce, some, every e outras formas de percorrer um array

Hoje "gracias" ao ECMAScript modernizando o JS, temos várias formas de percorrer um array, se eu vejo um trecho de código fazendo um for(let i = 0; i <= 10; i++) {} o bicho vai pegar vai ter a pull request reprovada SIM! kkkk.

Brincadeiras à parte, esses métodos ajudam muito a reduzir o código e deixar a gente entender com maior facilidade o que cada função está fazendo, o que ela precisa retornar e etc.

Então dê um ligue nesse vídeo aqui do Código Fonte TV que explica os principais métodos: bora ver!

Apenas um nível de identação por médoto

Esse é bem simples, e quanto mais você praticar isso, melhor é para você entender tudo o que é feito dentro das classes de seu código.

Assim como na parte de UI, temos o conceito de "componentize tudo", parte dos services é bom você "metodonizar tudo" (ok, essa tirada foi ruim!)

Esse vídeo do Matt Sokola explica muito bem, porém está em inglês... Mas você pode achar conteúdo sobre isso no livro Clean Code/Código Limpo, de Robert Cecil Martin. O link do vídeo tá aqui!

Documente seu código da forma correta / JSDoc

Como eu disse anteriormente, o javascript hoje é minificado em produção, então não tem problema nenhum deixar comentado no código os métodos que você cria. Desde que da forma correta! utilizando o JSDoc

Vamos ao código em exemplo:

function calcularFrete(cep1, cep2, hasVoucher) {
    ..todo o calculo de frete aqui..
    return price;
}

Quando for implementar essa função, vai ter que ficar procurando o método sempre pra lembrar quais os parametros e o que ele retorna? Faz assim ó!

/**
* @description efetua o calculo de frete de acordo com o cupom aplicado
* @param {string} cep1 - cep da transportadora
* @param {string} cep2 - cep do destinatário
* @param {boolean} hasVoucher - boolean se o usuário tem cupom de desconto no frete
* @return {number} price - valor final
*/

function calcularFrete(cep1, cep2, hasVoucher) {
    ..todo o calculo de frete aqui..
    return price;
}

E o legal é que de forma nativa as principais IDEs de mercado já fazem a leitura do JSDocs nas funções e te dão a orientação quando passa o mouse por cima quando você usar um const valorFrete = this.calcularFrete('00000-000', '11111-111', true)

E se você estiver deixando uma função absoleta, você pode usar o @deprecated since version 2.0, please use newCalcularFrete() instead Que toda vez que você chamar a função que está em processo de substituição, mas ainda sendo mantida para alguma garantia de uso legal, ela ficará tipo: this.calcularFrete() (riscado assim) visualmente, e quando você passar o mouse por cima, você já pode ver que essa versão está desatualizada e tem uma nova implementada.

Você pode achar toda a formatação do JSDocs no site oficial, aqui!


Finalmente finalizando Galera, existem muitos outros conceitos que eu aplico que eu posso não ter lembrado de aplicar aqui, mas eu garanto que esses são os que eu mais "bato o pé" pra seguirem nos meus projetos, pois assim eu sei que o sucesso é garantido.

Por isso comenta ai o que você achou e possíveis dicas, pois estou pensando em fazer uma parte 2 desse tópico!

Peço desculpas pelos erros de português afinal sou programador e não professor mas mesmo com uma breve revisão posso ter deixado passar algo.

Grato a todos, e vamo que dale TabNews! Isso aqui vai ser o novo stackoverflow, vai vendo! kkk

Muito bom essas dicas. Eu ja utilizo praticamente tudo isso exceto o Atomic Design, já tentei fazer mas virou uma bagunça, prefiro deixar os componentes mais complexos(que seriam ali as Moléculas) agrupados numa pasta onde seria o escopo dele, assim quando precisar fazer uma alteração já está lá tudo juntinho, só os componentes mais repetitivos ficam numa shared folder. Acho que a unica coisa que deixou de fora foi o Typescript e um Eslint, desenvolvi muito dessas praticas de code smell com o eslint, eu deixava o auto-formater desativado daí a IDE fica dando erro de lint e eu ia lá e corrigia manualmente. Hoje mesmo sem ter lint eu já escrevo dentro dos padrões, uso mesmo só pra formatar o código.

De fato o TS e o ESLint são importantes, eu esqueci de colocar pq pra mim já é basicamente automático usar eles kkkk Mas vou deixar eles então para uma parte 2, muito obrigado pelo feedback!

Ótimo artigo, mas trago uma pequena correção sobre o comentário

const var1IsTrue = !!varivel1 // o operador !! faz a variavel retornar uma negação de false, ou seja... ! = false, !! = not false (ou true)

Esse tipo de conversão atua conforme as especificações do toBoolean do EcmaScript. Não é a negação de false, e sim a negação da negação. Se fosse a negação de false, seria sempre true, como você disse no comentário. Segue um exemplo:

0 // number, 0
!0 // boolean, true
!!0 // boolean, false
Cara! eu tava procurando uma explicação melhor do que a minha pra colocar no exemplo kkkkk Muito obrigado, vou corrigir!

Bom artigo, gostei bastante da parte do jsDoc. Em relação ao Atomic, eu meio que já uso essa ideia de hiper componetização, mas seilá. Eu gosto de deixar os componentes relacionados todos na mesma pasta. Em vez de criar uma pasta pros atomos, uma para as moleculas, eu crio a pasta do input, e la coloco o input cru, o wrapper com as validações e labels, e asim vai.

Eu acho legal esse formato de cascata também, mas eu particularmente acho que os componentes ficam muitos mais "compartilhados" no atomic design. Por exemplo, se eu tenho um componente de `

${conteúdo}

`, ao invés de ficar a seguinte estrutura para um componente "pai": pai1/p pai2/p eu tenho: atoms/p (passando via attr/props a variante desejada) organims/pai1 import atoms/p:varianteAmarela organims/pai2 import atoms/p:varianteVermelha Não sei se ficou fácil de entender, mas eu vou estruturando a formatação e variantes nos atomos que vão sendo importados nos componentes pai. Pra mim pelo menos, embora seja um pouco mais complicado na visão macro, quando aplicado corretamente fica extremamente simples de entender.

Muito bom amigo. Assim como o comentario do Salom4N, também estou iniciando e todas as suas dicas vao ser muito valiosas.

Estou terminado um curso de Lógica de Programação e logo vou iniciar o de JS e essas suas dicas aqui vão me poupar muita quebra de cabeça.

Faça uma parte 2, por favor, que eu estarei aprendendo mais ainda.

[JS]

Muito obrigado pelo Feedback! Eu estou pensando em fazer uma publicação da minha recomendação de roadmap para iniciantes na área de frontend, então fica ligado aqui no TabNews :)

Uma Tab enorme, tanto em texto quanto em conteúdo (não é uma reclamação, de maneira alguma)

Informações úteis, quase nunca havia lido um compilado tão bom e "enxuto" como esse.

Irei começar a aplicar em meus projetos essas dicas.

Muito obrigado pelo feedback! Não precisa levar tudo aos seus projetos, pois as vezes uma coisa ou outra não faz sentido ser aplicada, pra não deixar o projeto tão complexo em algo que deveria ser bem simples. O Atomic Pattern, por exemplo, em projetos bem pequenos pode não valer a pena. Mas é legal ir testando os conceitos e ver o que te agrada para você seguir os seus próprios.

Muito bom seu post, principalmente pra quem está começando na área como eu, onde no ínicio recebe uma enxurrada de informações e ficamos sem saber quais informações devem ser guardadas e são de fato importantes ou não. Gostei dessa ideia de listar conceitos e metodologias que devs usam no desenvolvimento dos seus projetos e você explicou tudo de uma forma bem fácil de entender.

Muito obrigado pelo feedback! Eu lembro de quando estava começando, a faculdade nunca me mostrou como estruturar as pastas do projeto, ou o que é POO (programação orientada a objeto) na prática... Sempre com exemplos rasos. Quando eu pensei nesse post foi justamente lembrando desses momentos difíceis kkk

Cara conteúdo excelente e bem explicado com direito a um vídeo para cada tópico para quem quiser se aprofundar. Salvei quase todos aqui para ver depois, parabéns!

Muito obrigado pelo feedback! Cara, eu fiz questão de colocar os vídeos, pq são os mesmos que eu usei para aprender cada coisa. Mesmo eu já tendo uma jornada de quase 5 anos de dev. Frontend, confesso que aprendi muito mais no youtube e na udemy do que fazendo uma faculdade.