Skip to content

Multiple scoped imports via (reference) fail #3813

Open

Description

@dankolz

To reproduce:

.foo {
	@import (reference) "abc";
	.one {
		.two(); // defined in abc.less
	}
}

in another file

.bar {
	@import (reference) "abc";
	.three {
		.two(); // defined in abc.less
	}
}

Current behavior:

The second use of .two() fails with "NameError: .two is undefined in ..."

Expected behavior:

Both references should work.

Environment information:

I don't think the env matters here, but...

  • less version: 3 and 4
  • nodejs version: 18
  • operating system: Ubuntu 20.04

** Additional **

There is a workaround here by using:

	@import (multiple, reference) "abc";

The right behavior seems to me to be that the second reference should work because:

  1. The first reference is scoped, and therefor abc.less is not actually getting included twice, in the sense that duplicate css is being produced.
  2. It's a reference, and doesn't generate duplicate code anyway. Why not make the default 'multiple' to avoid the issue I had?
  3. Treating references in the manner suggested here seems to be the more typical way that compilers treat libraries.

If a change isn't made to the code, it seems like it may be worthwhile to put this info into the documentation somewhere.

Activity

  1. matthew-dean commented on Oct 2, 2023

    @matthew-dean
    Member

    I don't disagree this is somewhat counter-intuitive, but it's consistent with the way that @import is defined. In other words, @import was defined first with a "single-call" kind of pattern, to avoid duplication. Then multiple was added to signal duplication. Then reference was added. (I could have the order of the last two flipped.)

    In the future, this will likely be made more clear with more intuitive behavior with separate at-rules for including qualified rules vs including variables / mixins. See: less/less-meta#39

  2. Lfan-ke commented on Jul 25, 2026

    @Lfan-ke
    Contributor

    Still reproduces on current master. In the meantime there is a workaround: add the multiple keyword so the file is brought into each scope instead of being deduplicated:

    .foo { @import (reference, multiple) "abc"; .one { .two(); } }
    .bar { @import (reference, multiple) "abc"; .three { .two(); } }

    Both .two() calls then resolve.

    The underlying cause looks like the same-file import dedup: the second @import "abc" is treated as already-imported and skipped, so its mixins never land in the second scope. The check is in import-manager.js (the importManager.files[...] guard, unless options.multiple). Whether a (reference) import - which only emits the parts that are actually used - should be exempt from that dedup is really the design question here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions