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

Vite + router + tailwind JIT -> full page reload #4150

Closed
6 tasks done
jods4 opened this issue Jul 6, 2021 · 22 comments
Closed
6 tasks done

Vite + router + tailwind JIT -> full page reload #4150

jods4 opened this issue Jul 6, 2021 · 22 comments

Comments

@jods4
Copy link

@jods4 jods4 commented Jul 6, 2021

Describe the bug

Follow up of #4147 , when editing Vue templates, I get full page reload instead of HMR.

Reproduction

https://github.com/jods4/bug-vite-tailwind/

Go into HelloWorld.vue, change the class bg-yellow-400 into bg-green-400.

Notice on the terminal or in the browser that vite triggered a full page reload. I'd expect HMR here.

I first tried without Vue router and it worked, so I'm not sure where the problem lies exactly.

System Info

System:
    OS: Windows 10 10.0.18363
    CPU: (12) x64 Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz
    Memory: 5.05 GB / 15.79 GB
  Binaries:
    Node: 15.5.1 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.10 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 7.3.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.18362.1593.0)
    Internet Explorer: 11.0.18362.1
  npmPackages:
    @vitejs/plugin-vue: ^1.2.2 => 1.2.4
    vite: ^2.3.3 => 2.4.1

Used Package Manager

npm

Logs

No response

Validations

@jods4
Copy link
Author

@jods4 jods4 commented Jul 6, 2021

I'm sorry, I have no idea what happened! The code that was pushed is not the right one at all...

Please take a look here:
https://github.com/jods4/bug-vite-tailwind/

@yassinebridi
Copy link

@yassinebridi yassinebridi commented Jul 6, 2021

I have the same issue with React and tailwind JIT, while using @vitejs/plugin-react-refresh the 1.3.5 version

@luukdv
Copy link
Contributor

@luukdv luukdv commented Jul 7, 2021

Seeing this issue without vue-router as well (vite@2.4.1 + tailwindcss@2.2.4 in JIT mode).

@cossssmin
Copy link

@cossssmin cossssmin commented Jul 7, 2021

Similar issue here, using vite@2.4.1, vite-plugin-vue2@1.7.2, vue-router@3.5.2, tailwindcss@2.2.4.

When saving a component, in almost all cases the CSS will not be updated. HTML is being updated with HMR, but CSS is not. Weirdly, in very few cases, CSS will be properly updated but I can't see a pattern that would explain why.

I have to go save tailwind.config.js in order for CSS to be updated, but this triggers a full page refresh, which is difficult to work with when your component is a modal that disappears.

@OneNail
Copy link
Collaborator

@OneNail OneNail commented Jul 7, 2021

In this repo https://github.com/jods4/bug-vite-tailwind/, vite's version is 2.3.3. It works fine as change version to 2.4.1. I changed the HelloWorld.vue file, hmr works, not reload.

@OneNail
Copy link
Collaborator

@OneNail OneNail commented Jul 7, 2021

@patak-js Excuse me, can this bug be reproduced on your side?

@patak-js
Copy link
Member

@patak-js patak-js commented Jul 7, 2021

There should be an issue with the reproduction provided by @jods4, as it is using 2.3.3 as you said. @jods4 could you check your repro?
@cossssmin @luukdv @yassinebridi could you provide a minimal reproduction so it is easier to check the issue? Maybe they are not the same. Thanks!

@jods4
Copy link
Author

@jods4 jods4 commented Jul 7, 2021

@OneNail I double-checked, and as can be shown in System info, npm restored vite 2.4.1 on my machine as it satisfies ^2.3.3.
I am seeing full page reloads with this repro.

Check this, you can see Vite version (2.4.1) and the full page reloads instead of HMR:
cB2s9IWnWF

@anncwb
Copy link
Collaborator

@anncwb anncwb commented Jul 7, 2021

The same problem, not yet found the cause

@OneNail OneNail mentioned this issue Jul 9, 2021
6 tasks
@nmabhinandan
Copy link

@nmabhinandan nmabhinandan commented Jul 12, 2021

Using Vite + Tailwind JIT + React. Same problem

@OneNail
Copy link
Collaborator

@OneNail OneNail commented Jul 12, 2021

Using Vite + Tailwind JIT + React. Same problem

Could you provide a mini repo to check the problem? Thanks

@paraboul
Copy link
Contributor

@paraboul paraboul commented Jul 12, 2021

Same issue starting 2.4.1

Here is a very simple test case : https://github.com/paraboul/vue-hmr-reload
Updating "Page.vue" triggers a full reload.

Removing tailwind (along with the postcss config and stuff in index.css) makes hmr work again

@paraboul
Copy link
Contributor

@paraboul paraboul commented Jul 12, 2021

I tried to revert 09c6c94 locally, hmr triggers on index.css without page reload when updating Page.vue, but the component itself doesn't update.

Edit:

HMR is broken with tailwindcss (jit mode) since 2.3.7 (component simply won't update).
The fix introduced in 2.4.1 (09c6c94) makes it doing a full page reload instead of doing nothing.

Edit 2:

After editing Page.vue, its update is propagated (propagateUpdate) with index.css as an importer, leading to this code to be called : https://github.com/OneNail/vite/blob/328a2940963e52f1bf30412564624ff1715155cb/packages/vite/src/node/server/hmr.ts#L247-L256

This is the object received by propagateUpdate() :

  id: null,
  file: '/Users/anthonycatel/dev/bug-vite-tailwind/src/views/Page.vue',
  importers: Set(1) {
    ModuleNode {
      id: '/Users/anthonycatel/dev/bug-vite-tailwind/index.css?direct',
      file: '/Users/anthonycatel/dev/bug-vite-tailwind/index.css',
      importers: Set(0) {},
      importedModules: [Set],
      acceptedHmrDeps: Set(0) {},
      isSelfAccepting: true,
      transformResult: null,
      ssrTransformResult: null,
      ssrModule: null,
      lastHMRTimestamp: 1626186072440,
      url: '/index.css?direct',
      type: 'css'
    }
  },
  importedModules: Set(0) {},
  acceptedHmrDeps: Set(0) {},
  isSelfAccepting: false,
  transformResult: null,
  ssrTransformResult: null,
  ssrModule: null,
  lastHMRTimestamp: 1626186072440,
  url: '/@fs//Users/anthonycatel/dev/bug-vite-tailwind/src/views/Page.vue',
  type: 'js'
}

I'm not sure why routes.ts is not part of the importers list

IIUC, tailwind tells postcss to register all the purgeable files as a dependencies and so this is being called :
https://github.com/vitejs/vite/blob/main/packages/vite/src/node/plugins/css.ts#L674 leading to Page.vue being a deps of index.css

This precise case could be fixed by importing index.css from main.js instead of being a link in index.html (somehow routes.ts becomes an importer in addition to index.css in that case. But then the same issue could arise for SFC at the end of the chain. (Edit 3: I added another test case for this here : https://github.com/paraboul/vue-hmr-reload/tree/alt)

I'm laking a bit of context here to go forward with a fix.

Edit 4 :

Overall it seems that the issue is that Tailwind (JIT) generated css (index.css) somehow mess up with the importers list of SFC and strips any other importers in some cases.

@paraboul
Copy link
Contributor

@paraboul paraboul commented Jul 15, 2021

So it seems that the moduleGraph contains 2 entries for the SFC being updated :

  • One with index.css as the only importer (because Tailwind tells that every purgeable files are a deps of the generated css (index.css).
  • Another one with the "right" importer (the parent component or the js file where the component is imported).

Then during handleHotUpdate(), vite:vue plugin filter the list of modules on the hmrContext, leading to the second one being filtered out.

Ultimately a force page reload is invoked according to this code :

// #3716, #3913
// For a non-CSS file, if all of its importers are CSS files (registered via
// PostCSS plugins) it should be considered a dead end and force full reload.
if (
!cssLangRE.test(node.url) &&
[...node.importers].every((i) => cssLangRE.test(i.url))
) {
return true
}

@paraboul
Copy link
Contributor

@paraboul paraboul commented Jul 15, 2021

My guess is the original issue lies somewhere where the SFC module is registered twice with different URL and differents importers (absolute with FS_PATH from postcss (calling createFileOnlyEntry()) and relative in the moduleGraph (ensureEntryFromUrl()).

@eugene1g
Copy link

@eugene1g eugene1g commented Jul 15, 2021

As an interim solution, downgrading to vite@2.3.8 helped to get HMR working again in my project.

@paraboul
Copy link
Contributor

@paraboul paraboul commented Jul 16, 2021

As an interim solution, downgrading to vite@2.3.8 helped to get HMR working again in my project.

@eugene1g
2.3.8 is still broken if you're using Tailwind 2.2 + JIT mode in some cases (e.g. the one I linked).

@lhermann
Copy link

@lhermann lhermann commented Jul 19, 2021

Same issue here with tailwindcss@2.2.4, vite@2.4.1 and vue@3.1.4.

And additional observation: When you enable mode: 'jit' in tailwind.config.js and then start vite, it always performs a full page reload. But when you first start vite and then add mode: 'jit' (and wait for vite to apply the change itself), then the HMR works as expected.

@patak-js
Copy link
Member

@patak-js patak-js commented Jul 19, 2021

And additional observation: When you enable mode: 'jit' in tailwind.config.js and then start vite, it always performs a full page reload. But when you first start vite and then add mode: 'jit' (and wait for vite to apply the change itself), then the HMR works as expected.

This is further confirmation for #4267, because the order in which modules are emcountered can mask tge bug. @lhermann Could you try to yarn link vite with this PR to check that the issue is resolved for you?

@lhermann
Copy link

@lhermann lhermann commented Jul 19, 2021

@patak-js could you elaborate what you mean by "yarn link vite with this PR"? I'm afraid I don't quite understand.

@patak-js
Copy link
Member

@patak-js patak-js commented Jul 19, 2021

@lhermann
Copy link

@lhermann lhermann commented Jul 19, 2021

@patak-js thanks, learned something new today. I linked #4267 and can confirm that it resolves the issue, HMR works as expected 🎉

patak-js pushed a commit that referenced this issue Jul 20, 2021
@github-actions github-actions bot locked and limited conversation to collaborators Aug 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet