Skip to content

插件热更新

简介

主要是用到三方的js(evalCore.min.js), 在background.js中将放在服务器上的js通过fetch请求到本地,然后通过chrome.scripting.executeScript注入js到window上,
实现更新服务器上的js,插件中加载的js实时更新

主要配置

manifest.json主要配置,在permissions中添加上scripting权限, 并配置使用到的js
javascript
    {
        "content_scripts": {
            {
                "matches": [
                    "<all_urls>"
                ],
                "js": [
                    "static/evalCore.min.js",
                    "js/page.js"
                ],
                "css": [
                    "css/content.css",
                    "css/bootstrap.min.css"
                ],
                "run_at": "document_end"
            },
            {
                "matches": [
                    "<all_urls>"
                ],
                "js": [
                    "lib/popup.min.js"
                ]
            }
        },
        "background": {
            "service_worker": "js/background.js",
            "type": "module"
        },
        "permissions": [
            "contextMenus",
            "tabs",
            "notifications",
            "webRequest",
            "storage",
            "cookies",
            "scripting"
        ], 
         "web_accessible_resources": [
            {
                "resources": [
                    "img/*"
                ],
                "matches": [
                    "*://*/*"
                ]
            }
        ],
    }

background.js对应的主要配置,添加消息监听动态加载js

javascript
// 将js注入到window上
function executeScript(scriptContentList) {
  try {
    scriptContentList.forEach((scriptContent) => {
      const js = `${scriptContent}`;
      evalCore.getEvalInstance(window)(js); // 这里的window必传,将js绑定到window上
    });
  } catch (x) {
    console.log("x", x);
  }
}


const STATUSJS = "https://thirdorder.giikin.com/js/ad/";
//  对应的要使用的服务器上的js地址  最好是放在消息监听里面,方面后期加入新的js
const scriptjsList = [STATUSJS+'backgroundOrigin.js',STATUSJS+'TiktokClass.js']
let tabId = ''

// 动态加载js
function loadScript(tabId, sendResponse) {
    const fetchList = scriptjsList.map((item) =>
        fetch(item).then((response) => response.text())
    );
    Promise.all(fetchList).then((responseList) => {
        chrome.scripting
            .executeScript({
                target: { tabId },
                func: executeScript,
                args: [responseList],
            })
            .then(() => {
                sendResponse('注入成功')
            });
    })
}

const messageObj = {
    loadScript: (request, sender, sendResponse)=> {
        loadScript(sender.tab?.id, sendResponse)
    },
    postData: ()=> {}, //POST 请求逻辑
    getData: ()=> {}, //get 请求逻辑
}

// 消息监听
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  tabId = sender.tab?.id;
  messageObj[request.type] &&
    messageObj[request.type](request, sender, sendResponse);
  return true;
});

最好不要在background中处理业务逻辑,推荐仅作为与服务器的中转站,处理http请求,登录逻辑等


page.js主要代码

javascript
chrome.runtime.sendMessage(
    {
      type: "loadScript"
    },
    () => {
        // 注入成功之后的处理 这里可以使用服务器加载过来的js的方法了,注入到了当前window下了
    }
  );

完整的案例

参考广告花费插件:git地址: http://gitlab.giikin.cn/carlyang906/adsReportV3

【注】:使用到的evalCore.min.js 地址在花费插件中: V3/static/evalCore.min.js

Released Under The MIT License.