less / less.js

Less. The dynamic stylesheet language.
http://lesscss.org
Apache License 2.0
17.03k stars 3.41k forks source link

Inconsistent results of multiple imports with `(reference)`. #3374

Open dmantsevich opened 5 years ago

dmantsevich commented 5 years ago

Variables in @import statement cause for unexpected result.

I prepared demo app. https://github.com/mantsevich/less-variables-import-issue-demo

1) download 2) npm i 3) npm start 4) compare "correct.css" & "issue.css" files.

What do we have:

Difference in the source code: entry-issue.less uses variable in @import statement. Difference in the result: issue.css doesn't include hello-galaxy component at all.

Expected result: Result of CSS files should be identical.

I think problem related @import with variable in the path + @import (reference) in the child less files. If remove (reference) flag from hello-world.less file, then result will be "the same".

seven-phases-max commented 5 years ago

At quick glance I suspect it's about the "once import rule" and the order of imports: Since hello-world.less already imports hello-galaxy.less, the second hello-galaxy.less import (the one in entry.less) is ignored. Thus different result with and without (reference) of the only applied import is expected. In other words, it seems to be the same issue as #3040 (i.e. current behavior is expected, but there's room for a feature request if someone is interested to design/implement that).

dmantsevich commented 5 years ago

I locally remove extra "/" - result the same.


I think it's different issue. Why does code work if I don't use variable in the path?

Working:

@import "./components/hello-world/hello-world.less";
@import "./components/hello-galaxy/hello-galaxy.less";

With issue:

@import "./@{path-to-components}/hello-world/hello-world.less";
@import "./@{path-to-components}/hello-galaxy/hello-galaxy.less";

Result: Correct entry - exports hello-galaxy, but issued (with variables in the path) - don't.

seven-phases-max commented 5 years ago

I tested this in both Less 3.9.0 and 2.7.3 and the issue that inconsistency being wider than just "variable-in-import-vs-reference".


Here's a few minimalistic examples to illustrate the inconsistency: whatever.less:

whatever {whatever: whatever}

indirect.less:

@import "whatever.less";

indirect-ref.less:

@import (reference) "whatever.less";

main-1:

@import (reference) "whatever.less";
@import "whatever.less";    // not imported

/* something */

main-2:

@import "indirect-ref.less";
@import "whatever.less";    // imported

/* something */

main-3:

@w: w;
@import "indirect-ref.less";
@import "@{w}hatever.less"; // not imported

/* something */

main-4:

@import "indirect-ref.less";
@import "indirect.less";    // not imported

/* something */

Labeling as a bug since regardless of what result we expect, what is important is that we expect the same output from all these main files (there're obviously other (in)direct-import/reference-vs-ones/var-interp combinations to imagine to suffer from this).


I guess this is related to https://github.com/less/less.js/pull/2729 (i.e. most likely a main-2-like code triggers some importing-chain patterns introduced there), thus it's basically a continuation of the issues mentioned in the PR. Though I was not able to test Less 2.5.3 (the version before the #2729 patch) to make sure, as it no longer works with recent Node.js versions.


@mantsevich Still notice that technically it's entry-correct.less producing "wrong" result if compared to other snippets (despite it making more logical sense for your use-case). And the variable in the import only triggers the "proper" ("currently expected" per #3040) behavior I described in my previous post.