tailwindcss: Circular dependencies when using `@apply` cause infinite loops/hanging

Describe the problem:

After upgrading to Tailwind v2, my webpack build started hanging during the building phase

28% building 1/3 entries 22/27 dependencies 5/14 modules

It seems to be that a compound selector is causing an infinite loop and is not triggering RangeError: Maximum call stack size exceeded. Also not triggering Tailwind’s circular dependency detection.

.my-border { @apply border-2; }
/* Remove the following line to see Tailwind report a "circular dependency". Leave it to see build hang.
*/
.foo { @apply my-border; }
.bar.input-border { @apply my-border; }

Secondary issue

Why is this a circular dependency? https://play.tailwindcss.com/lS1DnjwS6g?file=css

Link to a minimal reproduction:

https://play.tailwindcss.com/UO2eaaZ0AD?file=css

tailwind.zip

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 3
  • Comments: 17 (4 by maintainers)

Most upvoted comments

In regards to the last example, I don’t think it’s intuitive behavior that @apply foo would pick up styles from .bar.foo.

I don’t think it’s intuitive behavior that @apply foo would pick up styles from .bar.foo.

You say that now but if you had this HTML:

<div class="group">
  <div class="group-hover:bg-black text-red-500 font-medium">...</div>
</div>

…you’d expect this refactoring to work right?

<style>
  .custom-class {
    @apply group-hover:bg-black text-red-500 font-medium
  }
</style>

<div class="group">
  <div class="custom-class">...</div>
</div>

The only way for that to work is for @apply to consider every use of a class name in the stylesheet. The guiding principal for what the correct behavior of @apply should be is “if you extract a list of classes from your HTML into a custom class using @apply, your code should work the same way it did before”.

I have a use case for this, where I don’t want @apply to pickup styles from every css class

I am using element UI as my framework for frontend. Now I would want to apply w-full to say upload element but it won’t work because the width is set to some child div tag. Now to solve this I am doing this

.w-full {
  .el-upload {
    @apply w-full;

    .el-upload-dragger {
      @apply w-full ;
    }
  }
}

Now I can use a different out class, but the reason I want it to be called w-full is to keep my class names similar to tailwindcss.

The possible solution would be

.w-full {
  .el-upload {
    width: 100%;

    .el-upload-dragger {
      width: 100%;
    }
  }
}

But again w-full is simple behaviour. It would be a prob if I want to apply color or margins etc