我如何自动重载一个Chrome扩展I'm开发?

我想为我的chrome扩展重新加载每次我保存在扩展文件夹中的文件,而不必显式点击“重新加载”在chrome://extensions/。这可能吗?

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

99683 次浏览

这不能直接完成。对不起。

如果你想把它作为一个功能,你可以在http://crbug.com/new请求它

Chrome扩展有一个权限系统,它不允许它(一些人在SO 和你有同样的问题吗),所以要求他们“添加此功能”是不会工作的IMO。有一个邮件从铬扩展谷歌组使用chrome.extension.getViews()建议的解决方案(理论),但不保证工作。

如果有可能在manifest.json中添加一些像chrome://extensions/这样的Chrome内部页面,就有可能创建一个与Reload锚交互的插件,并且,使用像XRefresh这样的外部程序(一个Firefox插件-有一个使用Ruby和WebSocket的Chrome版本),你将实现你所需要的:

XRefresh是一个浏览器插件 是否会刷新当前网页 所选文件夹中的文件更改。这 使它有可能做活页 使用您最喜欢的HTML/CSS编辑 编辑器。< / p >

这是不可能做到的,但我认为你可以用不同的方式来使用这个概念。

你可以尝试找到第三方解决方案,而不是,在看到文件中的修改后(我不知道emacs也不知道Textmate,但在emacs中可以绑定一个应用程序调用在“保存文件”动作),只是在特定应用程序的特定坐标中单击:在这种情况下,它是Reload锚从你的扩展在开发中(你留下一个Chrome窗口打开只是为了这个重载)。

(疯狂至极,但可能管用)

你的内容文件,如html和清单文件是不能改变没有安装扩展,但我相信JavaScript文件是动态加载,直到扩展已经打包。

我知道这是因为当前的项目,我通过Chrome扩展API工作,似乎每次我刷新一个页面加载。

是的,你可以间接地做!这是我的解决方案。

在manifest.json

{
"name": "",
"version": "1.0.0",
"description": "",
"content_scripts":[{
"run_at":"document_end",
"matches":["http://*/*"],
"js":["/scripts/inject.js"]
}]
}

在inject.js

(function() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = 'Your_Scripts';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(script, s);
})();

注入的脚本可以从任何位置注入其他脚本。

这种技术的另一个好处是你可以忽略孤立的世界的限制。看到内容脚本执行环境

更新:我已经添加了一个选项页面,这样你就不必再手动查找和编辑扩展的ID了。CRX和源代码在:https://github.com/Rob--W/Chrome-Extension-Reloader
更新2:添加快捷方式(见我的仓库在Github).
原始代码包括基本功能如下所示。< /子>


创建一个扩展,并使用浏览器动作方法与chrome.extension.management API一起重新加载已解包的扩展。

下面的代码为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"]
}

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);
});

icon48.png:选择任何漂亮的48x48图标,例如:
谷歌Chrome 谷歌Chrome

这里有一个函数,您可以使用它来监视文件的更改,并在检测到更改时重新加载。它通过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'));

你可以在Chrome中使用"Extensions Reloader":

使用扩展的工具栏按钮或浏览“http://reload.extensions”重新加载所有已解压的扩展

如果你曾经开发过Chrome扩展,你可能想要 自动重新加载已解包扩展的过程

.

.

"Extensions Reloader"允许你重新加载所有未打包的扩展 使用2种方式:

1 -扩展的工具栏按钮。

2 -浏览到“http://reload.extensions”。

工具栏图标将使用一次单击重新加载已解压的扩展。

“通过浏览重新加载”是为了使重新加载过程自动化 使用“后构建”脚本-只需添加一个浏览 "http://reload.extensions"使用Chrome到你的脚本,你会

更新:截至2015年1月14日,扩展是开源的,可以在GitHub上找到

感谢@GmonC和@Arik和一些空闲时间,我设法让它工作。我必须更改两个文件才能使其工作。

(1)安装LiveReload和Chrome扩展的应用程序。 这将在文件更改时调用一些脚本。< / p >

(2)打开<LiveReloadInstallDir>\Bundled\backend\res\livereload.js

(3)更改行#509

this.window.location.href = "http://reload.extensions";

现在安装另一个扩展Extensions Reloader,它有有用的链接处理程序,在导航到"http://reload.extensions"时重新加载所有开发扩展

现在以这种方式更改扩展的background.min.js

if((d.installType=="development")&&(d.enabled==true)&&(d.name!="Extensions Reloader"))

替换为

if((d.installType=="development")&&(d.enabled==true)&&(d.name!="Extensions Reloader")&&(d.name!="LiveReload"))

打开LiveReload应用程序,隐藏扩展重新加载按钮,并通过单击工具栏中的按钮激活LiveReload扩展,您现在将重新加载页面和每个文件更改扩展,同时使用所有其他好东西从LiveReload (css重新加载,图像重新加载等)

唯一不好的是,你将不得不重复在每次扩展更新上更改脚本的过程。为避免更新,请将扩展添加为未打包的扩展。

当我有更多的时间来处理这个时,我可能会创建一个扩展,消除对这两个扩展的需求。

在此之前,我正在处理我的扩展Projext用斧者

在任何场合或事件中

chrome.runtime.reload();

将重新加载你的扩展(文档)。你还需要修改manifest.json文件,添加:

...
"permissions": [ "management" , ...]
...

也许有点晚了,但我认为crxreload可能适合你。这是我在开发时尝试重新加载保存工作流的结果。

刚刚发现了一个新的基于咕哝着说的项目,它提供了引导,脚手架,一些自动预处理功能,以及自动重新加载(不需要交互)。

引导你的Chrome扩展 from Websecurify

我已经fork了LiveJS来允许打包应用程序的实时重新加载。只需将文件包含在应用程序中,每次保存文件时,应用程序将自动重载。

另一个解决方案是创建自定义liverload脚本(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();
}
}
};

这个脚本使用websockets连接到liverload服务器。然后,它会在重载消息时发出一个chromium .runtime.reload()调用。下一步是将该脚本添加到清单中作为后台脚本运行。Json,瞧!

注意:这不是我的解决方案。我只是把它发布出来。我在Chrome扩展生成器(伟大的工具!)的生成代码中找到了它。我把这个贴在这里,因为它可能有帮助。

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

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

关于如何在扩展文件夹中的文件更改时触发file.change事件的基于gulp的示例可以在这里找到:https://github.com/robin-drexler/chrome-extension-auto-reload-watcher

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

正如文档中提到的:下面的命令行将重新加载应用程序

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --load-and-launch-app=[path to the app ]

所以我只是创建了一个shell脚本,并从gulp调用该文件。超级简单:

var exec = require('child_process').exec;






gulp.task('reload-chrome-build',function(cb){


console.log("reload");


var cmd="./reloadchrome.sh"


exec(cmd,function (err, stdout, stderr) {
console.log("done: "+stdout);


cb(err);
}
);});

在脚本上运行必要的监视命令,并在需要时调用重载任务。干净,简单。

这正是AutoIt等软件或替代软件大放异彩的地方。关键是编写一个模拟当前测试阶段的脚本。至少要习惯使用其中的一种,因为许多技术都没有明确的工作流程/测试路径。

Run("c:\Program Files (x86)\Google\Chrome\Application\chrome.exe")
WinWaitActive("New Tab - Google Chrome")
Send("^l")
Send("chrome://extensions{ENTER}")
WinWaitActive("Extensions - Google Chrome")
Send("{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}")
Send("{ENTER}")
WinWaitActive("Extensions - Google Chrome")
Send("{TAB}{TAB}")
Send("{ENTER}")
WinWaitActive("Developer Tools")
Send("^`")

显然,您更改了代码以适应您的测试/迭代需求。确保标签点击是真的锚标签是在chrome://扩展站点。您还可以使用相对于窗口的鼠标移动和其他类似的宏。

我将以类似于下面的方式将脚本添加到Vim:

map <leader>A :w<CR>:!{input autoit loader exe here} "{input script location here}"<CR>

这意味着当我在Vim中,我按下ENTER上面的按钮(通常负责:|和\),即领导按钮,并跟随一个大写的“a”,它保存并开始我的测试阶段脚本。

请确保填写{input…}节在上面的Vim/热键脚本适当。

许多编辑器允许你用热键做类似的事情。

AutoIt的替代品可以在在这里中找到。

Windows: AutoHotkey

Linux: xdotool, xbindkeys

Mac: Automator

如果你有一台Mac,最简单的方法就是使用Alfred App!

只需要获得阿尔弗雷德应用程序与Powerpack,然后添加下面链接中提供的工作流,并自定义你想要的热键(我喜欢使用⌘+ + R)。

现在,每次你使用热键,谷歌Chrome将重新加载,无论你当时在哪个应用程序。

如果你想使用其他浏览器,打开AppleScript在阿尔弗雷德首选工作流程和替换“谷歌Chrome”与“Firefox”,“Safari”,…

我还将在这里显示在ReloadChrome。alfredworkflow文件中使用的/usr/bin/osascript脚本的内容,以便您可以看到它在做什么。

tell application "Google Chrome"
activate
delay 0.5
tell application "System Events" to keystroke "r" using command down
delay 0.5
tell application "System Events" to keystroke tab using command down
end tell

工作流文件是ReloadChrome.alfredworkflow

使用npm init创建一个包。Json在根目录下

npm install --save-dev gulp-open && npm install -g gulp

然后创建gulpfile.js

它看起来像:

/* File: gulpfile.js */


// grab our gulp packages
var gulp  = require('gulp'),
open = require('gulp-open');


// create a default task and just log a message
gulp.task('default', ['watch']);


// configure which files to watch and what tasks to use on file changes
gulp.task('watch', function() {
gulp.watch('extensionData/userCode/**/*.js', ['uri']);
});


gulp.task('uri', function(){
gulp.src(__filename)
.pipe(open({uri: "http://reload.extensions"}));
});

这适用于我开发CrossRider,你可能会观察改变路径,你看文件在,也假设你有npm和节点安装。

我想一夜之间重新加载(更新)我的扩展,这是我在background.js中使用的:

var d = new Date();
var n = d.getHours();
var untilnight = (n == 0) ? 24*3600000 : (24-n)*3600000;
// refresh after 24 hours if hour = 0 else
// refresh after 24-n hours (that will always be somewhere between 0 and 1 AM)
setTimeout(function() {
location.reload();
}, untilnight);
< p >问候, 彼得。< / p >

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

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

它监视扩展名目录中的文件更改。当检测到更改时,它重新加载扩展并刷新活动选项卡(以重新触发更新的内容脚本)。

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

免责声明:我自己开发了这个扩展。

Clerc - Chrome Live扩展重新加载客户端

连接到与liverload兼容的服务器,每次保存时自动重新加载扩展。

额外的好处:在你的部分有一点额外的工作,你也可以自动重新加载你的扩展改变的网页。

大多数网页开发人员使用带有某种监控器的构建系统,该系统自动构建文件并重新启动服务器并重新加载网站。

开发扩展不应该有那么大的不同。Clerc为Chrome开发者带来了同样的自动化。使用liverload服务器设置一个构建系统,Clerc将侦听重新加载事件以刷新扩展。

唯一的大问题是对manifest.json的更改。清单中的任何微小的拼写错误都可能导致进一步的重新加载尝试失败,并且您将被卡住卸载/重新安装扩展以再次加载更改。

在重新加载之后,Clerc将完整的重新加载消息转发给您的扩展,因此您可以选择使用提供的消息来触发进一步的刷新步骤。

我主要在Firefox中开发,其中web-ext run在文件更改后自动重新加载扩展名。一旦准备就绪,我会在Chrome中进行最后一轮测试,以确保没有Firefox中没有出现的任何问题。

但是,如果你想主要在Chrome上开发,并且不想安装任何第三方扩展,那么另一个选择是在扩展的文件夹中创建一个test.html文件,并添加一堆SSCCE的。然后,该文件使用一个普通的<script>标记来注入扩展脚本。

您可以使用它进行95%的测试,然后当您想在现场测试它时手动重新加载扩展。

这并不能完全重现扩展所运行的环境,但对于许多简单的事情来说已经足够好了。

BROWSER-SYNC

使用惊人的Browser-Sync

  • 更新浏览器(任何)当源代码改变(HTML, CSS,图像等)
  • 支持Windows、MacOS和Linux操作系统
  • 您甚至可以使用移动设备观看您的代码更新(实时)

MacOS上安装(查看它们在其他操作系统上安装的帮助)

安装NVM,这样您就可以尝试任何Node版本

brew install nvm             # install a Node version manager
nvm ls-remote                # list available Node versions
nvm install v10.13.0         # install one of them
npm install -g browser-sync  # install Browser-Sync

如何使用浏览器同步静态网站

让我们来看两个例子:

browser-sync start --server --files . --host YOUR_IP_HERE --port 9000


browser-sync start --server --files $(ack --type-add=web:ext:htm,html,xhtml,js,css --web -f | tr \\n \ ) --host $(ipconfig getifaddr en0) --port 9000

--server选项允许你在终端的任何地方运行本地服务器,而--files选项允许你指定跟踪哪些文件的更改。我更喜欢更具体的跟踪文件,所以在第二个例子中,我使用ack列出特定的文件扩展名(重要的是,这些文件没有带空格的文件名),还使用__abc3找到我在MacOS上的当前IP。

如何使用浏览器同步动态网站

如果您正在使用PHP、Rails等,您已经有一个正在运行的服务器,但是当您更改代码时它不会自动刷新。所以你需要使用--proxy开关来让浏览器同步知道该服务器的主机在哪里。

browser-sync start --files $(ack --type-add=rails:ext:rb,erb,js,css,sass,scss,coffee --rails -f | tr \\n \ ) --proxy 192.168.33.12:3000 --host $(ipconfig getifaddr en0) --port 9000 --no-notify --no-open

在上面的例子中,我已经在我的浏览器192.168.33.12:3000上运行了一个Rails应用程序。它实际上运行在使用Vagrant盒子的虚拟机上,但我可以使用该主机上的端口3000访问虚拟机。我喜欢--no-notify来停止浏览器同步每当我改变我的代码时在浏览器上发送一个通知警报,--no-open来停止浏览器同步行为,当服务器启动时立即加载一个浏览器选项卡。

重要的是:以防你使用Rails,避免在开发中使用Turbolinks,否则你将无法在使用--proxy选项时单击链接。

希望对别人有用。我尝试了许多技巧来刷新浏览器(甚至是我之前使用AlfredApp提交的关于这个StackOverflow问题的旧帖子),但这是真正的方法;没有更多的黑客,它只是流动。

信贷: 用一个命令启动本地实时重载web服务器

如果你使用webpack开发,有一个自动重载插件: https://github.com/rubenspgcavalcante/webpack-chrome-extension-reloader < / p >
const ChromeExtensionReloader = require('webpack-chrome-extension-reloader');


plugins: [
new ChromeExtensionReloader()
]

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

npx wcer

注意:一个(空的)后台脚本是必需的,即使你不需要它,因为它是注入重载代码的地方。

作者推荐该webpack插件的下一个版本:https://github.com/rubenspgcavalcante/webpack-extension-reloader。这对我来说很有效。

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

所以我的方法是轻量级的,你可以保留重载函数

manifest.json

{
...
"background": {
"scripts": [
"src/bg/background.js"
],
"persistent": true
},
"commands": {
"Ctrl+M": {
"suggested_key": {
"default": "Ctrl+M",
"mac": "Command+M"
},
"description": "Ctrl+M."
}
},
...
}

src / bg / background.js

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

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

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

博士TL;

创建一个WebSocket服务器,该服务器将消息分派给后台脚本,以处理更新。如果你正在使用webpack,不打算自己做,webpack-run-chrome-extension可以帮助。

回答

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

文件改变了吗?设置服务器向扩展发送请求更新的消息(将ws消息广播到客户机)。扩展然后重新加载,回复“ok,重新加载”;并不断倾听新的变化。

enter image description here

计划

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

如何

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

现在,为了让扩展重新加载自己,你可以在每次来自服务器的上传请求消息时调用它中的chrome.runtime.reload(),或者甚至创建一个“重新加载扩展”。这将为你做,使用chrome.management.setEnabled()(需要"permissions": [ "management" ]在manifest)。

在理想的情况下,像webpack-dev-server或任何其他web服务器软件这样的工具可以在本地提供对chrome-extension url的支持。在此之前,使用服务器代理扩展名的文件更改似乎是目前为止的最佳选择。

可用的开源替代方案

如果你正在使用webpack并且不想自己创建它,我创建了webpack-run-chrome-extension,它做了我上面计划的事情。

苹果只

使用Extensions Reloader:

使用打印稿

  1. 将你的观察者添加到你的项目:yarn add tsc-watch

  2. 将命令添加到scriptspackage.json

...
"scripts": {
"dev": "tsc-watch --onSuccess \"open -a '/Applications/Google Chrome.app' 'http://reload.extensions'\""
},
...
  1. 运行脚本yarn dev

使用JavaScript

  1. 将你的观察者添加到你的项目:yarn add watch-cli

  2. 将命令添加到scriptspackage.json

...
"scripts": {
"dev": "watch -p \"**/*.js\" -c \"open -a '/Applications/Google Chrome.app' 'http://reload.extensions'\""
},
...
  1. 运行脚本yarn dev

奖金:在Extensions Reloader选项中打开'reload current tab',这样它就会在做出更改后重新加载:

enter image description here

你可以使用Plasmo框架。

https://docs.plasmo.com/

< p > 这是2022年的最新答案
大多数答案都帮不了我,因为

  1. 所有的答案只是重新加载整个chrome扩展任何微小的变化。
  2. 重新加载chrome扩展,但不能自动打开弹出窗口或选项页。
  3. 大多数答案在manifest版本3上不起作用。
为了解决这些问题,我写了自己的esm-hmr库,并发布为npm包。
它像vite和workpack-hmr一样工作,但用于chrome扩展。
无需配置。只需运行npm create crx-hmr@latest
只要启动服务器npm start并开始构建chrome扩展

要贡献或创建新问题,请访问github页面:crx-hmr