@felix-kling が既に述べたように、これはモジュール レベルの分離によるものであり、考えてみると非常に理にかなっています。それ以外の場合はServices
、他のモジュールだけでなく、abc
.
ただし、別の重要な理由があります。JS コード モジュールは 1 回開始され、その後キャッシュされるため、2 回インポートするとどうなるでしょうか。1two.jsm
回は既にインポートされたモジュールから、Services.jsm
もう 1 回はインポートされていない別のモジュールからです 現在、two.jsm
「見る」Services
ことは、他のどのモジュールが最初にインポートされたかに依存します! これは非常に厄介です。
その文脈では、「abc is import into obj()」に関するあなたのコメントは間違っています。コードは実際にabc
最上位のスコープにインポートされます。Cu.import
インポートする別のスコープを明示的に指定しない限り、常にトップレベルのスコープにインポートされます。
"abc" in this; // false
"abc" in obj; // false
obj.init();
"abc" in this; // true
"abc" in obj; // false!
にインポートtwo.jsm
する場合は、2 番目の引数を指定し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
など、とにかくインポートするいくつかのモジュールを自動インポートすると便利だと思います。しかし、レガシーの理由と下位互換性の制約により、これは発生せず、今後も発生しない可能性があります。(たとえば、ES6がデフォルトのグローバルを追加したため、インポートされたコードブレークがありました...;そのような後方互換性の問題/制約)。Services.jsm
XPCOMUtils.jsm
const {Promise} = Cu.import(..., {});
Promise
代替案?
当然のことCu.import
ですが、自分のものではなく、別のものを使用することです。アドオンの束。もちろん、すべての SDK アドオンには、独自の CommonJS スタイルのrequire()
実装があります。
- 必要に応じて、SDK を使用せずに、または SDK の選択した部分のみを使用して、SDK ローダーを実際に再利用できます。
loader
ドキュメントを参照してください。Erik がそれ以外の非 SDK Scriptishアドオンでローダーを作成することは知っています。
- 添え字ローダーに基づいて、独自のカスタム ローダーを作成できます
Sandbox
。たとえば、定型文でそうしましたextSDK
(loader.jsm 内のすべてのグローバル シンボルは、== loader.jsm::exports
各require
d モジュールに表示されます)。
require()
ただし、これを行うには、既存の JS コード モジュールをベース モジュールに移植するために、かなりの追加作業、追加の知識、および労力が必要になる場合があります。