chrome-extension-tools
chrome-extension-tools copied to clipboard
HMR doesn't work for Tailwind classes in content scripts
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
I found a little work around: https://github.com/crxjs/chrome-extension-tools/issues/609#issuecomment-1563634844
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
😂
Same here.
The same problem, use import "./tailwind.css?inline"
syntax HMR does not work
Still no news on this issue?
I use workaround for now by:
// tailwind.config.js
{
safelist: process.env.NODE_ENV === 'development' ? [{ pattern: /./ }] : [],
}
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?
@carlos-mta It's inevitable, but I think it is better than restart dev server frequently.
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!
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.
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.
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?
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)
Any updates on this?
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'],
}),
],
};
});
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)
}
})
},
}
}
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: