Usando Redux em extensões MV3 do Chrome

Nota de tradução : O artigo original foi escrito antes de MV3 ser conhecido. No entanto, é totalmente relevante para extensões MV3 (pelo menos por enquanto). Portanto, decidi mudar um pouco seu nome, acrescentando a menção de "MV3", o que não contradiz o conteúdo de forma alguma. Se alguém não sabe: MV3 é o novo formato / padrão para extensões do Chrome, a ser introduzido em janeiro de 2021.







Este artigo, dirigido a desenvolvedores web experientes, aborda (e resolve) o problema da utilização do Redux nos chamados. extensões orientadas a eventos ( orientadas a eventos) do Chrome.







Especificidade de extensões baseadas em eventos



O modelo de extensão orientado a eventos apareceu pela primeira vez no Chrome 22 em 2012. Nesse modelo, o script de plano de fundo da extensão (se houver) é carregado / executado apenas quando necessário (principalmente em resposta a eventos) e descarregado da memória quando não faz nada.







A documentação do desenvolvedor do Chrome recomenda fortemente o uso do modelo orientado a eventos para todas as novas extensões e a migração de extensões existentes usando o modelo persistente . Há, no entanto, uma exceção ( no MV3 não é mais relevante, portanto, a transição para um novo modelo no MV3 é obrigatória) Mas parece que muitas extensões ainda usam o modelo persistente, embora possam ser orientadas a eventos. Claro, muitos deles foram lançados pela primeira vez antes que o modelo baseado em eventos se tornasse conhecido. E agora seus autores simplesmente não têm incentivo para mudar para um novo modelo. Por um lado, isso (ainda) é opcional, mas por outro lado, significa a necessidade de muitas mudanças, não apenas no script de fundo, mas também em outros componentes de extensão. Além disso, muitos usam uma abordagem cross-browser durante o desenvolvimento.coletando extensões prontas para navegadores diferentes do mesmo código-fonte. O modelo orientado a eventos é atualmente compatível apenas com o Chrome e é significativamente diferente do modelo persistente compatível com outros navegadores. Naturalmente, isso complica o desenvolvimento entre navegadores.







No entanto, algumas das extensões relativamente mais recentes do Chrome também usam um modelo persistente e podem ser orientadas a eventos. Em última análise, o motivo é o mesmo que no caso da migração: há diferenças significativas entre os modelos orientados a eventos e persistentes, que são expressos principalmente na maneira como gerenciamos o estado de extensão.







O problema do Redux



— , -. - ( .. ), , . Redux.







Redux — , , . Redux .







, " " — Redux, . ( ), . , Webext Redux, . - - - . .







(persistent) , , . (, ) , . , , Webext Redux.













- , , , , . , , .. ( ). .









, chrome.storage



/ / . ( ) , chrome.storage



, API , .













API chrome.storage



, — . — , , " ".







, , -, . , , .







— API chrome.storage



Redux, Redux. , chrome.storage



, . , Redux - . - chrome.storage



Redux, , Redux chrome.storage



).







— Redux- chrome.storage



, chrome.storage



Redux. API chrome.storage



Redux, (store) Redux. createStore



Store



( Redux). :











, , Store



. ReduxedStorage



.







getState



subscribe



, .. chrome.storage



: get



onChanged



. , Store



, . , get



chrome.storage



ReduxedStorage



, onChanged



, . . getState



. subscribe



: - , onChanged



.







getState



subscribe



, chrome.storage



Store.dispatch



. set



, Redux, Redux , , dispatch



. - dispatch



ReduxedStorage



. . Redux , , Redux. , .







, , - . , , . , dispatch



, , "" createStore



, "" Store.dispatch



, dispatch



. , , , chrome.storage



, . chrome.storage.onChanged



, .







: chrome.storage:get



, . chrome.storage:get



, ( ). , init



, , , chrome.storage:get



. init



Redux, , , chrome.storage



.







ReduxedStorage



:









: chrome.storage



(this.key



), () chrome.storage.onChanged



, chrome.storage:get



. , , .. chrome.storage



.







, , - , this.state



, chrome.storage:set



, . . Redux dispatch



this.state



, , .. this.state



. , . 2- dispatch



this.state



, - chrome.storage:set



. , .







, dispatch



, Redux. ( 100 ), . — . dispatch



:







dispatch


, , . Redux. , Redux, middleware, Redux Thunk. Redux Thunk , , . :









delayAddTodo



'ADD_TODO'



1 .







dispatch



, this.buffStore.getState



this.buffStore.subscribe



. this.buffStore.subscribe



1 dispatch



, this.buffStore



null



( 100 dispatch



). dispatch



, .. , subscribe



.







, , .. , , Redux. , — , - , delayAddTodo



. , , Redux dispatch



. , this.buffStore



, , lastStore



. , this.buffStore



, lastStore



subscribe



. , subscribe



lastStore



, this.buffStore



, " "). subscribe



, / lastStore



, .







, , ..:







  • this.areaName



    , this.key



    / .
  • , API chrome.storage



    , , WrappedStorage



    .


, :









Seu uso é semelhante ao do Redux original, exceto que em nossa interface o criador da loja é envolvido em uma função e executado de forma assíncrona, retornando uma promessa em vez da loja criada.







O uso padrão da interface é assim:







Uso padrão


Além disso, com a sintaxe async/await



disponível a partir do ES 2017, essa interface pode ser usada assim:







Uso avançado


O código-fonte está disponível no Github.







Além disso, esta interface está disponível como um pacote no NPM:







npm install reduxed-chrome-storage
      
      






All Articles