在 Chrome 扩展中使用 Require.JS 时如何让 chrome.runtime.onInstalled 触发
How to get chrome.runtime.onInstalled to fire when using Require.JS in Chrome extension
我在安装扩展程序时遇到一些设置代码执行问题。我正在按照 Chrome 开发者页面的建议使用 chrome.runtime.onInstalled,但它没有触发。看来问题与 Require.JS 的使用有关。这是我的代码:
requirejs.config({...});// i'll not reproduce the whole config here for brevity
// Define the Global Object that will hold the extension functionality
var EXT = EXT || {};
// Start the main app logic.
requirejs(['chrome.storage', 'chrome.settings', 'chrome.tabs'],
function (chromeStorage, chromeSettings, chromeTabs) {
'use strict';
var getLocalRepos;
/**
* Executes the callback with an array of repositories as the parameter.
* @param {function} callback
*/
getLocalRepos = function (callback) {
'use strict';
chromeStorage.get('localRepos', callback);
};
// Take care of the extension lifecycle.
chrome.runtime.onInstalled.addListener(function (details) {
"use strict";
// Create dummy data to populate the local storage for testing purposes.
var dummyData = [
{
name: 'repo1',
description: 'description1',
username: 'reydel',
age: 'theAge'
},
{
name: 'repo2',
description: 'description2',
username: 'reydel',
age: 'theAge'
}
];
switch (details.reason) {
case 'install':
chromeStorage.set({ localRepos: dummyData }, function () {
// Do nothing
});
break;
}
});
// Bind all functions to an object in the Global Space to make them accessible from the outside scripts
// referencing the BackgroundPage object
window.EXT.getLocalRepos = getLocalRepos;
});
我已经在控制台中使用了侦听器回调中的代码并且它有效,只是事件没有被触发。
关于如何解决这个问题的任何想法?有人做过吗?
加载代码后会直接触发 chrome.runtime.onInstalled
事件。如果您异步添加事件侦听器,那么 onInstalled
事件在您添加事件侦听器时已经被调度。
要解决此问题,您必须同步初始化您的应用程序。不幸的是,require.js 被设计成一个异步脚本加载器。修改这个库使其同步是可以的,但是白费功夫没有任何好处。
要在 Chrome 扩展中使用 require-style 模块 (AMD),我强烈建议使用结合脚本的中间构建步骤(例如 r.js or grunt-contrib-requirejs), and almond.js 作为脚本加载器。相反require.js、almond.js 是否支持同步加载。
这是一个配置示例,您可以使用它来构建名为 all.js
的单个文件,其中包含 almond.js(作为脚本加载器),并使用 mymain.js
作为入口点(主脚本):
({
name: 'mymain',
out: 'all.js',
include: [
'almond'
],
skipModuleInsertion: true,
wrap: {
start: '(function(){',
// true = load synchronously. This is a feature of almond.js
end: 'require(["mymain"], null, null, true);})();'
}
})
为了避免名称空间污染,我将代码包装在一个立即调用的函数表达式中。如果您希望模块在全局命名空间中可用(例如用于调试),只需删除 (function(){
和 })();
.
有关这些配置选项(以及更多)的文档,请参阅 https://github.com/jrburke/r.js/blob/master/build/example.build.js。
尝试前面的例子:
- 安装
r.js
:npm install -g requirejs
- 将之前的配置保存为
myfancyname.build.js
- 创建名为
mymain.js
的脚本:define(function() { ... });
。
(这是一个简单的module definition without dependencies. Read the require.js documentation if you want to learn more about other kind of modules, such as modules with dependencies)。
- 运行 r.js 编译文件:
r.js -o myfancyname.build.js
- 现在您有一个名为
all.js
的文件可以加载,例如在 Chrome 扩展的清单文件中使用 "background": { "scripts": ["all.js"] }
。
我在安装扩展程序时遇到一些设置代码执行问题。我正在按照 Chrome 开发者页面的建议使用 chrome.runtime.onInstalled,但它没有触发。看来问题与 Require.JS 的使用有关。这是我的代码:
requirejs.config({...});// i'll not reproduce the whole config here for brevity
// Define the Global Object that will hold the extension functionality
var EXT = EXT || {};
// Start the main app logic.
requirejs(['chrome.storage', 'chrome.settings', 'chrome.tabs'],
function (chromeStorage, chromeSettings, chromeTabs) {
'use strict';
var getLocalRepos;
/**
* Executes the callback with an array of repositories as the parameter.
* @param {function} callback
*/
getLocalRepos = function (callback) {
'use strict';
chromeStorage.get('localRepos', callback);
};
// Take care of the extension lifecycle.
chrome.runtime.onInstalled.addListener(function (details) {
"use strict";
// Create dummy data to populate the local storage for testing purposes.
var dummyData = [
{
name: 'repo1',
description: 'description1',
username: 'reydel',
age: 'theAge'
},
{
name: 'repo2',
description: 'description2',
username: 'reydel',
age: 'theAge'
}
];
switch (details.reason) {
case 'install':
chromeStorage.set({ localRepos: dummyData }, function () {
// Do nothing
});
break;
}
});
// Bind all functions to an object in the Global Space to make them accessible from the outside scripts
// referencing the BackgroundPage object
window.EXT.getLocalRepos = getLocalRepos;
});
我已经在控制台中使用了侦听器回调中的代码并且它有效,只是事件没有被触发。
关于如何解决这个问题的任何想法?有人做过吗?
加载代码后会直接触发 chrome.runtime.onInstalled
事件。如果您异步添加事件侦听器,那么 onInstalled
事件在您添加事件侦听器时已经被调度。
要解决此问题,您必须同步初始化您的应用程序。不幸的是,require.js 被设计成一个异步脚本加载器。修改这个库使其同步是可以的,但是白费功夫没有任何好处。
要在 Chrome 扩展中使用 require-style 模块 (AMD),我强烈建议使用结合脚本的中间构建步骤(例如 r.js or grunt-contrib-requirejs), and almond.js 作为脚本加载器。相反require.js、almond.js 是否支持同步加载。
这是一个配置示例,您可以使用它来构建名为 all.js
的单个文件,其中包含 almond.js(作为脚本加载器),并使用 mymain.js
作为入口点(主脚本):
({
name: 'mymain',
out: 'all.js',
include: [
'almond'
],
skipModuleInsertion: true,
wrap: {
start: '(function(){',
// true = load synchronously. This is a feature of almond.js
end: 'require(["mymain"], null, null, true);})();'
}
})
为了避免名称空间污染,我将代码包装在一个立即调用的函数表达式中。如果您希望模块在全局命名空间中可用(例如用于调试),只需删除 (function(){
和 })();
.
有关这些配置选项(以及更多)的文档,请参阅 https://github.com/jrburke/r.js/blob/master/build/example.build.js。
尝试前面的例子:
- 安装
r.js
:npm install -g requirejs
- 将之前的配置保存为
myfancyname.build.js
- 创建名为
mymain.js
的脚本:define(function() { ... });
。
(这是一个简单的module definition without dependencies. Read the require.js documentation if you want to learn more about other kind of modules, such as modules with dependencies)。 - 运行 r.js 编译文件:
r.js -o myfancyname.build.js
- 现在您有一个名为
all.js
的文件可以加载,例如在 Chrome 扩展的清单文件中使用"background": { "scripts": ["all.js"] }
。