Criando uma extensão para o Chrome com React

Utilizando a API do Spotify

--

Introdução

Porque criei uma extensão?

Eu nunca fui muito fã das sugestões de música que o Spotify gerava nas playlists personalizadas e por conta disso eu sempre usei o YouTube para escutar música enquanto trabalhava. Mas tinha um problema nisso. Toda vez que eu gostava de alguma música e queria adicionar ela em alguma playlist do Spotify, eu precisava abrir o Spotify, procurar pela música e adicionar na playlist que eu queria.

Aliás, se você quiser dar uma olhada na extensão, ela está publicada nesse link.

Descobri que era possível resolver meu problema

Tava dando uma enrolada no YouTube quando eu vi esse vídeo aqui:

Esse vídeo me mostrou que era possível resolver meu problema

Eu vi que podia sim criar um aplicativo usando a API do Spotify e não me pareceu muito difícil.

mal eu sabia rs

Agora eu tinha um objetivo

Vi esse vídeo em março de 2020, bem no começo da pandemia, ou seja, eu tinha MUITO tempo livre depois do trabalho. Ainda estava me acostumando a tudo isso e vi alguns influenciadores comentando que podia ser o momento de começar um projeto pessoal, estudar alguma coisa nova. Daí eu pensei em fazer isso, não tinha muito o que fazer também rs

Então eu tinha um objetivo, eu iria desenvolver uma extensão para o Chrome.

Afinal, eu queria fazer alguma coisa que facilitasse meu dia a dia.

Começando

Perdido mas com um objetivo

“If you don’t know where you are going, any road will get you there” — Lewis Carroll

Eu não fazia ideia de como começar, mas eu sabia onde eu podia descobrir isso. Comecei a pesquisar e a vida me deu um tapa logo de cara. Quando eu comecei, haviam poucos artigos sobre como criar uma extensão e ainda menos artigos explicando como fazer isso utilizando React, que era o que eu usava na época.

Pra mim fazia muito mais sentido usar o React para escrever a extensão porque é uma tecnologia que eu conheço e trabalho diariamente. Então também fazia sentido usar ela para desenvolver meus projetos pessoais.

Apesar de não ter achado muitas referências, meu maior problema e também a chave para a resolução dele, e eu ia descobrir isso depois, não era o desenvolvimento da extensão em si, mas entender como funciona o ecossistema de uma extensão no Chrome.

O grande problema

Eu imaginei que o desenvolvimento de uma extensão seguiria o mesmo processo do desenvolvimento na web. Pra ser sincero, eu não tinha pensado na possibilidade de que seria algo diferente.

Na real é que uma extensão, pelo menos no Chrome, possui uma arquitetura muito específica de comunicação e de funções. Cada arquivo desempenha um papel dentro do sistema e se comunica com as outras partes através de alguns sistemas internos do navegador. Para ilustrar o meu problema, seguem algumas imagens.

O que eu imaginava que seria:

Arquitetura que eu imaginava

Como funciona realmente:

Arquitetura de uma extensão

É, um pouco mais complexo do que eu imaginava 😅

Como tinham poucas referências com React, decidi me aventurar com vanilla JavaScript e escrever a extensão partindo do zero. Assim eu teria que entender o que eu estava fazendo e como cada elemento daquele quebra cabeças se encaixava.

As primeiras linhas de código

O começo foi bem difícil. Entender como tudo funcionava, desde a arquitetura, como os arquivos se comunicam, quais arquivos são necessários e o que está dentro do escopo de cada um fazer até como manipular o html para pegar o texto de alguma tag. ufa.

Eu descobri tudo isso através de vários testes e console.log, mas o mais difícil foi entender como tudo funcionava utilizando vanilla JavaScript.

Manipular o html e lidar com o estado da aplicação sem ter uma base, como o React (que é a que eu uso) por trás, pra mim foi muito complexo. E ter que lidar com essa dificuldade técnica mais a falta de conhecimento sobre como o Chrome se organiza só aumentou o meu desespero rs

A questão é que eu não sabia se o problema era o meu código ou algo que eu não estava conseguindo entender da documentação da Google.

Pequenos passos

Mesmo com tudo isso, aos poucos as coisas foram dando certo e alguns funcionamentos foram ficando mais claros na minha cabeça. Eu já conseguia pegar os títulos dos vídeos da página do YouTube e manipular esse valor dentro da minha aplicação. Agora faltava começar a integrar a minha aplicação com a API do Spotify.

Traçando pequenos objetivos

Eu já tinha uma ideia mais clara de como eu podia fazer a aplicação funcionar, onde colocar cada função e como eu iria organizar toda essa bagunça. Faltava agora definir alguns objetivos que precisavam ser feitos para uma primeira versão.

Eu tinha algumas ideias em mente do que precisava ser feito:

  • Acessar a API do Spotify
  • Armazenar os dados não sensíveis do usuário em algum lugar
  • Buscar uma música no Spotify através de um texto qualquer
  • Buscar as playlists de um usuário
  • Adicionar a música encontrada na playlist que o usuário selecionar

Com os estes objetivos traçados ficou mais fácil saber o que eu precisava fazer e principalmente estudar para poder fazer.

A API do Spotify

Estudar a API foi uma das primeiras coisas que eu fiz pra simplesmente ver o quão difícil ia ser trabalhar com ela e se era possível fazer testes com o meu próprio usuário. O desenvolvimento dessa parte não foi tão difícil porque eu já tinha contato com chamadas de API e a deles é muito bem documentada e fácil de entender. Inclusive parabéns para o time do Spotify que mantém ela dessa forma 🤣.

Escrevi algumas chamadas de API e em alguns dias consegui construir uma primeira versão do produto. O usuário já conseguia buscar as músicas no Spotify, ver as suas playlists e adicionar uma música nas playlists selecionadas. O principal da aplicação estava funcionando, mas eu ainda tinha dois problemas:

  • Eu ainda não tinha feito a lógica de autenticação do usuário. Estava utilizando o meu próprio para fazer os testes.
  • O código estava uma bagunça. Uma grande bagunça.

Ok, eu precisava escolher o que fazer.

Uma decisão muito importante

Por mais que o meu espírito de desenvolvedor tivesse gritando “arruma essa mer*** de código”, o que eu mais precisava fazer naquele momento era colocar o app no ar e pra isso eu precisava fazer a autenticação dos usuários.

Pode parecer uma decisão simples, mas são muitos os momentos no nosso dia a dia, principalmente como desenvolvedores, que precisamos decidir entre algo que queremos fazer e o que realmente precisa ser feito. E essas decisões não são fáceis de serem tomadas.

Sabendo o que eu precisava fazer, agora restava aplicar isso no código

Autenticando um usuário

Aqui surgem alguns problemas por conta das peculiaridades do Chrome. Para autenticar um usuário no Spotify, eu precisava chamar um script que abriria um pop-up com o login para o Spotify. O Google disponibiliza uma função auxiliar chamada launchWebAuthFlow dentro do objeto chrome.identity.

Fazer toda essa lógica de autenticação funcionar foi complicado, mas lendo a documentação do próprio Google sobre como criar uma extensão, deu pra fazer. O que não estava escrito nessa parte da documentação é que, assim que o usuário clica fora da extensão, o código dela também é fechado. Aí surgiu um dos problemas que me fez entender por completo a arquitetura do Chrome para extensões.

O arquivo de background

Um dos problemas que estavam acontecendo era que, quando o usuário abria o pop-up de autenticação, o código da minha extensão fechava. E era ela quem deveria receber os códigos de autenticação do Spotify e por estar fechado ela não recebia o retorno da API.

Lendo a documentação do Google, fazendo alguns testes e estudando alguns artigos, comecei a entender que tinha um arquivo background.js. Eu poderia criar ele e declarar dentro do manifest.json e ele executaria em background no navegador.

Isso era importante porque?

Bom, basicamente o que estava acontecendo era que, o usuário clicava para se autenticar, o pop-up de autenticação abria e a minha extensão fechava. O meu código fechava junto e eu perdia a comunicação entre a minha extensão e o pop-up do Spotify.

Declarando a função de login dentro do arquivo background.js, mesmo que a extensão seja fechada, o código continua rodando em background no navegador do usuário e lá eu tenho acesso ao retorno do pop-up do Spotify com os códigos de autenticação do usuário.

Voltando ao início

Com isso, foi possível criar e publicar a primeira versão da extensão no Chrome, o que não foi muito difícil.

Com a primeira versão publicada, o que eu queria fazer era refatorar todo o projeto para React com typescript para ficar show de bola mesmo.

Essa parte foi a mais fácil para ser bem sincero. Agora que eu tinha entendido como cada parte funcionava, eu só tinha que pedir para algum bundler, no caso eu escolhi o webpack, fazer o bundle da minha aplicação conforme as necessidades do Chrome e foi isso que eu fiz.

Com o código ainda escrito em JavaScript, coloquei o webpack para fazer o bundle de 3 arquivos, o background.js o content.js e o app.js dentro de uma pasta /build contendo os ícones do projeto, o arquivo .html e o manifest.json. Com essa lógica funcionando, foi tranquilo colocar o React junto com o typescript. Eu só precisei configurar no webpack que meu projeto precisava ir de typescript para javascript e apontar para o arquivo de “root” do React que eu estava usando.

Conclusão

Um resumo de como o Chrome funciona

Basicamente o Chrome funciona com 3 arquivos javascript que rodam a sua extensão. Um deles é o script da sua aplicação mesmo, ou seja, um arquivo que manipula e se comunica com o html da sua extensão. Esse, podemos chamar de app.js.

Outro arquivo é o content.js que tem acesso, através de um sistema de mensageria, ao html do navegador. É nesse arquivo que configurei a função que deveria pegar o valor do título do vídeo do YouTube.

E o outro arquivo é o background.js que como o nome diz, roda no background do seu navegador, ou seja, roda mesmo se a sua extensão estiver fechada. Este também se comunica com os outros arquivos através do mesmo sistema de mensageria.

Olhando para trás

Apesar de parecer simples hoje, foi muito complicado entender como tudo funciona e porque funciona da forma como funciona. Foi uma jornada bem divertida. Foi como aprender uma nova linguagem de programação do zero. Com pouco material, tive que me virar para aprender e assim como uma criança, testar para aprender.

Apesar de tudo isso, se você não quiser passar por todo esse perrengue e só quiser criar uma extensão para o Chrome utilizando React com typescript, criei um boilerplate para facilitar esse processo. Você pode dar uma olhada neste link.

E para quem ficou interessado, aqui está o link para a extensão do chrome.

Se tiverem alguma dúvida ou queiram um artigo explicando tecnicamente como funciona o ecossistema do Chrome para extensões, podem me marcar ou mandar DM no twitter

Abraços 🤙

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Samuel Monteiro
Samuel Monteiro

Written by Samuel Monteiro

Tech lead na Captalys | apaixonado por programação e desenvolvimento pessoal | Dev React e Typescript

Responses (1)