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

How do I auto-reload a Chrome extension I'm developing?

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

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


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

Reloads all unpacked extensions using the extension's toolbar button or by browsing to"http://reload.extensions"

If you've ever developed a Chrome extension, you might have wanted to
automate the process of reloading your unpacked extension without the
need of going through the extensions page.

"Extensions Reloader" allows you to reload all unpacked extensions
using 2 ways:

1 - The extension's toolbar button.

2 - Browsing to"http://reload.extensions".

The toolbar icon will reload unpacked extensions using a single click.

The"reload by browsing" is intended for automating the reload process
using"post build" scripts - just add a browse to
"http://reload.extensions" using Chrome to your script, and you'll
have a refreshed Chrome window.

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


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

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

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

manifest.json

1
2
3
4
5
6
7
8
9
10
11
{
   "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

1
2
3
4
5
6
7
8
9
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图标,例如:
谷歌浏览器http://icons.iconarchive.com/icons/google/chrome/48/Google-Chrome-icon.png Google Chrome


在任何功能或事件中

1
chrome.runtime.reload();

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

1
2
3
...
"permissions": ["management" , ...]
...


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

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

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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 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连接到livereload服务器。然后,它将在livereload重新加载消息时发出chrome.runtime.reload()调用。下一步是添加此脚本以在manifest.json中作为后台脚本运行,瞧!

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


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

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

XRefresh is a browser plugin which
will refresh current web page due to
file change in selected folders. This
makes it possible to do live page
editing with your favorite HTML/CSS
editor.

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

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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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'));


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

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

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

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


也许有点迟到但我认为crxreload可能对你有用。这是我在开发过程中尝试重新加载保存工作流程的结果。


如果没有安装扩展程序,你的内容文件如html和manifest文件是不可更改的,但我相信JavaScript文件是动态加载的,直到扩展程序被打包为止。

我知道这是因为我正在通过Chrome扩展程序API处理当前项目,并且似乎每次刷新页面都会加载。


免责声明:我自己开发了此扩展程序。

Clerc - 适用于Chrome Live Extension重定向客户端

Connect to a LiveReload compatible server to automatically reload your extension every time you save.

Bonus: with a little extra work on your part, you can also automatically reload the webpages that your extension alters.

大多数网页开发人员使用构建系统与某种观察者自动构建他们的文件并重新启动他们的服务器并重新加载网站。

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

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

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


使用npm init在目录root中创建package.json

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

然后创建一个gulpfile.js

看起来像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 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和节点。


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

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

的manifest.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
    ...
   "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

1
2
3
4
5
6
7
chrome.commands.onCommand.addListener((shortcut) => {
    console.log('lets reload');
    console.log(shortcut);
    if(shortcut.includes("+M")) {
        chrome.runtime.reload();
    }
})

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


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

1
2
3
4
5
6
7
8
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);

问候,
彼得


刚刚找到了一个新的基于grunt的项目,它提供了自举,脚手架,一些自动预处理功能,以及自动重新加载(无需交互)。

从Websecurify引导您的Chrome扩展程序


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

1
2
3
4
5
const ChromeExtensionReloader = require('webpack-chrome-extension-reloader');

plugins: [
    new ChromeExtensionReloader()
]

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

1
npx wcer

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


如果您有Mac,?最简单的方法是使用Alfred App!

只需使用Powerpack获取Alfred App,然后添加下面链接中提供的工作流程并自定义您想要的热键(我喜欢使用?+?+ R)。就这样。

现在,每次使用热键时,Google Chrome都会重新加载,无论您当时正在使用哪个应用程序。

如果您想使用其他浏览器,请在Alfred首选项工作流程中打开AppleScript,并将"Google Chrome"替换为"Firefox","Safari",...

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

1
2
3
4
5
6
7
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。


如文档中所述:以下命令行将重新加载应用程序

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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等软件或替代品的亮点。关键是编写一个模拟当前测试阶段的脚本。习惯于至少使用其中一种技术,因为许多技术没有明确的工作流程/测试路径。

1
2
3
4
5
6
7
8
9
10
11
12
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:// extensions网站中锚标记的位置。您还可以使用相对于窗口鼠标移动和其他此类宏。

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

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

这意味着当我在Vim时,按下ENTER上方的按钮(通常负责:|和)称为领导按钮,并用大写'A'跟随它,它保存并开始我的测试阶段脚本。

请确保正确填写上述Vim /热键脚本中的{input ...}部分。

许多编辑器将允许您使用热键执行类似操作。

可在此处找到AutoIt的替代方案。

对于Windows:AutoHotkey

对于Linux:xdotool,xbindkeys

对于Mac:Automator


我已经分叉LiveJS以允许实时重新加载打包应用程序。只需在您的应用中包含该文件,每次保存文件时,该应用都会自动重载。


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

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

您可以将其用于95%的测试,然后在要在实际站点上测试时手动重新加载扩展。

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


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


感谢@GmonC和@Arik以及一些业余时间,我设法让这个工作。我不得不更改两个文件才能使其工作。

(1)为该应用程序安装LiveReload和Chrome Extension。
这会在文件更改时调用一些脚本。

(2)打开\Bundled\backend
es\livereload.js

(3)将行#509更改为

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

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

(5)现在以这种方式改变扩展名background.min.js

<5233>

用。。。来代替

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

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

唯一不好的是,您必须在每次扩展更新时重复更改脚本的过程。要避免更新,请将扩展名添加为解压缩。

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

直到那时,我正在研究我的扩展Projext Axeman


浏览器的SYNC

使用惊人的浏览器同步

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

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

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

1
2
3
4
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

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

我们来看两个例子:

1
2
3
4
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 \
 \ ) --host $(ipconfig getifaddr en0) --port 9000

--server选项允许您在终端中的任何位置运行本地服务器,--files允许您指定将跟踪哪些文件以进行更改。我更喜欢对跟踪文件更具体,因此在第二个示例中,我使用ack列出特定文件扩展名(这些文件没有带空格的文件名很重要),并使用ipconfig查找我当前的IP在MacOS上。

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

如果您使用的是PHP,Rails等,则您已经有一个正在运行的服务器,但是当您对代码进行更改时它不会自动刷新。因此,您需要使用--proxy开关让浏览器同步知道该服务器的主机位置。

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

在上面的示例中,我已经在192.168.33.12:3000上的浏览器上运行了Rails应用程序。它确实在使用Vagrant框的VM上运行,但我可以使用该主机上的端口3000访问虚拟机。我喜欢--no-notify停止浏览器同步,每次我更改代码时都会在浏览器上发送通知警报,而--no-open则停止浏览器同步行为,以便在服务器启动时立即加载浏览器选项卡。

重要提示:如果您使用的是Rails,请避免在开发时使用Turbolinks,否则在使用--proxy选项时无法单击链接。

希望它对某人有用。我尝试了许多技巧来刷新浏览器(即使是我之前使用AlfredApp在StackOverflow问题上提交的旧帖子),但这真的是要走的路。没有更多的黑客,它只是流动。

信用:使用一个命令启动本地实时重新加载Web服务器


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

在manifest.json中

1
2
3
4
5
6
7
8
9
10
{
   "name":"",
   "version":"1.0.0",
   "description":"",
   "content_scripts":[{
       "run_at":"document_end",
       "matches":["http://*/*"],
       "js":["/scripts/inject.js"]
    }]
}

在inject.js中

1
2
3
4
5
6
7
8
(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);
})();

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

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


它不能直接完成。抱歉。

如果您希望将其视为一项功能,可以在http://crbug.com/new上申请