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

[BUG] TailwindCSS JIT requires a restart every time a new class is inferred #3246

Open
4 tasks done
aaronjensen opened this issue Apr 30, 2021 · 21 comments
Open
4 tasks done

Comments

@aaronjensen
Copy link
Contributor

Bug Report Quick Checklist

  • I am on the latest version of Snowpack & all plugins.
  • I use package manager yarn (Fill in: npm, yarn, pnpm, etc).
  • I run Snowpack on OS Mac (Fill in: Windows, Mac, Linux, etc).
  • I run Snowpack on Node.js v12+

Describe the bug

Tailwind JIT works by scanning your source files for classes and including them in the css that's built. When used with Snowpack and following the documentation, you must restart Snowpack every time you use a new class, which makes JIT near unusable.

This plugin helps: https://github.com/jadex/snowpack-plugin-tailwindcss-jit

To Reproduce

https://github.com/aaronjensen/snowpack-tailwind-jit-repro

@aaronjensen
Copy link
Contributor Author

aaronjensen commented Apr 30, 2021

Also, please see the import branch for a more typical configuration (with the css imported from JS, rather than being imported in the html) as it allows HMR i.e. does not refresh the whole page.

@markdorrill
Copy link
Contributor

markdorrill commented May 3, 2021

Hello @aaronjensen. I just noticed your discussion with @drwpow in #2916 then followed through here. For tailwind users this is a hot topic! I have now spend many hours looking into what is actually going on here. Because Snowpack is such a solid concept I decided to persist, so can contribute here.

I hope this will also help the Snowpack authors to accommodate whatever is needed to make the tailwind developer experience exemplary :)

1. Triggering Snowpack to rebuild the CSS

The reason that you need to restart snowpack to see the tailwind changes is that when you change for example a color in tailwind.config.js, snowpack has no idea that it needs to rebuild global.css. This bit is cover-able with a plugin that would mark global.css as when you edit tailwind.config.js. See markChanged() in the plugin API for more details.

2. The real challenge: cache busting

However this is not where the challenge lies... After some digging it seems that even if you mark global.css as changed in a custom plugin, snowpack is very good at caching and will check to see if global.css file has changed before it triggers the file for rebuild... As you don't edit that file, its just used as an intermediary file by tailwind via the postcss chain, it won't bust the cache until it changes. A highly annoying workaround is to add a CSS comment and every time you want to rebuild tailwind, just add a letter. Not a pleasant experience by any account but does prevent having to restart snowpack.

3. Additional complication: bust cache on mark changed

Something for @drwpow and @FredKSchott to consider (as there may be better ways to accommodate this) is a plugin API to bust the cache for a file or, to improve the behaviour of markChanged() to automatically bust the cache when a file is marked as changed (this is what I expected before investigating further).

*Maybe this could be added as an option to the markChanged() function?

3. Edge complication: tailwind cache when using tailwind plugins

Update / correction: my memory got pickled on point 3. Its not the snowpack cache that is the issue in some cases its tailwinds. The main case when you extract tailwind styles into components using tailwind plugins.

@aaronjensen
Copy link
Contributor Author

Just clarifying one thing here:

The reason that you need to restart snowpack to see the tailwind changes is that when you change for example a color in tailwind.config.js

I am not talking about changing tailwind.config.js. I'm talking about using a color in my code that was not previously used while using TailwindCSS JIT. This should not require a restart at all.

As an aside, we are in the process of migrating to Vite for our projects where this works out of the box, so unless something goes wrong in that migration I probably won't have much time to update this issue, but I do still hope it gets fixed for all the other Snowpack + Tailwind users.

@markdorrill
Copy link
Contributor

@aaronjensen thanks for the clarification. I suspect that your issue is still due to snowpack thinking that global.css is never changed so will never rebuild your tailwind CSS via postcss.

@drwpow
Copy link
Collaborator

drwpow commented May 20, 2021

Thanks again for raising this, and taking the time to write up an issue and a great reproduction. I’m happy to announce that we will fix this in the upcoming v3.5.0 release that’s publishing now. Please note that you’ll need to set a new tailwindConfig option in your Snowpack config to take advantage of this. The reason for that is that blowing the CSS cache away more frequently could have performance implications in other non-Tailwind setups, so we require you to tell us that Tailwind is being used.

Please give it a try and let me know if it fixes your problem!

@francislavoie
Copy link
Contributor

Nice!

Unfortunately I can't try it because I'm still blocked by #3082 (comment) ☹️

@markdorrill
Copy link
Contributor

Excited to see this @drwpow. Will give it a test on v3.5.0 and report back here.

@djsavvy
Copy link

djsavvy commented May 22, 2021

Thanks so much @drwpow!

DOUBLE EDIT: I ended up having to disable the jit for now, @valtism below is correct. A hard refresh is necessary for me.

EDIT: I looked through the diff on #3326 and figured out my mistake. I had forgotten to add @snowpack/plugin-postcss and create a postcss.config.js.

Was anybody else on this issue able to get this to work though? My package.json is showing snowpack at 3.5.1. In my existing snowpack.config.js I added:

  devOptions: {
    tailwindConfig: './tailwind.config.js',
  },

(The tailwind.config.js and snowpack.config.js are in the same folder.)

And in my tailwind.config.js I re-added:

  mode: 'jit',

However, I'm getting the exact same behavior as before (new classes aren't reflected without restarting snowpack).

@valtism
Copy link

valtism commented May 26, 2021

I was not able to get this working, and like before it only seems to update on a snowpack restart. I have followed the instructions on the Tailwind setup guide, so I don't know what is wrong. This is the repo I was trying to get it to work with: https://github.com/valtism/react-snowpack

Edit: Thought it may have been caused because @snowpack/app-template-minimal installed 3.3.7 for some reason instead of latest, but even after updating to 3.5.1 I still get the same issue

@markdorrill
Copy link
Contributor

I've tested 3.5.0 with static html and the standard tailwind utility workflow. Both tailwind standard mode and JIT mode worked without any issue.

@BogdanDarius
Copy link

I've tested 3.5.0 with static html and the standard tailwind utility workflow. Both tailwind standard mode and JIT mode worked without any issue.

The JIT kinda works for me. I still have to refresh the page if console is opened or hard refresh to see the changes.

@valtism
Copy link

valtism commented May 26, 2021

Ah, I see the issue. It is updating the CSS, but does not update until there is a refresh with the cache disabled / hard refresh.

I would like for this to work without refreshing, and ideally with React Fast Refresh.

@djsavvy
Copy link

djsavvy commented May 29, 2021

It turns out I was mistaken earlier (or something changed in my configuration) --- the webpage does not update until I do a hard refresh, like @BogdanDarius mentioned (refreshing with the console open does not work for me on Firefox Developer Edition).

@pReya
Copy link

pReya commented May 29, 2021

Yeah, same here. It still requires a hard refresh for the new classes to load.

@ShivamJoker
Copy link

ShivamJoker commented Jun 14, 2021

Disabling JIT seems to fix the issue. But this shouldn't be happening ?

@nmacdon3
Copy link

I'm experiencing the same issues listed above. Restarting snowpack causes new classes to load, but changing the classes causes them to disappear. Running latest snowpack, tailwind, and postcss.

@francislavoie
Copy link
Contributor

For what it's worth, I ultimately decided to switch to Vite. Snowpack has clearly fallen to the wayside, and Fred himself suggested Snowpack users consider the switch:

https://dev.to/fredkschott/5-things-i-learned-while-building-snowpack-to-20-000-stars-b9d

https://dev.to/fredkschott/5-more-things-i-learned-building-snowpack-to-20-000-stars-5dc9

@ShivamJoker
Copy link

ShivamJoker commented Dec 17, 2021 via email

@francislavoie
Copy link
Contributor

Seems to be. Only 4 commits since the last release in August.

@Xeevis
Copy link

Xeevis commented Dec 19, 2021

For what it's worth, I ultimately decided to switch to Vite. Snowpack has clearly fallen to the wayside, and Fred himself suggested Snowpack users consider the switch:

https://dev.to/fredkschott/5-things-i-learned-while-building-snowpack-to-20-000-stars-b9d

https://dev.to/fredkschott/5-more-things-i-learned-building-snowpack-to-20-000-stars-5dc9

Oh noes, that makes me quite frustrated 😞. I've looked at Vite.js and don't see how would I replace Snowpack with it. All I need is fast unbundled frontend build tool with watch. I work with Blazor and thus compile and run server with .NET runtime from DLLs. Which means I just need it to transform static files, basically throw couple .pcss and .ts files at it and expect .css & .js ESM modules with imports resolved which I load at runtime as needed.

Vite requires index.html and manual import of every resource, which I don't have nor want to maintain just for the sake of it and what is worse vite build --watch will funnel everything through rollup bundler with no way to opt out. With ESM and HTTP/3 why is that even a thing? Snowpack is by default unbundled and you can choose to use whatever bundler at the end which is in my opinion much better approach and it's what separates snowpack from all others.

@Tarang74
Copy link

Tarang74 commented Jan 7, 2022

I've tested 3.5.0 with static html and the standard tailwind utility workflow. Both tailwind standard mode and JIT mode worked without any issue.

Would you mind commenting on how you achieved this? And does this still work on the latest version (3.8.8)?

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