Extensão Google Chrome com Angular 11

Veja nesse artigo como criar uma extensão para o Google Chrome utilizando o Angular

Extensão Google Chrome com Angular 11

O que é uma extensão?

Antes de começarmos a desenvolver nosso projeto, primeiro devemos entender o que é e como funciona uma extensão.

Uma extensão nada mais é que um pequeno programa que adiciona um ou vários recursos a um navegador (que no nosso caso será o Google Chrome).

Se você sabe como criar páginas da Web, é tudo o que precisa saber para criar extensões para o Chrome, as extensões são implementadas usando as tecnologias da web padrão, como html, css, e java script.

Uma extensão é na verdade uma pasta compactada, mais precisamente um arquivo zip com uma assinatura que contém vários arquivos.

A única coisa que diferencia uma extensão do Chrome de um projeto web com (html, css, java script) é que obrigatoriamente uma extensão deve ter um arquivo chamado manifest.json.

Ele contém todas as informações sobre a extensão, como o número da versão, seu nome e pode apontar para outros componentes da extensão, componentes que, por sua vez, fornecem funcionalidade à extensão.

Por que alguém iria querer desenvolver uma extensão do Chrome?

Existem alguns motivos que lhe faria querer desenvolver uma extensão do Chrome. O primeiro (e o mais improvável) é ganhar dinheiro.

Sim, existem extensões do Chrome publicadas na Chrome Store e os desenvolvedores são pagos por isso. Então se você tem uma ideia para uma extensão e um modelo de negócio que seja lucrativo, é uma boa alternativa.

No entanto, acredito que o principal caso de uso para desenvolver uma extensão é atender às suas necessidades como desenvolvedor no quesito de automatização de tarefas.

Eu utilizo uma técnica chamada de mineração de sentenças junto com o Anki (Software de Repetição Espaçada) para aumentar o meu vocabulário em inglês, então costumo buscar minhas frases/palavras novas em uma série de URLs, porem eu geralmente preciso pesquisar nesse conjunto de URLs a mesma palavra/frase, como esse processo se tornou bastante repetitivo, fiz uma extensão bem simples para automatizar essa pesquisa (caso queira ver clique aqui).

Esse foi apenas um exemplo de algo que eu consegui automatizar utilizando uma extensão,tenho certeza de que você consegue pensar facilmente em pelo menos uma coisa que está fazendo repetidamente durante o ciclo de desenvolvimento ou no uso comum do seu computador.

Algo que pode ser facilmente automatizado com uma simples extensão do Chrome.

Antes de colocarmos a mão na massa é importante entendermos como funciona uma extensão do chrome.

Estrutura Anatômica de uma extensão do Chrome:

Estrutura anatômica de uma extensão do chromeEstrutura anatômica de uma extensão do chrome

Background script:

O background script é o manipulador de eventos da extensão, ele pode conter ouvintes para eventos do navegador que são importantes para a extensão. Ele permanece inativo até que um evento seja disparado e, em seguida, execute a lógica instruída. um background script eficaz só é carregado quando necessário e descarregado quando fica ocioso.

Content script:

As extensões que realizam leitura ou gravação em páginas da web utilizam um content script. O content script contém o código JavaScript que pode ser injetado em uma página que foi carregada no navegador. O content script lê e modifica o DOM da página da web que o navegador visita.

Se uma ação do navegador tiver um pop-up, ele aparecerá quando o usuário clicar no ícone da extensão. O pop-up pode conter qualquer conteúdo HTML de sua preferência e é dimensionado automaticamente para caber em seu conteúdo.

Comunicação entre as páginas:

Diferentes componentes em uma extensão geralmente precisam se comunicar uns com os outros. Diferentes páginas HTML podem se encontrar usando os métodos da API chrome.extension, como getViews()e getBackgroundPage().

Uma vez que uma página tenha uma referência a outras páginas da extensão, a primeira pode chamar funções nas outras páginas e manipular seus elementos DOM.

Além disso, todos os componentes da extensão podem acessar valores armazenados usando a storage API (que será a forma utilizada nesse artigo) e se comunicar utilizando **message passing**.

Criando o Projeto:

  1. Comece criando um novo projeto angular: ng new angular-chrome-extension

  2. Navegue até a pasta do projeto cd angular-chrome-extension

  3. Crie um arquivo chamado manifest.jsondentro da pasta src.

manifest.json:

Esse arquivo não é nada mais que um JSON, onde ficarão os metadados relacionados à sua extensão: nome da extensão, descrição, versão, permissões, etc. nesse link você encontra todos os metadados que podem ser incluídos no manifest.json.

Inclua o código a seguir no arquivo:

{
  "name": "angular-chrome-extension",
  "version": "1.0",
  "description": "construindo uma extensão com angular",
  "manifest_version": 2
}

Carregando a extensão no chrome:

Ao realizarmos o buildda nossa aplicação precisamos que o arquivo manifest.json esteja lá também, pois é ele que diz ao chrome que o nosso app é uma extensão, para isso vamos incluí-lo no array da propriedade assetsdo nosso angular.json

"assets": ["src/favicon.ico", "src/assets", "src/manifest.json"],

Execute o comando ng build para certificar-se de que o manifest.json está realmente presente no diretório dist :

confirmação de inclusão do arquivo manifest.json no buildconfirmação de inclusão do arquivo manifest.json no build

Para carregá-la no chrome siga os seguintes passos:

  • Abra o Chrome

  • Navegue para chrome://extensions ou clique no menu de extensões e vá em gerenciar extensões

menu para abrir a parte de gerenciamento das extensõesmenu para abrir a parte de gerenciamento das extensões

  • Ative o modo de desenvolvedor clicando no botão toggle no canto superior direito.

botão para ativar o modo de desenvolvedorbotão para ativar o modo de desenvolvedor

  • Clique no botão Carregar sem compactação e selecione o diretório da extensão que no nosso caso está em dist/angular-chrome-extension

opção para realizar o upload da extensãoopção para realizar o upload da extensão

Agora você já deve ser capaz de ver a extensão instalada na lista de extensões e poderá fixá-la na barra de extensões.

exibição da extensão na lista de extensõesexibição da extensão na lista de extensões

opções mostradas ao clicar no icone da extensãoopções mostradas ao clicar no icone da extensão

No entanto, como você provavelmente notou, não há nada na extensão além do ícone padrão e o título que demos a ela no arquivomanifest.json.

O motivo é que não definimos nenhuma ação. Vamos acrescentar isso ao nosso arquivo manifest.json:

{
  "name": "angular-chrome-extension",
  "version": "1.0",
  "description": "Build an Extension with Angular",
  "manifest_version": 2,
  "browser_action": {
    "default_popup": "index.html"
  }
}

Inclusão da propriedade browser_action no manifest.jsonInclusão da propriedade browser_action no manifest.json

Utilize a propriedade browser_action para definir as ações que o navegador irá executar, é possível utilizar as seguintes propriedades abaixo:

default_title: define qual será o titulo a ser exibido como um tooltip quando o usuário passar o mouse sobre o icone, caso não seja informado será utilizado o nome da extensão definido na proprieade name.

default_icon: utilizado para definir o ícone a ser exibido da extensão.

default_popup: pagina html que será exibida quando o usuário clicar no ícone da extensão.

agora com o nosso index.html definido para ser a nossa página de popup vamos fazer ng build da nossa aplicação novamente e clicar para recarregar a nossa extensão.

apenas clicando nesse botão a extensão será recarregada novamente da pasta de origemapenas clicando nesse botão a extensão será recarregada novamente da pasta de origem

agora quando clicamos no ícone da extensão nossa aplicação angular será exibida.

Live reload e ng serve

O ideal seria se pudessemos utilizar o comandong serveda mesma forma que usamos para nossas aplicações web e esperar que a extensão seja atualizada automaticamente sempre que houver uma alteração. Infelizmente esse não é o caso.

Não podemos usar o ng serve aqui porque ele grava o pacote na memória do servidor de desenvolvimento, enquanto o Chrome precisa de uma pasta física real no disco para carregar a extensão.

Porém podemos utilizar o ng build --watch.

Ele irá observar as alterações e reconstruíra os arquivos relevantes enquanto atualiza os pacotes no diretório dist .

Ele se encarregará de atualizar a pasta dist quando houver alterações nos arquivos ou em nosso manifest.json .

A extensão ainda não será atualizada automaticamente, mas está mais fácil que antes. Agora, para aplicar as alterações, você só precisa de algumas coisas:

  1. Se você alterou qualquer arquivo de origem que afeta o pop-up da extensão, abra e feche o pop-up. O Chrome carrega o pop-up diretamente da pasta distsempre que você o abre, de forma que todas as alterações feitas no pop-up são aplicadas automaticamente quando ele é reaberto.

  2. Se você alterou o manifest.json, deverá recarregar a extensão na página de extensões (assim como fizemos antes). O manifest.jsoné um conjunto de definições, regras e instruções para sua extensão, portanto, é aplicado quando a extensão é instalada. Ao pressionar o botão de recarregar, você está efetivamente reinstalando a extensão descompactada.

  3. O background script também podem ser recarregado automaticamente, mas abordaremos isso mais tarde.

Adicionando Funcionalidades a Extensão

No momento, temos uma extensão que mostra apenas a página padrão do Angular como um pop-upe, além disso, não faz absolutamente nada. Vamos mudar isso.

Primeiro, definiremos o que essa extensão fará:

  1. Ela estará ativa apenas em sites sob o domínio google.com.

  2. Irá conter um color-picker.

  3. Irá mudar o background-colorde uma página para a cor selecionada ao pressionar um botão.

Ativar a extensão apenas em sites específicos

Até agora estávamos usando apenas o browser_action sem o background scriptou o content script, vamos relembrar o que é obrowser_action.

API para colocar ícones na barra de ferramentas principal do Google Chrome, à direita da barra de endereço. As ações da página representam ações que podem ser realizadas na página atual, mas que não se aplicam a todas as páginas. As ações da página aparecem esmaecidas quando inativas.

Como queremos mostrar a extensão apenas em sites google.com, usaremos a propriedade page_action em seu lugar, que serve para:

API para colocar ícones na barra de ferramentas principal do Google Chrome, à direita da barra de endereço. As ações da página representam ações que podem ser realizadas na página atual, mas que não se aplicam a todas as páginas. As ações da página aparecem esmaecidas quando inativas.

Qual é a diferença?

Eles são basicamente os mesmos (exceto alguns pequenos recursos que apresentam apenas no browser_action), mas o page_actionestá desabilitado por padrão para todas as páginas, enquanto obrowser_actioné habilitado por padrão para todas as páginas.

Poderíamos continuar usando o browser_action desde que o desabilitássemos para todos os sites que não correspondem a google.com, mas a documentação deixa isso explícito:

Não use o*browser_action para recursos que fazem sentido apenas para algumas páginas. Em vez disso,use o`page_action`*.

então vamos alterar o nosso manifest.jsone trocar para o page_action

{
  "name": "angular-chrome-extension",
  "version": "1.0",
  "description": "Build an Extension with Angular",
  "manifest_version": 2,
  "page_action": {
    "default_popup": "index.html"
  }
}

alteração da propriedade browser_action para page_actionalteração da propriedade browser_action para page_action

Recarregue a extensão (pois alteramos o manifest.json ), e agora ela deve ser desabilitada para todos os sites. O ícone ficará esmaecido e quando você clicar nele, você tem apenas algumas opções que normalmente receberia ao clicar com o botão direito:

clique com o botão esquerdo na extensão que agora está desabilitadaclique com o botão esquerdo na extensão que agora está desabilitada

Agora é hora de habilitá-la para os sites que possuem google.comno endereço.

Background Script

Para lembrá-lo, o background script é:

o manipulador de eventos da extensão; ele contém ouvintes para eventos do navegador que são importantes para a extensão.

No nosso caso, gostaríamos de ouvir o evento de navegação na web concluído, fazer a correspondência de URL e habilitar a extensão se houver uma correspondência.

  1. Instale as tipagens da API do Chrome: npm i -D @types/chrome

  2. Adicione chrome aos tipos do array da propriedade types que fica dentro compilerOptionsno tsconfig.app.json

    "types": ["chrome"]

Inclusão types para o chromeInclusão types para o chrome

  1. Crie um arquivo chamado background.tsdentro da pasta srccom o seguinte conteúdo:
chrome.runtime.onInstalled.addListener(() => {
  chrome.webNavigation.onCompleted.addListener(
    () => {
      chrome.tabs.query({ active: true, currentWindow: true }, ([{ id }]) => {
        if (id == null) return;
        chrome.pageAction.show(id);
      });
    },
    { url: [{ urlMatches: 'google.com' }] }
  );
});

As APIs do Chrome quase sempre são assíncronas, então é o que acontece aqui:

  1. Nós adicionamos um ouvinte que, uma vez que a extensão for instalada irá …

  2. Adicionar um ouvinte que, assim que um usuário acessar qualquer URL que contenha google.com, irá …

  3. … consultar as abas abertas para escolher uma ativa e assim que houver uma resposta…

  4. … Ativa o page_actionna aba

Agora vamos executar o ng build .

O nosso background script foi compilado? Obviamente não. basicamente ele foi para limbo 😂 , pois como ele não é referenciado de nenhum lugar, não há como o Angular CLI realmente saber que esse script existe.

Precisamos adicionar o nosso background script ao processo de build.

Adicionando o background script ao processo de build

Uma vez que o background script é executado em um contexto diferente do pop-upda extensão, não podemos simplesmente adicioná-lo à seção de scriptsno angular.json

Tudo o que está na seção de scripts é compilado pelo Angular CLI em blocos de scripts e carregado no index.html (no contexto do popup em nosso caso).

Este também é o motivo pelo qual não podemos simplesmente importar o background script no main.ts ou em qualquer outro arquivo que é compilado como parte do popup.

O que podemos fazer é criar outro entry point para o background script no processo de builddo webpack, que é executado pelo angular CLI por debaixo dos panos, para isso, podemos usar o Custom Webpack Builder:

  1. Instale utilizando npm i -D @angular-builders/custom-webpack

  2. Na raiz do projeto crie um arquivo chamado custom-webpack.config.tscom o seguinte conteúdo:

export default {
  entry: { background: 'src/background.ts' },
};

Arquivo de configuração do cutsom-webpack configArquivo de configuração do cutsom-webpack config

  1. Atualize o angular.jsonda seguintes forma:

dentro da propriedadearchitectsubstitua a propriedade builder que fica dentro da propriedade build removendo o builder padrão do Angular pelo do custom-webpack:

substuição do builder padrão para o custom-webpacksubstuição do builder padrão para o custom-webpack

Na propriedade "options" acrescente mais uma propriedade ao objeto onde irá informar o caminho para o nosso arquivo de configuração do custom-webpack. conforme trecho destacado abaixo:

"builder": "@angular-builders/custom-webpack:browser",
"options": {
  ...
  "customWebpackConfig": {
    "path": "./custom-webpack.config.ts"
  }
},

Inclusão da proprieda customWebpackConfig no angular.jsonInclusão da proprieda customWebpackConfig no angular.json

  1. Inclua o arquivo background.ts no array da propriedade filesdo tsconfig.app.json
 "files": ["src/main.ts", "src/polyfills.ts", "src/background.ts"],

Inclusão do background.ts no tsconfig.app.jsonInclusão do background.ts no tsconfig.app.json

  1. execute novamente o ng build.

Agora você deve ser capaz vê-lo na saída do build (e também na pasta dist):

Exibição do background.js na saida do buildExibição do background.js na saida do build

Agora precisamos deixar o Chrome ciente desse background script. Também precisamos conceder algumas permissões para nossa extensão. Atualize seu manifest.json :

{
  "name": "angular-chrome-extension",
  "version": "1.0",
  "description": "Build an Extension with Angular",
  "manifest_version": 2,
  "permissions": ["activeTab", "webNavigation"],
  "background": {
    "scripts": ["background.js"]
  },
  "page_action": {
    "default_popup": "index.html"
  }
}

Inclusão do background.js e permissões no manifest.jsonInclusão do background.js e permissões no manifest.json

Se você recarregar a extensão agora e for para http://google.com, ainda verá que ela está inativa. Se você se aprofundar um pouco, verá que o background scriptestá sendo carregado, mas não está sendo executado. E há uma razão para isso.

Vamos dar uma olhada na versão compilada de nosso background.ts:

Versão compilada do arquivo background.tsVersão compilada do arquivo background.ts

Como você pode ver, nosso código está sendo inserido no array webpackJsonpcomo parte de um dicionário que mapeia caminhos para o código real. Mas ninguém o invoca. Então, sim, o script está sendo carregado, mas nada acontece, porque ninguém realmente executa o código.

O Angular (Webpack) coloca o código responsável pela execução dos chunks em um chunk separado chamado runtime. Esta é a parte que falta que precisamos adicionar ao manifest.json:

  "scripts": ["background.js", "runtime.js"]

Inclusão do runtime.js no manifest.jsonInclusão do runtime.js no manifest.json

Você pode ler mais sobre webpackJsonpcomo Webpack runtime nesse artigo

Recarregue a extensão, vá para http://google.com e você estará de volta para ver esta bela imagem:

exibição do popup ao clicar na extensãoexibição do popup ao clicar na extensão

Live Reload para o Background Script

O background script se comporta de forma muito semelhante ao manifest.json ele é recarregado apenas quando você recarrega a extensão.

No entanto, ao contrário do manifest.json(que raramente é atualizado após a fase inicial de desenvolvimento), ele contém uma parte significativa do nosso código e é atualizado com bastante frequência durante o desenvolvimento.

E acredite em mim, é muito chato ir à página de extensões e pressionar o botão recarregar toda vez que você altera o nome de uma variável no background script.

Então, o que pode ser feito aqui? como já incorporamos o Custom Webpack Builder em nosso processo de build , podemos nos beneficiar um pouco mais.

Existe um plugin chamado webpack-extension-reloader que faz exatamente o que queremos. Ele acrescenta um código no background script que ouve as alterações dos chunks e, quando há uma mudança no background script ele informa ao Chrome para recarregar a extensão.

Queremos essa funcionalidade apenas durante o desenvolvimento, então vamos criar outra configuração do webpack que fará uso de nossa configuração inicial e irá adicionar o plug-in webpack-extension-reloaderapenas durante o desenvolvimento.

  1. Instale o reloader: npm i -D webpack-extension-reloader

  2. Crie um arquivo chamado custom-webpack-dev.config.ts na raiz do projeto:

const ExtensionReloader = require('webpack-extension-reloader');
import config from './custom-webpack.config';

const options = {
  reloadPage: true,
  entries: {
    background: 'background',
  },
};

export default {
  ...config,
  mode: 'development',
  plugins: [new ExtensionReloader(options)],
};
  1. Na propriedade configurationsdo angular.jsoncrie uma propriedade chamada dev
            "dev": {
              "customWebpackConfig": {
                "path": "./custom-webpack-dev.config.ts"
              }
            },

Configuração a ser adicionada no angular.jsonConfiguração a ser adicionada no angular.json

Vamos nos certificar de que tudo está funcionando:

  1. Execute o build utilizando está configuração: ng build --watch --configuration=dev .

  2. Recarregue a extensão (o antigo background scriptainda não possui o código para recargar em tempo real, então você tem que fazer isso pela última vez).

  3. Navegue até http://google.com

  4. Veja o page actionhabilitado.

  5. Vá até o arquivo background.ts e altere a condição que verifica a URL para blahblah

  6. Volte para http://google.com

  7. E veja o page action desabilitado.

Obs: poderíamos ter escrito o background script em JavaScript em vez de TypeScript e adicioná-lo ao assets assim como fizemos com o manifest.json porem fazendo isso não seria possível realizar o live reload, que seria um problema.

Obs 2: tudo o que fizemos aqui para o background script (incluindo construí-lo com ng build, live reload etc.) também se aplica ao content script.

Adicionando o color picker

Isso será fácil. Usaremos o componente ngx-color-picker.

  1. Instale o ngx-color-picker: npm i ngx-color-picker

  2. Adicione o ColorPickerModule a propriedade imports no app.module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ColorPickerModule } from 'ngx-color-picker';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, AppRoutingModule, ColorPickerModule],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

Adição do ColorPickerModule ao app.module.tsAdição do ColorPickerModule ao app.module.ts

  1. Adicione a propriedade color no app.component.ts :
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {
  color: string;
}

Adição da propriedade color no app.component.tsAdição da propriedade color no app.component.ts

  1. Substitua o conteudo padrão do angular pelo color-picker no app.component.html:
<span
  [style.color]="color"
  [cpToggle]="true"
  [cpDialogDisplay]="'inline'"
  [cpPositionRelativeToArrow]="true"
  [(colorPicker)]="color"
  [cpOKButtonText]="'Aplicar'"
  [cpOKButton]="true"
>
</span>

Adição color-picker no app.component.htmlAdição color-picker no app.component.html

Caso queira entender o funcionamento do color-pickerconsulte aqui.

  1. Se você não quiser a borda branca ao redor do color-picker, remova as margens do body em styles.scss:
body {
  margin: 0;
}
  1. Abra o popup e veja:

Exibição do color-pickerExibição do color-picker

Mas atualmente ele ainda não faz nada. O que nos leva ao próximo (e último) item.

Alterar o background color de Uma página

Agora que temos todas as ferramentas no lugar, queremos realmente aplicar a cor escolhida ao plano de fundo do site.

Vamos fazer isso:

  1. Adicione o método colorize ao app.component.ts :
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {
  title = 'angular-chrome-extension';
  color: string;

  public colorize() {
    chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
      const id = tabs[0].id;
      if (id == null) return;
      chrome.tabs.executeScript(id, {
        code: 'document.body.style.backgroundColor = "' + this.color + '";',
      });
    });
  }
}

Aqui estamos usando a API de tabs de novo — selectionando uma aba ativa e injetando programaticamente o content scriptna página.

  1. Faça um Event binding da propriedade colorPickerSelect ao método colorize(que será chamado após clicar em Aplicar) no app.component.html:
<span
  [style.color]="color"
  [cpToggle]="true"
  [cpDialogDisplay]="'inline'"
  [cpPositionRelativeToArrow]="true"
  [(colorPicker)]="color"
  [cpOKButtonText]="'Aplicar'"
  [cpOKButton]="true"
  (colorPickerSelect)="colorize()"
>
</span>

Adição de event-bind na propriedade do color-pickerAdição de event-bind na propriedade do color-picker

  1. Abra o popup, selecione uma cor e clique em Aplicar para objeto o resultado abaixo:

Aplicação da alteração do background na página.Aplicação da alteração do background na página.

Bonus: salvando a ultima cor selecionada

Para deixar as coisas mais produtivas, podemos salvar a última cor selecionada e carrega-la na próxima vez que abrirmos o pop-up.

Para isso, precisamos de algumas coisas:

  1. Adicionar a permissão de acesso ao storage no manifest.jsone erecarregar a extensão:
{
  "name": "angular-chrome-extension",
  "version": "1.0",
  "description": "Build an Extension with Angular",
  "manifest_version": 2,
  "permissions": ["activeTab", "webNavigation", "storage"],
  "background": {
    "scripts": ["background.js", "runtime.js"]
  },
  "page_action": {
    "default_popup": "index.html"
  }
}

Adição da permissão de acesso ao storage no array de permission do manifest.jsonAdição da permissão de acesso ao storage no array de permission do manifest.json

  1. Criar o método updateColor no app.component.tse fazer um event bind dele a propriedade colorPickerChange :
  public updateColor(color: string) {
    chrome.storage.sync.set({ color });
  }

Criação do método updateColor no app.component.tsCriação do método updateColor no app.component.ts

<span
  [style.color]="color"
  [cpToggle]="true"
  [cpDialogDisplay]="'inline'"
  [cpPositionRelativeToArrow]="true"
  [(colorPicker)]="color"
  [cpOKButtonText]="'Aplicar'"
  [cpOKButton]="true"
  (colorPickerSelect)="colorize()"
  (colorPickerChange)="updateColor($event)"
>
</span>

Realização do bind da propriedade colorPickerChange ao método updateColor no app.component.htmlRealização do bind da propriedade colorPickerChange ao método updateColor no app.component.html

  1. Definindo a cor inicial no storage assim que o pop-up for criado:
  ngOnInit(): void {
    chrome.storage.sync.get('color', ({ color }) => {
      this.color = color;
    });
  }

Atribuindo a cor iniciando no método ngOnInitAtribuindo a cor iniciando no método ngOnInit

  1. Opcional: definindo uma cor padrão no background script:
  chrome.storage.sync.set({ color: '#3aa757' });

definindo cor padrão no background.tsdefinindo cor padrão no background.ts

Conclusão

Embora a maioria das extensões não tenha uma interface do usuário complicada, algumas como por exemplo o Checker Plus ou 1PasswordX, têm uma interface do usuário bastante complicada.

Essas extensões seriam muito mais fáceis de construir e manter usando um dos frameworks populares da web, entre eles o Angular.

Espero que este artigo forneça todas as ferramentas e conhecimentos necessários para que você possa iniciar no desenvolvimento uma extensão do Chrome utilizando o Angular de maneira conveniente e eficiente.

O projeto utilizado está no GitHub e para acessá-lo clique aqui.

Esse artigo é uma adaptação/tradução e atualização que fiz do artigo original em Inglês do JeB Barabanov de 2019 que pode ser conferido aqui.

Espero que isso seja útil para você e até a próxima.