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
:
, , . 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:
Além disso, com a sintaxe async/await
disponível a partir do ES 2017, essa interface pode ser usada assim:
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