chrome-extension-tools icon indicating copy to clipboard operation
chrome-extension-tools copied to clipboard

HMR doesn't work for Tailwind classes in content scripts

Open AndreiHudovich opened this issue 1 year ago • 17 comments

Build tool

Vite

Where do you see the problem?

  • [X] In the browser
  • [ ] In the terminal

Describe the bug

It looks like it's the same (or similar) issue that we had in v1 - #288

Everything works perfectly for a popup and options page. But when you add Tailwind classes in the content script source, the injected CSS file in the head isn't updated. Classes are added to the class attributes in HTML code by HMR, but CSS stays intact.

Only restarting Vite helps to capture new classes.

Reproduction

I've added popup, options and content script to test.

https://github.com/andrei-hudovich/crxjs-issue-tailwindcss

Logs

--

System Info

System:
    OS: macOS 13.2.1
    CPU: (8) x64 Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
    Memory: 112.87 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.15.0 - ~/.nvm/versions/node/v18.15.0/bin/node
    npm: 9.6.1 - ~/.nvm/versions/node/v18.15.0/bin/npm
  Browsers:
    Chrome: 111.0.5563.64
  npmPackages:
    @crxjs/vite-plugin: ^2.0.0-beta.15 => 2.0.0-beta.15
    vite: ^4.1.4 => 4.2.0

Severity

annoyance

AndreiHudovich avatar Mar 17 '23 08:03 AndreiHudovich

I found a little work around: https://github.com/crxjs/chrome-extension-tools/issues/609#issuecomment-1563634844

thmsmlr avatar May 25 '23 23:05 thmsmlr

Same issue here. Only reloading vite server I see changes in the CSS.

I also notice that generated file by vite is not updated in dist/css/app.css.js so maybe I have another problem. Just adding here just in case other people is using also Vite.

Also to add more entropy I'm doing the chrome extension in a monorepo with pnpm and turbo-repo where some styles are in a package which I call ui 😂

andresgutgon avatar Jun 11 '23 12:06 andresgutgon

Same here.

ghost avatar Jun 23 '23 00:06 ghost

The same problem, use import "./tailwind.css?inline" syntax HMR does not work

molvqingtai avatar Jul 15 '23 15:07 molvqingtai

Still no news on this issue?

AndreiHudovich avatar Aug 18 '23 11:08 AndreiHudovich

I use workaround for now by:

// tailwind.config.js
{
  safelist: process.env.NODE_ENV === 'development' ? [{ pattern: /./ }] : [],
}

yunsii avatar Sep 10 '23 02:09 yunsii

I use workaround for now by:

// tailwind.config.js
{
  safelist: process.env.NODE_ENV === 'development' ? [{ pattern: /./ }] : [],
}

Takes a lot of time to reload, isn't it?

ghost avatar Oct 28 '23 00:10 ghost

@carlos-mta It's inevitable, but I think it is better than restart dev server frequently.

yunsii avatar Oct 28 '23 03:10 yunsii

Some follow-up on this issue.

I had to downgrade the Vite version to the one that CRXJS uses, and it works fine now. It's quite misleading that there is no Vite version specified in peer dependencies for v2.

These versions definitely have HMR for Tailwind:

  • "@crxjs/vite-plugin": "2.0.0-beta.21",
  • "vite": "3.1.7"

Bear in mind, though, that you'll have to downgrade your other Vite plugins too, as they probably won't work with Vite 3!

AndreiHudovich avatar Dec 19 '23 17:12 AndreiHudovich

Just like to bump this! Downgrading to vite 3.1.7 really isn't an option for me because it's so outdated. If I have time, I'll try to look in and see if I can fix this issue.

megagames-me avatar Dec 26 '23 15:12 megagames-me

Having this issue too with React/Vite/Tailwind within a Chrome Extension content script. I seemed to have found a better workaround than above.

Basically at the root of my app I have one central stylesheet that I am importing that includes the tailwind styles in src/styles/global.css. I always have my global.css open in vscode and whenever I add utility classes in my code and the changes aren't reflected in the app I just resave the global.css and HMR kicks in with the new styles applied.

kmcaloon avatar Dec 29 '23 21:12 kmcaloon

happens on

"@crxjs/vite-plugin": "2.0.0-beta.23",
"vite": "^5.1.1"

it's a real shame to go back to rollback 2 version of vite to Vite@3

aything we can do to tackle this?

kaminskypavel avatar Feb 21 '24 10:02 kaminskypavel

I use workaround for now by:

// tailwind.config.js
{
  safelist: process.env.NODE_ENV === 'development' ? [{ pattern: /./ }] : [],
}

I really would NOT recommend doing that. bare in mind this will resolve in a 16mb css file. your vite loading time will be in minutes no milliseconds

Use a more sensible subset of classes instead. for me this was enough, but your milage may vary.

  // !! this is a workaround for a big in crxjs
  // !! https://github.com/crxjs/chrome-extension-tools/issues/671
  // eslint-disable-next-line no-undef
  safelist: process.env.NODE_ENV === 'development' ?
    [
      {
        // colors 
        pattern: /\b((bg|text)-[\w-]+)/,
      },
      {
        // padding and margin
        pattern: /\b((p|px|py|my|mx|spacing-x|spacing-y)-\d+)/,
      },
      {
        // width, high, and size
        pattern: /\b((w|h|s)-\d+)/,
      },
    ] : [],

this will resolve in a 1mb index.css.js file (instead of 16)

kaminskypavel avatar Feb 21 '24 10:02 kaminskypavel

Any updates on this?

ozeron avatar Mar 18 '24 18:03 ozeron

The workaround @kmcaloon mentioned is the most conventional one here, but it's still pretty annoying to have to manually resave the global CSS file. We could have a plugin to automate this.

// vite-plugin-touch-global-css.ts

import fs from 'fs';
import { Plugin } from 'vite';

function touchFile(filePath: string): void {
  const time = new Date();
  fs.utimesSync(filePath, time, time);
}

type TouchGlobalCSSPluginOptions = {
  cssFilePath: string;
  watchFiles: string[];
};

export default function touchGlobalCSSPlugin({
  cssFilePath,
  watchFiles,
}: TouchGlobalCSSPluginOptions): Plugin {
  return {
    name: 'touch-global-css',
    configureServer(server) {
      server.watcher.on('change', (file) => {
        if (watchFiles.some((watchFile) => file.includes(watchFile))) {
          touchFile(cssFilePath);
        }
      });
    },
  };
}
// vite.config.ts

import path from 'path';
import { defineConfig } from 'vite';
import viteTouchGlobalCss from 'vite-plugin-touch-global-css';

export default defineConfig(() => {
  return {
    plugins: [
      viteTouchGlobalCss({
        cssFilePath: path.resolve(__dirname, 'src/assets/globals.css'),
        watchFiles: ['./src/content-script'],
      }),
    ],
  };
});

pnd280 avatar May 19 '24 10:05 pnd280

The above solution worked for me. Thank you for your help @pnd280

Additionally, we can add support to Windows file system:

export default function touchGlobalCSSPlugin({
  cssFilePath,
  watchFiles,
}: TouchGlobalCSSPluginOptions): Plugin {
  return {
    name: 'touch-global-css',
    configureServer(server) {
      server.watcher.on('change', (file) => {
        file = file.replace(/\\/g, '/') // <-- Add this to add support to Windows
        if (watchFiles.some((watchFile) => file.includes(watchFile))) {
          touchFile(cssFilePath)
        }
      })
    },
  }
}

Jerrylum avatar Jun 24 '24 16:06 Jerrylum

GUYS I FOUND A SOLUTION!!!! 🎉🎉

Hey everyone,

I finally found a solution right where it all began, using minified libraries! 😂

All you need to do is download the minified Tailwind file from cdn.tailwindcss.com and include it in your project's main file. And that's it! GG!

working well: image image (1) image (2) image (3)

geanrt avatar Aug 04 '24 20:08 geanrt