如何自动重新加载我正在开发的Chrome扩展程序?

And*_*rov 249 javascript google-chrome google-chrome-extension

每次我在扩展文件夹中保存文件时,我都希望我的chrome扩展程序重新加载,而不必在chrome:// extensions /中明确单击"reload".这可能吗?

编辑:我知道我可以更新 Chrome重新加载扩展程序的时间间隔,这是一个中途解决方案,但我宁愿让我的编辑器(emacs或textmate)触发 - 保存重新加载或要求Chrome监控更改目录.

Ari*_*rik 152

您可以为Chrome 使用" Extensions Reloader ":

使用扩展程序的工具栏按钮或浏览到" http://reload.extensions " 重新加载所有解压缩的扩展名

如果您曾经开发过Chrome扩展程序,那么您可能希望自动执行重新加载解压扩展程序的过程,而无需通过扩展程序页面.

"Extensions Reloader"允许您使用以下两种方式重新加载所有解压缩的扩展:

1 - 扩展的工具栏按钮.

2 - 浏览" http://reload.extensions ".

工具栏图标将通过单击重新加载解压缩的扩展名.

"通过浏览重新加载"旨在使用"后期构建"脚本自动执行重新加载过程 - 只需使用Chrome向您的脚本添加浏览" http://reload.extensions ",您就会有一个刷新的Chrome窗口.

更新:截至2015年1月14日,该扩展程序是开源的,可在GitHub上获得.

  • Woaw,我只是通过使用[grunt-open](https://github.com/onehealth/grunt-open)来设置[gruntjs](http://gruntjs.com/)来使用这个插件.修改文件时http:// reload.extensions`.它现在的行为与livereload完全相同,但每次修改指定的插件文件时都会打开一个恼人的chrome窗口:P.谢谢! (29认同)
  • 这是迄今为止最好的解决方案,但是每次我修改它正在使用的文件时,它仍然不容易更新扩展,这是我理想的样子. (3认同)
  • 谢谢.想提一下我使用PhpStorm,并添加了一个工具栏按钮,用"reload.extensions"url调用chrome.exe.每当我想测试代码时,我按下该按钮,Chrome就会弹出更新的插件. (2认同)

Rob*_*b W 57

更新:我添加了一个选项页面,因此您无需再手动查找和编辑扩展程序的ID.CRX和源代码位于:https://github.com/Rob--W/Chrome-Extension-Reloader
Update 2:添加了快捷方式(请参阅我在Github上的存储库).
原始代码包括基本功能,如下所示.


创建扩展,并将Browser Action方法与chrome.extension.managementAPI 结合使用,以重新加载解压缩的扩展.

下面的代码会向Chrome添加一个按钮,该按钮会在点击后重新加载扩展程序.

manifest.json

{
    "name": "Chrome Extension Reloader",
    "version": "1.0",
    "manifest_version": 2,
    "background": {"scripts": ["bg.js"] },
    "browser_action": {
        "default_icon": "icon48.png",
        "default_title": "Reload extension"
    },
    "permissions": ["management"]
}
Run Code Online (Sandbox Code Playgroud)

bg.js

var id = "<extension_id here>";
function reloadExtension(id) {
    chrome.management.setEnabled(id, false, function() {
        chrome.management.setEnabled(id, true);
    });
}
chrome.browserAction.onClicked.addListener(function(tab) {
    reloadExtension(id);
});
Run Code Online (Sandbox Code Playgroud)

icon48.png:选择任何漂亮的48x48图标,例如:
Google Chrome http://icons.iconarchive.com/icons/google/chrome/48/Google-Chrome-icon.png 谷歌浏览器


小智 38

在任何功能或事件中

chrome.runtime.reload();
Run Code Online (Sandbox Code Playgroud)

将重新加载您的扩展程序(docs).您还需要更改manifest.json文件,添加:

...
"permissions": [ "management" , ...]
...
Run Code Online (Sandbox Code Playgroud)

  • 我猜我们应该从后台脚本中调用`chrome.runtime.reload()` (3认同)

Vit*_*don 38

我做了一个简单的可嵌入脚本进行热重载:

https://github.com/xpl/crx-hotreload

它会在扩展程序的目录中监视文件更改.检测到更改后,它会重新加载扩展并刷新活动选项卡(以重新触发更新的内容脚本).

  • 通过检查文件的时间戳来工作
  • 支持嵌套目录
  • 在生产配置中自动禁用自身

  • 不适用于清单版本 3 (4认同)
  • 答案需要更多支持。与Webpack --watch结合使用也可以很好地工作,因为您可以将其放在构建文件夹中,以便仅在构建过程完成后进行更新。没有复杂的Webpack生成后命令插件。 (3认同)
  • 如果您正在寻找"口味"解决方案,就是这样. (2认同)

Cez*_*sto 16

长话短说

创建一个 WebSocket 服务器,将消息分派到可以处理更新的后台脚本。如果您正在使用 webpack 并且不打算自己动手,则webpack-run-chrome-extension可以提供帮助。

回答

您可以创建一个 WebSocket 服务器来作为 WebSocket 客户端(通过对象)与扩展进行通信window。然后,扩展程序将通过将 WebSocket 服务器附加到某些侦听器机制(如 webpack devServer)来侦听文件更改。

文件有变化吗?设置服务器向扩展发送请求更新的消息(向客户端广播 ws 消息)。然后,扩展程序会重新加载,回复“确定,已重新加载”,并继续侦听新的更改。

在此输入图像描述

计划

  1. 设置 WebSocket 服务器(以发送更新请求)
  2. 找到一个可以告诉您文件何时更改的服务(webpack/其他捆绑软件)
  3. 当更新发生时,向客户端发送消息请求更新
  4. 设置 WebSocket 客户端(用于接收更新请求)
  5. 重新加载扩展

如何

对于 WebSocket 服务器,请使用ws. 对于文件更改,请使用一些侦听器/钩子(如 webpack 的watchRun钩子)。对于客户端部分,原生 WebSocket。然后,扩展程序可以将 WebSocket 客户端附加到后台脚本上,以保持服务器(由 webpack 托管)和客户端(附加在扩展程序后台的脚本)之间的同步。

现在,要使扩展自行重新加载,您可以在chrome.runtime.reload()每次来自服务器的上传请求消息时调用它,甚至可以使用chrome.management.setEnabled()(manifest 中的 require "permissions": [ "management" ]) 创建一个“重新加载扩展”来为您执行此操作。

在理想情况下,类似工具webpack-dev-server或任何其他 Web 服务器软件都可以chrome-extension原生提供对 URL 的支持。在此之前,拥有一台服务器来代理对扩展程序的文件更改似乎是迄今为止最好的选择。

可用的开源替代方案

如果您正在使用 webpack 并且不想自己创建它,我制作了webpack-run-chrome-extension,它完成了我上面的计划。


小智 11

mozilla 的伟大人士刚刚发布了一个新的https://github.com/mozilla/web-ext,您可以使用它来启动web-ext run --target chromium

  • 这对我来说是最好的解决方案。我还用它来签署我的扩展 (2认同)

ref*_*lio 10

另一种解决方案是创建自定义livereload脚本(extension-reload.js):

// Reload client for Chrome Apps & Extensions.
// The reload client has a compatibility with livereload.
// WARNING: only supports reload command.

var LIVERELOAD_HOST = 'localhost:';
var LIVERELOAD_PORT = 35729;
var connection = new WebSocket('ws://' + LIVERELOAD_HOST + LIVERELOAD_PORT + '/livereload');

connection.onerror = function (error) {
  console.log('reload connection got error:', error);
};

connection.onmessage = function (e) {
  if (e.data) {
    var data = JSON.parse(e.data);
    if (data && data.command === 'reload') {
      chrome.runtime.reload();
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

此脚本使用websockets连接到livereload服务器.然后,它将在livereload重新加载消息时发出chrome.runtime.reload()调用.下一步是添加此脚本以在manifest.json中作为后台脚本运行,瞧!

注意:这不是我的解决方案.我只是张贴它.我在生成的Chrome Extension生成器代码中找到了它(很棒的工具!).我在这里张贴这个,因为它可能有所帮助.


Joh*_*sma 10

我正在使用快捷方式重新加载。我不想在保存文件时一直重新加载

所以我的方法是轻量级的,你可以将重新加载功能保留在

清单文件

{
    ...
    "background": {
        "scripts": [
            "src/bg/background.js"
        ],
        "persistent": true
    },
    "commands": {
        "Ctrl+M": {
            "suggested_key": {
                "default": "Ctrl+M",
                "mac": "Command+M"
            },
            "description": "Ctrl+M."
        }
    },
    ...
}
Run Code Online (Sandbox Code Playgroud)

src/bg/background.js

chrome.commands.onCommand.addListener((shortcut) => {
    console.log('lets reload');
    console.log(shortcut);
    if(shortcut.includes("+M")) {
        chrome.runtime.reload();
    }
})
Run Code Online (Sandbox Code Playgroud)

现在在 chrome 浏览器中按 Ctrl + M 重新加载


Gmo*_*onC 9

Chrome扩展程序有一个不允许的权限系统(SO 中的某些人遇到了与您相同的问题),因此要求他们"添加此功能"并不适用于IMO.有来自Chromium Extensions Google Groups的邮件,其中提议的解决方案(理论)使用chrome.extension.getViews(),但不保证也可以使用.

如果可以添加到manifest.json某些Chrome内部页面chrome://extensions/,可以创建一个可以与Reload锚点交互的插件,并使用XRefresh等外部程序(一个Firefox插件 - 使用Ruby和WebSocket 的Chrome版本)),你会实现你所需要的:

XRefresh是一个浏览器插件,由于所选文件夹中的文件更改,它将刷新当前网页.这样就可以使用您喜欢的HTML/CSS编辑器进行实时页面编辑.

这是不可能的,但我认为你可以用不同的方式使用同样的概念.

您可以尝试找到第三方解决方案,在看到文件中的修改后(我不知道emacs既不是Textmate,但在Emacs中,可以在"保存文件"操作中绑定应用程序调用),点击特定应用程序的特定坐标:在这种情况下,它是Reload您的扩展程序中的锚点(您只需为此重新加载打开Chrome窗口).

(疯狂的地狱,但它可能工作)


Sco*_*ott 7

这是一个可用于监视文件以进行更改的函数,并在检测到更改时重新加载.它通过AJAX轮询它们,并通过window.location.reload()重新加载.我想你不应该在分发包中使用它.

function reloadOnChange(url, checkIntervalMS) {
    if (!window.__watchedFiles) {
        window.__watchedFiles = {};
    }

    (function() {
        var self = arguments.callee;
        var xhr = new XMLHttpRequest();

        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                if (__watchedFiles[url] &&
                    __watchedFiles[url] != xhr.responseText) {
                    window.location.reload();
                } else {
                    __watchedFiles[url] = xhr.responseText
                    window.setTimeout(self, checkIntervalMS || 1000);
                }
            }
        };

        xhr.open("GET", url, true);
        xhr.send();
    })();
}

reloadOnChange(chrome.extension.getURL('/myscript.js'));
Run Code Online (Sandbox Code Playgroud)


Rob*_*ler 6

也许我参加派对有点晚了,但我已经通过创建https://chrome.google.com/webstore/detail/chrome-unpacked-extension/fddfkmklefkhanofhlohnkemejcbamln为我解决了这个问题.

它通过重新加载chrome://extensions页面来工作,只要file.change事件通过websockets传入.

file.change可以在此处找到有关如何在扩展文件夹中进行文件更改时发出事件的基于Gulp的示例:https://github.com/robin-drexler/chrome-extension-auto-reload-watcher

为什么要重新加载整个选项卡而不是仅使用扩展管理API来重新加载/重新启用扩展?目前再次禁用和启用扩展会导致任何打开的检查窗口(控制台日志等)关闭,我发现在活动开发过程中这些窗口太烦人了.


Eug*_*hov 5

如果您使用 webpack 进行开发,则有一个自动重新加载插件:https : //github.com/rubenspgcavalcante/webpack-chrome-extension-reloader

const ChromeExtensionReloader = require('webpack-chrome-extension-reloader');

plugins: [
    new ChromeExtensionReloader()
]
Run Code Online (Sandbox Code Playgroud)

如果你不想修改 webpack.config.js,还附带了一个 CLI 工具:

npx wcer
Run Code Online (Sandbox Code Playgroud)

注意:即使您不需要(空的)后台脚本,它也是必需的,因为它会在那里注入重新加载代码。