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

[HMR] TailwindCSS do not compile new CSS when files with HMR changed #15460

Open
7 tasks done
KermanX opened this issue Dec 29, 2023 · 14 comments
Open
7 tasks done

[HMR] TailwindCSS do not compile new CSS when files with HMR changed #15460

KermanX opened this issue Dec 29, 2023 · 14 comments
Labels
feat: css feat: hmr feat: html p3-minor-bug An edge case that only affects very specific usage (priority)

Comments

@KermanX
Copy link

KermanX commented Dec 29, 2023

Describe the bug

TailwindCSS does not compile new CSS when a file is modified and handled by HMR (e.g. a Vue SFC) in dev mode.

The class name of the element is updated by the Vue plugin via HMR, but Tailwind doesn't create a new rule for the new class name. So the new class name becomes useless.

There is a similar issue, which is about pug: #4588

And there is also a relative test (pug only): https://github.com/vitejs/vite-plugin-vue/blob/main/playground/tailwind/__tests__/tailwind.spec.ts.

I think it is an issue of Vite, not plugin-vue. Because this also happens to my web framework and its plugin (with HMR).

Reproduction

https://stackblitz.com/edit/vitejs-vite-8djtq2?file=src%2FApp.vue

Steps to reproduce

  1. install and dev
  2. The text "test" in the preview panel is blue
  3. modify App.vue: text-blue-400text-red-400
  4. The text "test" becomes black, instead of red, which means the .text-red-400 rule is not generated.

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.18.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 9.4.2 - /usr/local/bin/npm
    pnpm: 8.10.5 - /usr/local/bin/pnpm
  npmPackages:
    @vitejs/plugin-vue: ^4.5.2 => 4.6.0 
    vite: ^4.5.1 => 4.5.1

Used Package Manager

npm

Logs

Click to expand!
  VITE v4.5.1  ready in 2604 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h to show help
17:27:07 [vite] hmr update /src/App.vue

Validations

Copy link

stackblitz bot commented Dec 29, 2023

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

@KermanX
Copy link
Author

KermanX commented Dec 29, 2023

I think maybe quite a few people (who use Vite+Vue+TailwindCSS) have encountered this but I couldn't find an issue about it. 😢

@KermanX KermanX changed the title [HMR] TailwindCSS do not compile new CSS when Vue file changed [HMR] TailwindCSS do not compile new CSS when files with HMR changed Dec 29, 2023
@agm1984
Copy link

agm1984 commented Dec 29, 2023

I'm having an issue with Tailwind also. I can't upgrade past Vite 4.5.1 because hot module reload causes the page to full reload every time I change CSS classes.

I tried to isolate the problem by creating a new repo, but it works as expected. I also copied half my project into the new repo and it still worked properly. I also tried a strange idea of copying the affected repo to another folder and running it. That one exhibits the problem also.

I see this in the terminal every time I change CSS class and see full page reload:

10:37:23 AM [vite] page reload src/pages/profile/Profile.vue (circular imports) (x2)

Currently frustrated because it works fine with v4.5.1 but i can't upgrade vite past that. I've spent a lot of time messing with packages but I can't get it working in this project.

  "dependencies": {
    "@unhead/vue": "^1.8.9",
    "@vuelidate/core": "^2.0.3",
    "@vuelidate/validators": "^2.0.4",
    "axios": "^1.6.2",
    "chart.js": "^4.4.1",
    "date-fns": "^2.30.0",
    "fuse.js": "^7.0.0",
    "lodash.clonedeep": "^4.5.0",
    "lodash.debounce": "^4.0.8",
    "maska": "^2.1.10",
    "path": "^0.12.7",
    "pinia": "^2.1.7",
    "primeicons": "^6.0.1",
    "primevue": "^3.45.0",
    "sortablejs": "^1.15.1",
    "sortablejs-vue3": "^1.2.11",
    "vite-plugin-pwa": "^0.17.4",
    "vue": "^3.3.11",
    "vue-router": "^4.2.5",
    "vue-toastification": "^2.0.0-rc.5",
    "vue3-draggable": "^2.0.9",
    "vue3-popper": "^1.5.0"
  },
  "devDependencies": {
    "@pinia/testing": "^0.1.3",
    "@vitejs/plugin-vue": "^4.6.1",
    "@vitest/coverage-v8": "^1.0.2",
    "@vue/test-utils": "^2.4.3",
    "autoprefixer": "^10.4.16",
    "c8": "^8.0.1",
    "eslint": "^8.55.0",
    "eslint-config-prettier": "^8.10.0",
    "eslint-plugin-vue": "^9.19.2",
    "jsdom": "^23.0.1",
    "postcss": "^8.4.32",
    "prettier": "^2.8.8",
    "tailwindcss": "^3.4.0",
    "unplugin-vue-components": "^0.26.0",
    "vite": "^5.0.10",
    "vite-plugin-eslint": "^1.8.1",
    "vitest": "^1.0.2"
  }

@KermanX
Copy link
Author

KermanX commented Dec 30, 2023

@agm1984 I think maybe #15221 is more relative to your issue, rather than this one.

Also try this?

npm run dev --debug hmr

@KermanX
Copy link
Author

KermanX commented Dec 30, 2023

I debugged and found these:

When a Vue file is modified, because it is self-accepting, and it has /index.html?html-proxy&direct&index=0.css as its importer, which is a CSS request, the following lines are executed.

https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/hmr.ts#L288-L293

However, it does nothing effective because propagateUpdate returns at https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/hmr.ts#L312, and the return value is ignored.

@agm1984
Copy link

agm1984 commented Jan 2, 2024

Hmm, I did npm run dev --debug hmr and it says

(!) Could not auto-determine entry point from rollupOptions or html files and there are no explicit optimizeDeps.include patterns. Skipping dependency pre-bundling.

And the app is not running properly. I can't access it. My vite config is on port 3000 but the one that loads is on port 5173 and it doesn't work on that port, probably because it skipped dependency pre-bundling.

@KermanX
Copy link
Author

KermanX commented Jan 3, 2024

@agm1984 I'm sorry. The command I provided is wrong. It should be pnpm run dev --debug hmr or npm run dev -- --debug hmr.

And I think maybe you're having a different problem than this issue. It might be better to create a new issue with minimal reproduction.

@bluwy
Copy link
Member

bluwy commented Jan 3, 2024

@agm1984 That's a different issue and perhaps you're interested in #15118 instead.

@KermanX If I move the @tailwind code into it's own CSS file and import through a JS file, it works. From what I can tell, your current setup doesn't work because the <style> tag is plainly transpiled to CSS, and there's no JS code that handles what to do when HMR should apply. That is unless Vite injects one, but the current expected behaviour for now is to force a full reload.

As to why a full reload didn't happen, I'm not really sure but it could be related to #15229, where we explicitly didn't want a full reload to happen for tailwind for circular imports. I suppose we always expected Tailwind code to exist in their own CSS file for better HMR anyways.

@KermanX
Copy link
Author

KermanX commented Jan 3, 2024

From what I can tell, your current setup doesn't work because the <style> tag is plainly transpiled to CSS, and there's no JS code that handles what to do when HMR should apply.

I think it is reasonable to make HMR work with <style> tag in index.html. Because when using TailwindCSS, there likely are no more or very few CSS rules than the three @tailwind directives, so a styles.css seems to be spare. Also, it is more consistent in design.


As to why a full reload didn't happen, I'm not really sure but it could be related to #15229, where we explicitly didn't want a full reload to happen for tailwind for circular imports.

I think if HMR is intended to not work with <style> tag in index.html, maybe the return value I’ve mentioned in #15460 (comment) should not be ignored, in order to trigger a full reload. But I am not sure.

@Danones
Copy link

Danones commented Jan 5, 2024

Hey 👋

I have just created the #15516 issue when afterwards I noticed yours @KermanX

I am using Remix + Vite + Tailwind as tech stack and noticed that in my case, the CSS class actually reaches the browser css file but nothing is applied. Which in your case it seems like the class isnt created at all.

@KermanX
Copy link
Author

KermanX commented Jan 6, 2024

@Danones I think the two issues are different.

My issue is that Vite doesn't trigger a TailwindCSS re-run when putting the @tailwind directives inside index.html.

In your issue, TailwindCSS re-runs after the file is changed (because you run the TailwindCSS compiler in a new process in watch mode), which I think may be a problem with how Vite (or maybe Remix plugin) handles modified CSS.

@bluwy
Copy link
Member

bluwy commented Jan 8, 2024

I think if HMR is intended to not work with <style> tag in index.html, maybe the return value I’ve mentioned in #15460 (comment) should not be ignored, in order to trigger a full reload. But I am not sure.

I don't think that return value will fix the issue you're seeing, but it does look strange that the value is ignored. Seems like it's being called to only mutate boundaries.

For a fix, we could:

  1. Special case CSS that are directly referenced from HTML files to force a full reload. I can reproduce the no-HMR issue if I use @import and updating the imported file too.
  2. Re-work CSS handling in HTML files so they have HMR. That likely means refactoring this code, which is a little complex.

@bluwy bluwy added feat: css feat: hmr feat: html p3-minor-bug An edge case that only affects very specific usage (priority) and removed pending triage labels Jan 8, 2024
@Danones
Copy link

Danones commented Jan 8, 2024

@Danones I think the two issues are different.

My issue is that Vite doesn't trigger a TailwindCSS re-run when putting the @tailwind directives inside index.html.

In your issue, TailwindCSS re-runs after the file is changed (because you run the TailwindCSS compiler in a new process in watch mode), which I think may be a problem with how Vite (or maybe Remix plugin) handles modified CSS.

You are right @KermanX and I was aware of that. Just wanted to leave a comment to make aware of a similar issue.

I have found what was causing my issue but I am afraid the solution isn't optimal.
Seems to be related with hydration issues, if you have any extensions on your browser, those issues seem to break the styles. Updating to

"react": "^18.3.0-next-fccf3a9fb-20230213",
"react-dom": "^18.3.0-next-fccf3a9fb-20230213"

seems to fix the issue for now but because I am using this on my company project I will have to wait for this to be more stable in order to move forward

@agm1984
Copy link

agm1984 commented Jan 19, 2024

Sorry for a bump but I just noticed this in the release notes:

feat(hmr): reload for circular imports only if error (#15118) (6ace32b), closes #15118

This might fix my issue that I described up in this thread. I will try V5 again as soon as 5.1 gets out of beta.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat: css feat: hmr feat: html p3-minor-bug An edge case that only affects very specific usage (priority)
Projects
None yet
Development

No branches or pull requests

4 participants