繁体   English   中英

为什么在Firefox插件中,导入的对象无法访问导入者的导入模块?

[英]Why in Firefox Addon the imported objects can not access the importers' imported modules?

为了澄清起见,请考虑以下简化示例:

一个.js

Components.utils.import('resource://gre/modules/Services.jsm');

let obj = {

  init: function() {

   Components.utils.import('chrome://myaddon/modules/two.jsm', this);
  }

  // code here has access to Services.jsm
}

two.js

this.EXPORTED_SYMBOLS = ['abc'];

this.abc = {

  // abc is imported into obj()
  // however as part of obj (), abc{} does not have access to Services.jsm
}

我知道这是如何运作的,但问题是为什么?
结果是,例如,必须在每个模块中赋予Services.jsm
尽管Firefox缓存了模块,并且在性能上并没有多大区别,但我想知道是否可以避免重复导入?

就像已经提到过的@ felix-kling一样,这是由于模块级别的隔离,如果您考虑一下,这很有道理。 如果不是这样,则其他模块不仅可以看到Services还可以看到abc

但是,还有另一个重要原因:由于JS代码模块一次启动并在之后缓存,因此,如果两次导入two.jsm ,一次是从已经导入Services.jsm的模块中导入,一次是从另一个未导入的模块中导入,将会发生什么情况。 ? 现在, two.jsm “看到” Services将取决于首先导入了其他模块中的哪个! 这将是非常讨厌的。

在这种情况下,您对“将abc导入到obj()中”的评论是错误的。 您的代码实际上将abc导入顶级范围。 Cu.import将始终导入到顶级作用域,除非您明确指定要导入到的另一个作用域。

"abc" in this; // false
"abc" in obj; // false
obj.init();
"abc" in this; // true
"abc" in obj; // false!

如果要将two.jsm导入obj ,则需要使用第二个参数调用Cu.import

let obj = {
  init: function() {
   Components.utils.import('chrome://myaddon/modules/two.jsm', this);
  }
};
"abc" in this; // false
"abc" in obj; // false
obj.init();
"abc" in this; // false
"abc" in obj; // true

但这当然不会影响Services的可见性。

我想如果Cu.import只是自动导入您仍然要导入的某些模块(例如Services.jsmXPCOMUtils.jsm ,那将XPCOMUtils.jsm 但是,由于遗留原因和向后兼容的限制,这种情况不会而且很可能永远不会发生。 (例如,我的代码中断导致导入的const {Promise} = Cu.import(..., {});因为ES6添加了默认的Promise global ...;这种向后兼容的问题/约束)。

备择方案?

好吧,显而易见的是,不要将Cu.import用于自己的东西,而要使用其他东西。 一堆附加组件,包括 当然,所有SDK插件都具有自己的CommonJS风格的require()实现。

  • 实际上,您可以重新使用SDK加载器,而无需使用SDK,或者根据需要仅使用SDK的选定部分。 请参阅loader文档。 我知道Erik在另一个非SDK Scriptish插件中创建了一个加载器。
  • 您可以基于下标加载器(也许是Sandbox编写自己的自定义加载器。 如我这样做,我extSDK样板(在loader.jsm所有全局符号== loader.jsm::exports将是可见的每一个require D模块)。

但是这样做可能需要大量额外的工作,额外的知识以及将现有的JS代码模块移植到基于require()的模块上的工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM