[英]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.jsm
和XPCOMUtils.jsm
,那將XPCOMUtils.jsm
。 但是,由於遺留原因和向后兼容的限制,這種情況不會而且很可能永遠不會發生。 (例如,我的代碼中斷導致導入的const {Promise} = Cu.import(..., {});
因為ES6添加了默認的Promise
global ...;這種向后兼容的問題/約束)。
好吧,顯而易見的是,不要將Cu.import
用於自己的東西,而要使用其他東西。 一堆附加組件,包括 當然,所有SDK插件都具有自己的CommonJS風格的require()
實現。
loader
文檔。 我知道Erik在另一個非SDK Scriptish插件中創建了一個加載器。 Sandbox
編寫自己的自定義加載器。 如我這樣做,我extSDK
樣板(在loader.jsm所有全局符號== loader.jsm::exports
將是可見的每一個require
D模塊)。 但是這樣做可能需要大量額外的工作,額外的知識以及將現有的JS代碼模塊移植到基於require()
的模塊上的工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.