次のような変数によってロードする変数ファイルを決定するindex.lessファイルがあります。
@theme-variant: "a-theme.less";
<strong i="6">@import</strong> "./@{theme-variant}";
そのインデックスファイルにロードするファイルが少なくなっています。
<strong i="10">@import</strong> "~theme-variant-variables";
webpack.config.js
ファイルで変数の値を設定しています。
lessOptions.modifyVars = {
"theme-variant": `"${v}-theme.less"`
}
index.lessファイルの内容を直接インポートされたlessファイルに移動すると、すべてが期待どおりに機能します。悲しいことに、これらの2行のlessを一元化しようとすると、webpack構成ロジックに基づいて選択した変数ファイルを切り替えることができます。直接インポートされたファイルより少ないファイルがそれ自体をインポートすると、動作を停止します。 予想される構成ではローダー呼び出しが少なくなるので、コンパイラーが少ないと、インポートされたファイル数が少ないために変数/オプションが伝達されないと思います。 それは期待されていますか?
これは#2772と同じことだと思います-そこでの議論の途中を参照してください(たとえば、 modifyVars
は変数を定義する効果がありますが、対象のインポートステートメントがすでに評価された後に発生します)。 ただし、 https: //github.com/less/less.js/issues/1400#issuecomment-137128461も参照してください。
要するに、重要なのは、インポートステートメント内の変数補間は便利なことですが、遅延評価の原則と直接矛盾します。 したがって、複雑な構造化に関しては、そのような種類のカスタマイズを実現する他の方法を見つける方がよいでしょう(たとえば、テーマファイルごとに異なるdirを使用し、対応するpaths
オプションを設定して切り替える)。
返信いただきありがとうございます。 変数は、JSによって直接インポートされるlessファイルで更新されます。変数が更新されていない他のlessファイルによってインポートされるファイルだけです。 どちらの場合も遅延評価は確実に発生していますか? インポートされていないファイルにmodifyvarlogic/configが適用/渡されていないようです。 それとも私は何かが足りないのですか?
変数は、JSによって直接インポートされるlessファイルで更新されます。変数が更新されていない他のlessファイルによってインポートされるファイルだけです。
まあ、それよりもトリッキーです。 遅延評価が機能するためには、コンパイラはさまざまな言語エンティティを(同じスコープ内で)コードに表示される順序ではなく、上位レベルから下位レベルへとタイプ別に評価する必要があることに注意してください。つまり、(大まかに)次のようになります。imports-> mixins- >変数。
<strong i="9">@import</strong> "@{var}";
がある場合、コンパイラはインポート(および後続のすべてのインポート)の前に指定された変数を評価するように強制されます-これが全体を台無しにします(一般に、そのような悪用の結果は単に未定義です-それある場合(ほとんどの場合非常に単純)に機能し、他の場合には機能しません)。
直接競合する2つの機能が組み合わされた場合、コンパイラが一貫した動作を保証する方法はありません。
つまり、 modifyVars
が後続のインポートで「変数を更新」しないわけではありませんが、更新された変数値自体が外部レベルのインポートに影響を与えることはありません(これらのインポートはすでに「完了」しているため)。
そして、ドキュメントが言ったとしても:
v2.0.0より前では、ルートスコープまたは現在のスコープで宣言されている変数のみが考慮され、変数を検索するときに現在のファイルと呼び出し元ファイルのみが考慮されていたことに注意してください。
...v2以降はそれほど良くはありません。 より多くの組み合わせ/ユースケースを改善/恨み修正しましたが、すべてを修正することはできません。 詳細については、#1108、具体的には#2246を参照してください。
インポートされていないファイルにmodifyvarlogic/configが適用/渡されていないようです。
いいえ(最終的にファイルが1つの大きな文字列としてまとめて評価されるため)。 問題が他の場所にない限り、確認するには以下を追加します。
foo {bar: @theme-variant}
関心のあるファイルに移動し、結果を確認します。
ところで。 ユースケース(「*-theme.less」が特定のテーマの変数/ミックスインのみに関する場合)の場合、次のように試すことができます。
<strong i="7">@import</strong> "a-theme.less";
をそのままにして(つまり、補間なしで)明示するか、完全に削除します。modifyVars
を使用して、インポートステートメント自体を設定します(例: <strong i="11">@import</strong> "custom-theme.less";
を直接)。modifyVars
は変数bla-bla-blaについてのみのふりをしますが、実際には、ルートファイルの最後に任意のテキストを追加するだけであることに注意してください。 つまり、 lessc
の場合は、実際に--modify-vars="whatever-less-code foo {bar: baz;}"
だけです。 webpackのless-loaderが通過できる形式はわかりませんが、うーん... lessOptions.modifyVars = "an arbitrary code";
多分?
これは明らかにハックですが、実際にはかなり予測可能なハックです(最初のコンボのように言語自体ではなく、 modifyVars
形式のみを悪用するため)。
返信とアイデアをありがとうございました@seven-phases-max今週中にさらに調査し、この問題を週の後半に更新/クローズするようにリマインダーを設定しました。 再度、感謝します。
実際に何らかの方法で修正できる問題というよりは、予想される(この場合は「未定義/未指定」として定義されている)動作に似ているため、これを閉じます。
改善のアイデア、特にPRはいつでも歓迎しますが、近い将来、誰もこれに参加することはないと思います。