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

Support invalidating Vite Styling when content changes (Tailwind, Uno, etc) #1119

Open
atinux opened this issue May 23, 2022 · 11 comments
Open
Labels
enhancement New feature or request

Comments

@atinux
Copy link
Member

atinux commented May 23, 2022

I think a video is better to understand:

Screenshot.2022-05-04.at.18.42.26.mp4

Adding classes that are not generated by Tailwind at first does not work when changing

Example for Tailwind: https://stackblitz.com/edit/nuxt-starter-omgw5t?file=app.vue

I am also trying to make UnoCSS works but not sure what I did wrong (cc @antfu): https://stackblitz.com/edit/nuxt-starter-rbqpf3?file=nuxt.config.ts

@atinux atinux added the enhancement New feature or request label May 23, 2022
@antfu
Copy link
Member

antfu commented May 23, 2022

Do we have a resource that describes how Nuxt Content handles the markdown compiling somewhere? Did a quick check, and it seems that the markdowns are not been passed to Vite's plugins pipeline. Which UnoCSS is relying on, and probably also how TW handles HMR.

By adding this to config:

 vite: {
    plugins: [
      {
        name: 'foo',
        transform(code, id) {
          if (!id.match('node_modules'))
            console.log(id)
        },
      },
    ],
  },

You will see the contents are not presented in the log.

Copy link
Member Author

atinux commented May 23, 2022

Indeed @antfu, the Markdown files are not handled through Vite at all, this is the power of Nuxt Content, the Markdown is part of runtime, like any other CMS.

The main thing I need is the ability to tell Vite to tell its plugins (Uno, Tailwind, etc) to "recompile" by reading their sources (content/** is included in them). Basically, it will be here that I would like to ping Vite to re-run the plugin and do a HMR: https://github.com/nuxt/content/blob/docs/marketing/src/module.ts#L421

Or it could be handled on client-side here: https://github.com/nuxt/content/blob/docs/marketing/src/runtime/composables/web-socket.ts#L25

Something like import.meta.hot.refreshStyles() could be possible? (https://vitejs.dev/guide/api-plugin.html#client-to-server)

@antfu
Copy link
Member

antfu commented May 23, 2022

Tailwind is probably reading the changes from the disk, in this case, you might need a custom extractor for it to understand MDC? Other than that, you might just need to invalidate the style. You can use configureServer hook from a Vite plugin, and send a ws event to vite client manually:

server.ws.send({
  type: 'update',
  updates: [{
    acceptedPath: id, // id is the CSS file contains `@tailwind`
    path: id,
    timestamp: +Date.now(),
    type: 'js-update',
  }],
})

For UnoCSS it's a bit different, we read and extract utils usage from the plugin's transform hook instead of disk for efficiency. It means in this case UnoCSS didn't know about the contents at all. You might need to use cross-plugin API.

Unless we fake the vite plugin hook calls, we might more or less need to have some specific logic for handling Uno or Tailwind (probably a few other integrations in the future).

@harlan-zw
Copy link
Contributor

harlan-zw commented May 26, 2022

Nuxt content v1 also had this issue with Windi, I fixed it with this code.

Basically, hook into before the markdown is parsed, extract the classes from the markdown, generate the classes for just that file and insert them at the end of the .md within a style block.

Not an ideal solution by any means but it's simple and worked. Since the scope was just the HMR update I wasn't too worried, the build isn't effected. Not sure if the same hook is provided for v2.

Seems like we'll need a custom extractor either way

@atinux
Copy link
Member Author

atinux commented May 26, 2022

Can we expose this hook @farnabaz ?

@farnabaz
Copy link
Member

We can provide a similar hook. Not in module scope but inside nitro scope.
Windi module could inject a nitro plugin to use this hook.

// windi-nitro-plugin.ts
export default defineNitroPlugin((nitroApp) => {
 nitroApp.hooks.hook('content:file:beforeParse', () => {
   ...
 })
})

@harlan-zw
Copy link
Contributor

Sounds good, I'm guessing we would be able to inject this nitro plugin via the nitro:context hook?

@farnabaz
Copy link
Member

'nitro:context' removed in favor of 'nitro:config'. You can use this hook to update nitro configs

@harlan-zw
Copy link
Contributor

It's a bit hacky and there are sometimes some weird h3 and worker errors popping up, but nuxt-windicss now supports nuxt/content v2

Nitro plugin: https://github.com/windicss/nuxt-windicss/blob/main/packages/nuxt-windicss/src/runtime/server/class-extractor.mjs
Setup: https://github.com/windicss/nuxt-windicss/blob/main/packages/nuxt-windicss/src/module.ts#L310

@Triloworld
Copy link
Contributor

Right now is not working together - MDC and UnoCSS:
Example from @atinux but newest version: https://stackblitz.com/edit/nuxt-starter-9s9zsj?file=content%2Findex.md,app.vue,package.json

    "@nuxt/content": "npm:@nuxt/content-edge@latest",
    "@unocss/nuxt": "^0.45.21",
    "nuxt": "3.0.0-rc.9"

We have problem with tailwind by refresh loop. On UnoCSS is not updating at all on rc9.

@anhzf
Copy link

anhzf commented Feb 29, 2024

for those who looking current workaround for unocss, you can include your content dir to uno.config.ts

export default defineConfig({
  filesystem: ['content/**'],
  pipeline: {
    include: [
      // the file extensions are limited by default. In my case, I need to add .json extension
      /\.(vue|svelte|[jt]sx|mdx?|astro|elm|php|phtml|html|json)($|\?)/,
    ]
  }
})

references: https://unocss.dev/guide/extracting#extracting-from-filesystem

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

No branches or pull requests

6 participants