after chrome 88 release in january I'd be able to start development and testing react redux development in mv3. here are the results:
besides some other big changes I think these are the most important ones. here is a part of my manifest.json:
...
"background": {
"service_worker": "sw.js"
},
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'"
},
...
for me sw.js only exists. because I prefer the background signalling work done by a redux middleware.
my sw.js file:
//sw.js
"use strict";
self.addEventListener("install", e => {
console.log("Service Worker Installed.");
});
self.addEventListener("activate", e => {
console.log("Service Worker Activated.");
});
and you need to register your service worker in your popup.js:
// somewhere in popup.js
...
// register service worker
if ("serviceWorker" in navigator) {
console.log("Service Worker Supported.");
window.addEventListener("load", () => {
navigator.serviceWorker.register("sw.js")
.then(reg => console.log("Service Registered.", reg))
.catch(err => console.error("ERROR!", err));
});
}
- webpack --mode=production
you need to compile only production even you are testing. otherwise you will face unsafe eval error.
here is js/jsx configuration in my webpack.config.js
{ // JS - BABEL LOADER
test: /\.(js|jsx|mjs)$/i,
exclude: /(node_modules|bower_components)/,
use: [
{
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"],
plugins: ["@babel/plugin-transform-runtime"], // for async functions (not dev, install this one as prod dependency)
}
}
]
},
unfortunately I couln't be able to persist redux store between tabs. so I wanted unlimited storage permission in manifest.json
//manifest.json
...
"permissions": [
...
"unlimitedStorage",
],
...
STORE DATA: make a "storage.js" middleware for redux and pass {storage: true} meta with it. for example:
// actions.js
const setThemeColor = color => ({
type: SET_THEME_COLOR,
payload: {
data: color, // theme_color : action.payload.data
meta: {
storage: true,
type: "string", // for storage middleware
key: "theme_color"
}
}
});
// storage.js middleware
...
const read = key => new Promise((resolve, reject) => {
if (chrome.runtime.lastError) {
reject("chrome runtime error read[key] @storage middleware");
} else {
chrome.storage.local.get(key, obj => {
resolve(obj);
});
}
});
const storage = store => next => action => {
// check if storage meta in action
if (action.payload && action.payload.meta && action.payload.meta.storage) {
let { type, key } = action.payload.meta;
switch (type) {
case "string":
read(key) // get saved value
.then(val => { // if key not exists
if (val[key] === undefined) val[key] = "";
return val;
})
// begin storage process
.then(val => {
chrome.storage.local.set({
...val, // don't change others
[key]: action.payload.data
}, () => {
return next(action); // save completed! continue next middleware.
});
})
.catch(err => {
console.error(err, "Some error occured @storage middleware.");
});
return;
RETRIVE DATA: make an "initLocalStorage.js" and import it in popup.js.
// initLocalStorage.js (logic may change according your data storing perefer)
// REDUX
import store from "../redux/store.js";
chrome.storage.local.get(null, all => {
store.dispatch({ type: `INIT_STORAGE`, payload: { data: all } });
});
and catch your "INIT_STORAGE" action in your reducers.
for every each reducer have an "INIT_STORAGE" action by default.
reduce your initial state and check if that key blongs to that reducer and place it if so.
//themeReducer.js
...
export default (state = initialState, { type, payload }) => {
let newState = { ...state };
switch (type) {
case INIT_STORAGE:
newState = Object.keys(newState).reduce((acc, cur) => {
if (cur in payload["data"]) {
acc[cur] = payload["data"][cur];
} else {
acc[cur] = newState[cur];
}
return acc;
}, {});
return newState;
...
this is as far as I can go for react redux extension development for mv3. maybe I will find a simpler way in the future.
have a nice day
Ulvi.
14 Şubat 2021 Pazar tarihinde saat 06:33:54 UTC+3 itibarıyla
marcu...@gmail.com şunları yazdı: