我正在尝试包括 IOUtil.js
和 ChannelReplacement.js
在我的附加组件中,使用 Cu.import(...)
函数。这两个都使用了xpcom_generateQI
,我试图从XPCOM jsm 中获取它,但是这两个脚本无法访问它。
const {Cc, Ci, Cu, Cr} = require("chrome");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const xpcom_generateQI = XPCOMUtils.generateQI;
Cu.import(self.data.url("IOUtil.js"));
Cu.import(self.data.url("ChannelReplacement.js"));
给我 xpcom_generateQI is not defined
。
如何访问 main.js 中定义的函数?
最佳答案
问题
- 不要对本地 SDK 模块使用
Cu.import
。 SDK插件不要写JS代码模块,SDK使用CommonJS-style modules连同require()
设施一起,它还带有适当的免费清理,这不能说是 JS 代码模块和Cu.import
(你需要适本地Cu.unload
一切并可能自己杀死一些引用)。 - 那个 https-everywhere 的东西既不是 JS 代码模块也不是 SDK 模块,而是使用了下标加载器。要么转为SDK代码模块,要么自己使用下标加载器。
- 可以在不同的范围/模块中导入内置的 JS 代码模块。实际上不需要从 main 中提供可用的
xpcom_generateQI
(尽管可以做到;好吧,开始吧)。 - 为了面向 future ,您应该正确绑定(bind)您的
xpcom_generateQI
快捷方式,如XPCOMUtils.generateQI.bind(XPCOMUtils)
中所示。否则,如果实现发生变化并需要适当的this
,您的内容就会崩溃。 - 要从任何 CommonJS 模块中导出某些内容,您需要将其放入
exports
模块中。请参阅第一个链接。 - 要导入某些内容,请使用
require()
(再次是第一个链接)。 - 注意循环引用,其中模块 A 导入模块 B 导入模块 A。现在这有点管用(但只是有点,因为当模块 B 像这样导入时,模块 A 可能无法使用某些内容,因为模块 A未满载)。最好避免它。
示例1(循环)
所以这是一个循环require
的例子(main
imports modules
imports main
)
main.js
function someFunction() {
console.log("some function called");
}
exports.someFunction = someFunction;
var mod = require("./module");
mod.anotherFunction();
module.js
const { someFunction } = require("./main");
exports.anotherFunction = function() {
someFunction();
}
现在,由于循环引用,这是一个脆弱结构。如果现在可以正常工作,但当模块变得更复杂或 SDK 发生变化时,它可能会中断......最好将 someFunction
放入第三个模块。
示例 2(避免循环导入)
main.js
var mod = require("./module");
mod.anotherFunction();
// Or call someFunction directly
var { someFunction } = require("./utils");
someFunction();
module.js
const { someFunction } = require("./utils");
exports.anotherFunction = function() {
someFunction();
}
utils.js
function someFunction() {
console.log("some function called");
}
exports.someFunction = someFunction;
没有圈子了。如果你想重用 xpcom_generateQI
,你可以将它作为 exports
的一个属性放在 utils.js
中(在这个例子中),然后再 require它与 require("./utils")
.
https-无处不在
https-everywhere 的内容需要使用下标加载器进行转换或加载。我不建议使用下标加载器,因为很可能逐字逐句的 https-everywhere 代码不会自行清理。我实际上还建议不要通过在 (exports.xzy = ...
) 中添加一些东西来转换它。此代码不应在 SDK 中运行。最好创建您自己的实现,并在需要的任何地方借鉴 https 的想法。
关于javascript - 在导入模块中使用 main.js 中的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24587864/