Less.js: 同期および非同期インポートをトリガーする方法

作成日 2014年12月07日  ·  26コメント  ·  ソース: less/less.js

現在のfileManager loadFileまたはloadFileSyncを呼び出すことをどのように決定しますか? このコードによると、 isSyncパラメータを設定する必要があります。 ただし、 getFileManager呼び出しを短く検索すると、このオプションはlib/less/functions/data-uri.jsのみ使用されていることがわかります。

render()呼び出すときに、このオプションを明示的に設定することはできますか?

feature request medium priority stale

最も参考になるコメント

renderSyncもうありますか? そうでない場合、同期render回避策はありますか?

編集:Nvm。 これに遭遇する将来の人のために、これは私がしたことです:

less.renderSync = function (input, options) {
    if (!options || typeof options != "object") options = {};
    options.sync = true;
    var css;
    this.render(input, options, function (err, result) {
        if (err) throw err;
        css = result.css;
    });
    return css;
};

全てのコメント26件

isSyncは、レンダリングするオプションオブジェクトに渡すことができます。 data-uriは常に
関数を非同期にすることはできないため、同期します。

しかし、 importManagergetFileManagerオプションを渡しません...

ここで行われます

https://github.com/less/less.js/blob/32dbbee247f76af00eb7577053eccad2ee5f6110/lib/less-browser/file-manager.js#L61

そのオプションは少ないコアによって無視され、ブラウザにのみ固有であるためです。 そのため、ブラウザは常に非同期と呼ばれ、オプションによっては同期または非同期メカニズムを使用してファイルを取得する場合があります。

それがどのように混乱しているのかがわかります。 問題が発生していますか?

すぐにわかることの1つは、ページの読み込み時にオプションの影響を受けるため、後で設定したり、オプションとして渡したりすると無視されるということです。

まあ、おそらく私は私のユースケースを説明する必要があります:

webpack用のless-loader作成しました。 webpackには独自の解決メカニズムがあるため、プラグインを使用して、ファイルマネージャーを介してより少ないファイル解決にフックします。

Webpackは同期ローダーと非同期ローダーをサポートしていますが、すべてのファイルを同期または非同期にレンダリングするように指示する方法が見つかりませんでした。 現在、常にloadFile呼び出します。 したがって、同期コンパイルが要求されたときに、ダーティハックを使用してloadFileSyncを呼び出しました。 幸いなことに、コールバックが同期的に呼び出された場合、同期的に機能することは少なくなります(もちろん、通常の状況では実行しないでください)。

分かりました...

非同期オプションをより少ないコンテキストに移動し、それを使用して、提案どおりにどの呼び出しを行うかを決定する必要があると思います。 ブラウザのファイルマネージャにいくつかの変更が必要な場合がありますが、それは良いリファクタリングになると思います。

いいね!

1つだけ問題があります: callbackを受け入れている間に同期的に何かを行うことは非常に珍しいことです( render関数が行うように)。 次のようなsyncオプションを提案しています。

less.render(
    input,
    { ... sync: true ... },
    function (err, result) {
    }
);

コールバックが同期的に呼び出されるのはおかしいです。 私はこのようなAPIを期待しています:

// async
less.render(input, option, callback);

// sync
var result = less.renderSync(input, option);

はい、あなたは正しいです、それはより良いです。

+1
これは、コールバックのみでコードの実行を制限しないようにrenderSync実装を検討することも非常に役立つようです。 コールバックスコープでは、 console.errthrow new Error()などの多くのメソッドや意図的なJavaScriptエラーはコンソールに何も出力せず、コードの実行を停止するだけで、追跡できないバグが発生する可能性があります。 私はこの振る舞いが起こらないはずだと思います。

私の特定のケースでは、 renderSyncはコマンドラインユーティリティで使用され、promiseを使用してコールバックフローを制御してすべての出力とエラーが毎回順番に出力されるようにするのではなく、renderSyncを使用します。それについて心配する。

(問題自体を侮辱するのではなく、それが実際よりもさらに奇妙にならないようにするためです):

コールバックが同期的に呼び出されるのはおかしいです。

これは誇張です...コードのこの行では、構成が非同期に設定されているとは想定していませんね。
コールバックは単なるコールバックであり、それ自体は同期/非同期のものとは何の関係もありません。

わかりました。 callbackウィンク:という用語について話す必要があり

forEachcallback渡される関数を呼び出すものもあります( MDNなど)。 私にとってコールバックはタスクが終了したときに呼び出されるものなので、私はそれをそうは呼びません。

また、コールバックがノードのエラー規則に従い、最初の引数がnullまたはエラーである場合は、非同期で呼び出す正当な理由があります。

forEach渡された関数を呼び出してコールバックするものもあります `

誰かがnodeを使いすぎています;)誰もがこれを「コールバック」と名付けています。 したがって、「タスクが終了したときに呼び出されるコールバック関数」に関するものであれば、それは「非同期コールバック」にほかなりません。

しかし、気にしないでください、申し訳ありませんが、私はCOのように聞こえて、この純粋に言語的な議論を始めるつもりはありませんでした(同じ言語を話し、ドキュメントが実際にless.renderが同期していることを確認したかっただけです)。

PS詳細を明確にするために:

@kwketh

このless.renderフォームは何年も前から存在していました。何もないところから取り出して変更するだけでは、無数のスニペットを壊すことができません。

@ seven-phases-max

あなたの答えに感謝します、それらはすべて役に立ちます。 コールバックに関するすべての点に同意します。 私は.renderコードを非常に簡単に調べましたが、あなたは正しいです、それが書かれている形式、それはすべてコールバックを中心に展開しており、 renderSyncを持つのは簡単でも合理的でもないようです。

私の問題はどういうわけか異なりますが、関連しています(https://github.com/less/less.js/issues/2546)。 renderSync機能を実装すると問題は解決しますが、最終的な解決策にはなりません。

ざっと見てもいいですか。 本当にありがたいです。

ありがとう。

誰かがノードを使いすぎています

まあ、それは本当です:grin:

ただし、ノードのコールバック規則は十分に確立されています。 この場合、コールバックは常に非同期で呼び出されると思います。

さらに:エラーが発生した場合、エラーはどのように処理されますか? (ほとんどの同期APIのように)スローされますか、それともコールバックへの引数として渡されますか?

現在のAPIがあいまいなだけです(少なくとも私見)

renderSyncもうありますか? そうでない場合、同期render回避策はありますか?

編集:Nvm。 これに遭遇する将来の人のために、これは私がしたことです:

less.renderSync = function (input, options) {
    if (!options || typeof options != "object") options = {};
    options.sync = true;
    var css;
    this.render(input, options, function (err, result) {
        if (err) throw err;
        css = result.css;
    });
    return css;
};

この機能は実際に実装されていますか? ドキュメントはありますか? asyncオプションしか見つかりません。

実際にサポートされている場合はIdkですが、現在私が行ったことはうまくいくことを知っているので、肩をすくめる

@Aarilightどうもありがとうございました、あなたのコードは大いに役立ちました

この同期コールバックの動作は、実際には直感に反します:confused:

@Aarilightそれは私には機能しません=(
私は試した

less.render(css, {sync : true}, (e, result) =>{
        if(e) {
         console.error(e)
    }

        output = result;
        return result
    });

記録されたhttps://github.com/less/less.js/blob/master/lib/less/render.js

            console.log('1')
            this.parse(input, options, function(err, root, imports, options) {
                console.log('2')
                if (err) { return callback(err); }

                var result;
                console.log('3')
                try {
                    console.log('4')
                    var parseTree = new ParseTree(root, imports);
                    console.log('5')
                    result = parseTree.toCSS(options);
                }
                catch (err) { 
                    console.log('6')
                    return callback(err); 
                }

                console.log('7')
                callback(null, result);
            });
            console.log('8')

そして、いくつかのファイルについては、1、8、次に2、3、4、5、6、7が表示されます

-1を使用して、レンダリングをrenderrenderSyncに分割します。 厄介なのはNode.jsの規則です。 また、同期オプションをgrunt / gulp / accordに送信したり、JSオブジェクトを指定された関数に渡すlessに統合された他のワークフローを送信したりすることはできません。 IMO非同期オプションを使用する場合は、オプションのコールバックを渡すことは問題ありません。

別のオプション:ライブラリが実行し始めるのを見たのは、どちらの場合でも実際に約束を返すことです。 次に、sync / asyncの間で変更されるのは、promiseが実行されたときだけですが、結果を処理するコードはまったく同じです。

そしてところで:

{sync: true}

そのようなオプションはありません

-1は、renderをrenderとrenderSyncに分割します。 厄介なのはNode.jsの規則です。

それは完全に主観的な視点ではありませんか? 非同期と同期を1つの関数に組み合わせたIMHOは、(いくつかの例外を除いて)ひどいアンチパターンです。 条件付きステートメントが散らかっていて、保守が難しく、1つのことをうまく実行する明確に定義され、文書化された関数よりもユーザーを混乱させるコードを作成します。 ちょうど私の2c

それは完全に主観的な視点ではありませんか?

はい。

とにかく、私の他の点は主観的ではありません。 つまり、Lessは、関数が分割された場合に更新が必要になる可能性のあるビルドプロセスで使用されます。 たとえば、現在1つのプロジェクトで使用しているAccord(https://github.com/jenius/accord)は、さまざまなコンパイラを1つのAPIに抽象化し、通常、エンジンが必要とする関数にオブジェクトを渡します。 したがって、開発者が指定するLessオプションに基づいて使用する関数を切り替えることはおそらく大したことではありませんが、影響するライブラリの数はわかりません。 知っておくべきことです。

今のところ、オプションにsyncImport: trueを追加すると、これが修正されました。

(ドキュメントにはありません...ソースコードで偶然見つけたのは幸運でした)

この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。

このページは役に立ちましたか?
0 / 5 - 0 評価