如何在React版Chrome扩展内容脚本中运行Tailwind与DaisyUI?
问题:Chrome扩展内容脚本中Tailwind + DaisyUI样式不生效
使用Vite、React、Tailwind(4.1.3)+ DaisyUI(5.0.19)开发Chrome扩展时,Popup页面样式正常,但内容脚本中的Tailwind和DaisyUI样式完全失效。已尝试通过Shadow DOM隔离样式,但问题仍未解决。
相关代码
src/content/index.tsx
import { createRoot } from 'react-dom/client'; import { StrictMode } from 'react'; import css from './index.css?inline'; const TARGET_ID = 'secondary'; const waitForElement = (id: string, callback: (el: HTMLElement) => void) => { const el = document.getElementById(id); if (el) { callback(el); return; } const observer = new MutationObserver(() => { const found = document.getElementById(id); if (found) { observer.disconnect(); callback(found); } }); observer.observe(document.body, { childList: true, subtree: true }); }; waitForElement(TARGET_ID, (el) => { const shadowRoot = document.createElement('div'); el.prepend(shadowRoot); const shadowDOM = shadowRoot.attachShadow({ mode: 'open' }); const appRoot = document.createElement('div'); shadowDOM.append(appRoot); const styleReset = document.createElement('style'); styleReset.textContent = `:host {all: initial;}`; shadowDOM.append(styleReset); createRoot(appRoot).render( <StrictMode> <style type='text/css'>{css}</style> <div className='card bg-base-100 w-96 shadow-sm'> <figure> <img src='https://img.daisyui.com/images/stock/photo-1606107557195-0e29a4b5b4aa.webp' alt='Shoes' /> </figure> <div className='card-body'> <h2 className='card-title'>Card Title</h2> <p>A card component has a figure, a body part, and inside body there are title and actions parts</p> <div className='card-actions justify-end'> <button className='btn btn-primary'>Buy Now</button> </div> </div> </div> </StrictMode> ); });
src/content/index.css
@import 'tailwindcss'; @plugin 'daisyui';
vite.content-config.js
import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import tailwindcss from '@tailwindcss/vite'; export default defineConfig({ plugins: [react(), tailwindcss()], build: { outDir: 'build', rollupOptions: { input: { content: './src/content/index.tsx', }, output: { entryFileNames: 'assets/[name].js', }, }, emptyOutDir: false, }, });
解决方案
1. 修正Tailwind 4.x的CSS导入语法
Tailwind 4.x不再支持@import 'tailwindcss'的简写方式,需拆分导入基础、组件、工具类样式,同时调整DaisyUI的引入路径:
/* src/content/index.css */ @import 'tailwindcss/base'; @import 'tailwindcss/components'; @import 'tailwindcss/utilities'; @import 'daisyui/dist/full.css';
2. 优化Shadow DOM样式注入逻辑
将样式标签直接在Shadow DOM中创建并注入,避免React渲染时的潜在样式隔离问题:
// 修改src/content/index.tsx中的挂载逻辑 waitForElement(TARGET_ID, (el) => { const shadowHost = document.createElement('div'); el.prepend(shadowHost); const shadowDOM = shadowHost.attachShadow({ mode: 'open' }); const appRoot = document.createElement('div'); // 先注入Tailwind/DaisyUI样式 const styleEl = document.createElement('style'); styleEl.textContent = css; shadowDOM.append(styleEl); // 注入宿主重置样式 const styleReset = document.createElement('style'); styleReset.textContent = `:host { all: initial; }`; shadowDOM.append(styleReset); shadowDOM.append(appRoot); createRoot(appRoot).render( <StrictMode> <div className='card bg-base-100 w-96 shadow-sm'> {/* 原有组件内容不变 */} </div> </StrictMode> ); });
3. 确保Tailwind扫描到内容脚本的Class
在tailwind.config.js中添加内容脚本的文件路径,让Tailwind能识别并生成用到的样式:
/** @type {import('tailwindcss').Config} */ export default { content: [ './src/content/**/*.{js,ts,jsx,tsx}', // 其他需要扫描的项目文件路径 ], plugins: [require('daisyui')], // 可添加DaisyUI主题配置 };
4. 明确Vite中Tailwind插件的配置路径(可选)
如果有自定义Tailwind配置文件,在Vite配置中指定路径确保加载正确:
// vite.content-config.js export default defineConfig({ plugins: [ react(), tailwindcss({ config: './tailwind.config.js' }) ], // 原有build配置不变 });
内容的提问来源于stack exchange,提问作者Monkey
相关产品推荐
相关产品推荐

