Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tailwind v4 @source directive ignores subdirectories with .gitignore #15452

Open
jhh opened this issue Dec 19, 2024 · 5 comments
Open

Tailwind v4 @source directive ignores subdirectories with .gitignore #15452

jhh opened this issue Dec 19, 2024 · 5 comments
Assignees

Comments

@jhh
Copy link

jhh commented Dec 19, 2024

What version of Tailwind CSS are you using?

v4.0.0-beta.8

What build tool (or framework if it abstracts the build tool) are you using?

None, using CLI

What version of Node.js are you using?

v20.18.1

What browser are you using?

N/A

What operating system are you using?

tested on macOS and Linux

Reproduction URL

https://github.com/jhh/tailwind-gitignore

Describe your issue

Adding a .gitignore file to a directory referenced by a @source directive in a Tailwind CSS source file causes the referenced directory to be ignored.

I discovered this because the uv Python packaging tool creates a .gitignore in the .venv directory it uses and I couldn't @source a template directory within it. Manually deleting .venv/.gitigore fixes the issue.

@e-krebs
Copy link

e-krebs commented Dec 28, 2024

this is a documented behavior: https://tailwindcss.com/docs/v4-beta#automatic-source-detection

@jhh
Copy link
Author

jhh commented Dec 28, 2024

I went over that documentation pretty carefully while I was trying to figure out why I wasn't picking up template sources. I think this is still a bug. The docs state that "And if you ever need to explicitly add a source that’s excluded by default, you can always add it with the @source directive...", reinforced by an example @source directive pointing to a directory within node_modules (nearly always .gitignored).

Taken from the repro above, works with one .gitignore:

.
├── .gitignore # ignores ignored/ dir
├── base.css
├── ignored
│   └── template.html # works as documented, @source will pick up classes
├── package-lock.json
├── package.json
├── README.md
└── test.html

Does not work when second gitignore is present in ignored directory:

.
├── .gitignore  # ignores ignored/ dir
├── base.css
├── ignored
│   ├── .gitignore # adding this, ignores *
│   └── template.html # this will not be seen by @source
├── package-lock.json
├── package.json
├── README.md
└── test.html

@e-krebs
Copy link

e-krebs commented Dec 29, 2024

according to the (limited) doc, in neither of those two cases should the template file classesnbe picked up, so that's probably where the bug is.

@RobinMalfait RobinMalfait self-assigned this Jan 6, 2025
@RobinMalfait
Copy link
Member

Hey!

When dealing with gitignored files/folders you have to be very explicit because this can lead to accidental overhead (we had a lot of issues over the years where people accidentally included node_modules which scanned thousands of files).

Let's imagine that you have a plugin in your node_modules, by just adding @source "node_modules"; that would mean that not only your plugin but everything inside node_modules will be scanned.

In your case, the ignored folder is pretty small, so that's not really an issue. However, the only way for us to know whether it's a big or small folder is by actually scanning it.

When using @source, if you point it to a folder, all the same auto source detection rules apply (such as ignoring gitignored files/folders, ignoring binary files and so on).

This means that the moment you add * to the ignored/.gitignore file, the contents is hidden again. This is similar to the node_modules case I mentioned earlier.

The solution here is to be very explicit about the ignored files/folders.

To solve it in your case, you could do this instead:

/* base.css */
@source "ignored/template.html";

This is very explicit and telling Tailwind CSS that it's okay to scan the ignored/template.html file even though it is being ignored.

Does this work for you?

@jhh
Copy link
Author

jhh commented Jan 6, 2025

My repro example was a little contrived and over-simplified. Let me describe what's going on in my actual application and see what you think about its bug-worthiness. It may just be something that could be pointed out in documentation.

I have a base.css that sources a relative path to some third party templates I'm using, thusly:

/* puka/static/puka/base.css */
@source "../../../.venv/lib/python3.12/site-packages/crispy_tailwind";

The @sourced crispy_tailwind folder has 44 files to be scanned for templates:

crispy_tailwind/
.
├── __init__.py
├── layout.py
├── tailwind.py
├── templates
│   └── tailwind
│       ├── display_form.html
│       ├── errors.html
│       ├── errors_formset.html
│       ├── field.html
│       ├── inputs.html
│       ├── layout
│       │   ├── alert.html
│       │   ├── attrs.html
│       │   ├── baseinput.html
│       │   ├── button.html
│       │   ├── buttonholder.html
│       │   ├── checkboxselectmultiple.html
│       │   ├── checkboxselectmultiple_inline.html
│       │   ├── column.html
│       │   ├── div.html
│       │   ├── field_errors.html
│       │   ├── field_errors_block.html
│       │   ├── field_with_buttons.html
│       │   ├── fieldset.html
│       │   ├── formactions.html
│       │   ├── help_text.html
│       │   ├── help_text_and_errors.html
│       │   ├── inline_field.html
│       │   ├── prepended_appended_text.html
│       │   ├── radioselect.html
│       │   ├── radioselect_inline.html
│       │   ├── row.html
│       │   ├── select.html
│       │   └── select_option.html
│       ├── table_inline_formset.html
│       ├── uni_form.html
│       ├── uni_formset.html
│       ├── whole_uni_form.html
│       └── whole_uni_formset.html
└── templatetags
    ├── __init__.py
    ├── tailwind_field.py
    └── tailwind_filters.py

The .venv directory in the path of the @source directive above is created by the uv tool, just like npm creates node_modules. It has over 11k files and is ignored by my project repo.

The problem stems from the fact that uv puts the aforementioned second .gitignore in the root of the .venv directory it creates and hides the template files.

The point you make is a good one, but I'm sourcing template files as explicitly as I can without putting 44 @source directives in my CSS. There's also the confusing fact that I can source when there is a .gitignore 4 or 5 directories above, but not both 4 and 5.

In my case, I deleted the .gitignore that uv created and thankfully it isn't recreating it every time it syncs!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants