Como usar o script de segundo plano para buscar dados em uma extensão do Chrome

Hu Chen em Level Up Your Code Seguir 8 de jul · 6 min ler Guia Hacker: extensão do Chrome para visualizar projetos de tendências do GitHub em nova aba ?

Se você não tiver certeza de como escrever uma extensão do Google Chrome, poderá dar uma olhada na minha história anterior Como usar o React.js para criar uma extensão entre navegadores em cinco minutos . Ele ensina como usar o aplicativo create-react-app para criar uma extensão de navegador para a nova guia.

A extensão que construímos foi boa, mas toda vez que o usuário abre uma nova guia, recarregamos os últimos repositórios de tendências da API, o que pode levar alguns segundos. Mesmo que demore apenas um segundo, ainda é lento para uma nova aba de abertura.

E se buscarmos os dados em segundo plano periodicamente, salvar os dados no localStorage e lê-los ao abrir uma nova guia?

Passei alguns dias pesquisando sobre isso e descobri que isso é totalmente viável. Neste artigo, vou compartilhar com você o que aprendi durante o processo.

1. Adding background script to manifest.json

O script de segundo plano pode reagir a eventos do navegador e executar determinadas ações, a página de segundo plano é carregada quando é necessária e descarregada quando fica inativa. Para usar o arquivo de plano de fundo, declare-o da seguinte maneira no arquivo manifest.json :

Você notará o parâmetro persistent , uma página de plano de fundo persistente durante o tempo de vida da extensão e apenas uma instância ativamente em execução no plano de fundo do navegador Chrome aguardando o usuário interagir com a extensão.

De acordo com a documentação do desenvolvedor do Google , é mais recomendado usar o modo não persistente e isso pode ajudar a reduzir o custo do recurso de sua extensão. Um script de segundo plano não persistente é puramente baseado em eventos, permanece inativo até que um evento esteja atento a incêndios, reaja com instruções especificadas e, em seguida, descarregue. Alguns exemplos de eventos incluem:

  • A extensão é primeiro instalada ou atualizada para uma nova versão ou o navegador é reiniciado.
  • A página de segundo plano estava atendendo a um evento e o evento foi despachado. (por exemplo. Eu criará um alarm para despachar um evento periodicamente)
  • Um script de conteúdo ou outra extensão envia uma mensagem.
  • Outra exibição na extensão, como um pop-up, chama runtime.getBackgroundPage .

2. Adicionando alarmes para desencadear ações periodicamente

Você pode estar familiarizado com o código abaixo para executar algo periodicamente:

 window.setInterval (function () { 
console.log ('Olá, mundo!');
}, 1000 * 60 * 3);

Imprime “Olá, mundo!” A cada 3 minutos. Para alterá-lo para alarme baseado em evento, usaremos a API de alarmes .

 chrome.alarms.create ('refresh', {periodInMinutes: 3}); 

Em seguida, adicione um ouvinte.

 chrome.alarms.onAlarm.addListener ((alarm) => { 
alerta ("Olá, mundo!");
});

Nós precisaremos criar um alarme quando a extensão for instalada para que o alarme seja disparado a cada 3 minutos em segundo plano, este é o nosso background.js até o momento.

Para usar alarmes, você também precisará adicionar permissão de alarms no manifest.json

3. Depurando o script de fundo

Para testar se os scripts acima podem ser executados conforme o esperado, precisaremos testá-lo localmente. Isso é muito semelhante aos passos da história anterior .

  1. Certifique-se de que o modo de desenvolvedor esteja ativado conforme mostrado na imagem acima.
  2. Clique em “Load descompactado” e a pasta de destino contém seu manifest.json .
  3. Em vez de inspecionar na nova guia, você deve clicar na background page , pois a página de plano de fundo está sendo executada em um processo separado.
  4. Se você alterou o código localmente, será necessário clicar em recarregar.

Extensão de teste localmente

Como você pode ver na imagem abaixo, os alarmes estão funcionando a cada 3 minutos.

Inspecionar script de plano de fundo

E você poderia verificar a rede , localStorage aqui também. Se sua extensão modificou uma nova guia, o localStorage é compartilhado com sua extensão, é assim que comunicamos dados entre seu script de segundo plano e a nova extensão de guia.

4. Buscar dados e salvar em localStorage

Agora temos um alarme básico funcionando, vamos buscar dados e salvar em armazenamento local. Posteriormente em nossa extensão React, poderíamos direcionar a leitura do armazenamento local no carregamento, em vez de buscar a partir da API.

  1. Criaremos um alarme de " atualização " para buscar e salvar dados a cada 30 minutos quando a extensão for instalada ou atualizada pela primeira vez.
  2. Vamos buscar dados quando o Chrome for reiniciado para que o usuário receba os dados mais recentes.
  3. Também criaremos outro alarme de “ watchdog ” a cada 5 minutos para verificar se o alarme de atualização ainda está disponível, caso contrário, iremos criá-lo. (Pode não ser necessário para isso aqui)

5. Reutilize a lógica e transpile para o ES5

Existem dois problemas com o código acima e precisaremos resolvê-los agora:

  1. Observe que nós não escrevemos a implementação para fetchRepositories e saveToLocalStorage , eles provavelmente já estão disponíveis em seu aplicativo React, é bom copiar a implementação para background.js mas será melhor se pudéssemos reutilizar as funções para manter o código DRY .
  2. Nós escrevemos o background.js usando a sintaxe ES6 como => e async await , navegadores mais antigos podem não ser capazes de executá-lo.

Aqui, usaremos o webpack para ajudar a empacotar e transpilar o código para o ES5.

5.1 Instalar dependências

 fio adicionar --dev webpack-cli npm-run-all rimraf 

Observe que não devemos instalar o webpack. ( react-scripts já o tem em dependência e vai reclamar de outra instância do webpack ). Sinta-se à vontade para instalá-lo se você não estiver usando o create-react-app .

5.2 Alterar script de construção

Agora mudar a sua build roteiro para construir tanto a sua aplicação e roteiro de fundo:

 "pré-construção": "rimraf build", 
"build": "npm-run-all build: *",
"build: app": "INLINE_RUNTIME_CHUNK = false reagir construção de scripts",
"build: bg": "produção de webpack --mode ./src/background.js --output ./build/background.js",

Já cobrimos INLINE_RUNTIME_CHUNK=false em um tutorial anterior . Após a mudança, se você executar npm run build , ele executará

  • Limpar a pasta de build
  • Agrupar a extensão React usando react-script
  • Agrupe o src/background.js usando o webpack e exporte para build/background.js

5.3 Refatorar ./src/background.js

Em seu src/background.js , você está livre para importar quaisquer bibliotecas externas como lodash ou importar constantes / funções de outros arquivos, como:

 importar { 
fetchRepositories,
saveToLocalStorage
} de './lib/helpers';
chrome.runtime.onInstalled.addListener (() => {
...

Seu código está muito mais limpo agora.

5.4 Atualizar configuração do ESlint

Se você estiver usando o ESLint em seu editor, pode estar reclamando que o chrome não está definido em seu ./src/background.js . Isso ocorre porque a API do chrome está disponível apenas nas extensões. Precisamos informar ao ESLint que estamos desenvolvendo a extensão e ignorá-las.

Adicione / atualize as seguintes linhas no seu package.json .

 "eslintConfig": { 
"extends": "react-app",
"env": {
"navegador": verdadeiro
"webextensions": true
}
}

Depois de adicionar webextensions ao env , o editor não mais se webextensions disso.

5.5 Adicionar .babelrc

O Webpack precisará de um arquivo .babelrc para compilar, e precisaremos adicioná-lo manualmente. Como react-scripts já instalaram o babel-presets-react-app , precisaremos apenas usá-lo.

 { 
"presets": ["react-app"]
}

Agora execute npm run build e terá sua extensão completa junto com script de fundo compilado em sua pasta de build .

É isso aí!

Se você está curioso, você pode verificar todo o arquivo alterado no commit do meu ramal no GitHub.