概要
RequireJSを使用し てサイトをAMDに変換しようとしています。サイトの大部分は、別のモジュール (主にユーティリティ メソッド) で定義されたグローバル変数に依存しています。モジュールは常にコンテンツ スクリプトの前にロードされるとは限らないため、これは開発者にとって深刻な問題につながります。
理想的な結果
特定のモジュールが読み込まれるまで、これらのページ内スクリプトが解析されないようにする方法が必要です。これにより、チーム メンバーは時間の許す限りゆっくりとそれらを削除できます。
リサーチ
- curl.jsには、いくつかのスクリプトを同期モードでロードする方法があることに気付きました。
- 以前はサポートされていたと思っていましたが、RequireJS 2+ に似たものは見つかりませんでした。(私の git foo は十分に強力ではありません。)
注意事項
- dev モードでスクリプト タグを介してモジュールをロードできることは承知していますが、モジュールを 2 か所にリストする必要があるため、ロードしないほうがよいでしょう。
私が試したこと
そこで私はポーリング ソリューションを生成しようとしました。これは大雑把なタイミングの while ループを実行し、その後ブレークアウトしてコールバックを実行します。これが私の実装です:
(function (global) { // Making this into a global, so I don't need to wait for the loader's extra timeout.
var undef;
/**
* Simple args getter.
*
* @param {*} arg Used if defined.
* @param otherwise Used if arg is not defined.
* @return {*}
*/
var arg = function (arg, otherwise) {
return arg !== undef ? arg : otherwise;
};
/**
* Locks up the main thread as soon as the current thread completes.
*
* @param {number} time
*/
var lock = function (time) {
setTimeout(function () {
var start = +(new Date),
current = 0;
console.log('Locking thread at %d', start);
start += time;
while (start > (current = +(new Date))) {
console.log('tick');
}
console.log('Unlocking thread at %d', current);
}, 0);
};
/**
* Locks up the main thread until a condition is met, releasing it
* momentarily to allow other "threads" to advance.
*
* @param {Function} condition
* @param {number} [checkInterval=50] How long
*/
var lockThreadUntil = global.lockThreadUntil = function (condition, checkInterval, releaseDuration) {
checkInterval = arg(checkInterval, 50);
releaseDuration = arg(releaseDuration, 0);
var id = setInterval(function () {
if (!condition()) {
lock(checkInterval);
} else {
clearInterval(id);
}
}, releaseDuration);
};
define(function () {
return lockThreadUntil;
});
})(this);
ページ上(グローバルを作成するモジュールでテストしました):
(function (global) {
lockThreadUntil(function () {
var isLoaded = !!global.path && !!global.path.toModule;
if (!isLoaded) {
return false;
}
console.log('Is loaded!');
return true;
}, 1000);
})(this);
コンテンツ内スクリプトでは、次のようになります。
console.log('Was needed!');
これにより、スクリプトをロードする時間を与えながら DOM がほとんど進まず、コンテンツ内スクリプトより先に解析スタックに入ることができるようになることを期待していました。残念ながら、コンテンツ内スクリプトが最初に起動しているようです。
要約
私は提案を受け入れます。私が考えているオプションには次のものがあります(どちらもひどいようです):
- 歯を食いしばり、スクリプト タグを使用します。
- RequireJS ロード メソッドを飲み込み、xhr 実装に置き換えます。