从utils导入Tailwind类字符串在Next.js中不生效的原因咨询
问题
在Next.js项目中,从utils文件导入Tailwind类名字符串到app目录的index页面使用时未生效,但直接在app目录元素的className中编写这些类名却能正常工作。
相关代码
utils/responsiveBox
const responsiveBoxClass = "border-2 border-[red] xxsmScr:border-tahitiii xsmScr:border-[blue] smScr:border-[green] midScr:border-[orange] bigScr:border-[white] biggerScr:border-[brown] biggestScr:border-[grey]"; export default responsiveBoxClass;
app/page.tsx
import { AvatarContainer } from "@/components/home/avatarContainer"; import { RenderBox } from "@/components/home/renderBox"; import responsiveBoxClass from "@/utils/responsiveBox"; export default function Home() { return ( <div className="w-screen h-[300vh]" style={{ backgroundImage: `url("/home/gvHomeBg.svg")`, backgroundSize: 'cover', backgroundRepeat: 'no-repeat' }}> <div className="flex justify-center items-start w-screen"> <RenderBox className={`bg-primary ${responsiveBoxClass} my-[40px] h-[800px]`}> <AvatarContainer /> </RenderBox> </div> </div> ); }
tailwind.config.ts
/** @type {import('tailwindcss').Config} */ import type { Config } from "tailwindcss"; const config: Config = { content: [ "./pages/**/*.{js,ts,jsx,tsx,mdx}", "./components/**/*.{js,ts,jsx,tsx,mdx}", "./app/**/*.{js,ts,jsx,tsx,mdx}" ], theme: { screens: { 'xxsmScr': "360px", 'xsmScr': "450px", 'smScr': "640px", 'midScr': "768px", 'bigScr': "1024px", 'biggerScr': "1280px", 'biggestScr': "1536px", }, extend: { backgroundImage: { "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", "gradient-conic": "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", }, colors: { primary: { foreground: "white", DEFAULT: "black", }, tahitiii: { foreground: "#FF5733", DEFAULT: "#20575A", } } }, }, plugins: [], }; export default config;
原因
Tailwind CSS依赖静态扫描生成样式:构建时它会遍历tailwind.config.ts中content配置的目录,提取出明确写在className属性里的类名,再生成对应的CSS。
你把类名字符串放在utils文件中,再通过模板字符串拼接传入className,Tailwind的扫描器无法识别这种动态拼接的类名——它不会解析utils文件里的字符串内容,也无法追踪模板变量里的类名,因此这些类名不会被纳入生成的CSS,自然无法生效。
而直接在className中写类名时,Tailwind能直接扫描到这些类,所以样式正常工作。
解决方案
1. 将utils目录加入Tailwind扫描范围
修改tailwind.config.ts的content数组,添加utils目录:
content: [ "./pages/**/*.{js,ts,jsx,tsx,mdx}", "./components/**/*.{js,ts,jsx,tsx,mdx}", "./app/**/*.{js,ts,jsx,tsx,mdx}", "./utils/**/*.{js,ts}" // 新增此行 ],
这样Tailwind会扫描utils目录下的文件,提取其中的类名生成样式。
2. 使用Tailwind推荐的类名组合工具(推荐)
用clsx工具组合类名,它的调用会被Tailwind扫描器识别:
首先安装clsx:
npm install clsx
修改utils文件:
import clsx from 'clsx'; const responsiveBoxClass = clsx("border-2 border-[red] xxsmScr:border-tahitiii xsmScr:border-[blue] smScr:border-[green] midScr:border-[orange] bigScr:border-[white] biggerScr:border-[brown] biggestScr:border-[grey]"); export default responsiveBoxClass;
修改页面代码:
import { AvatarContainer } from "@/components/home/avatarContainer"; import { RenderBox } from "@/components/home/renderBox"; import clsx from 'clsx'; import responsiveBoxClass from "@/utils/responsiveBox"; export default function Home() { return ( <div className="w-screen h-[300vh]" style={{ backgroundImage: `url("/home/gvHomeBg.svg")`, backgroundSize: 'cover', backgroundRepeat: 'no-repeat' }}> <div className="flex justify-center items-start w-screen"> <RenderBox className={clsx("bg-primary", responsiveBoxClass, "my-[40px] h-[800px]")}> <AvatarContainer /> </RenderBox> </div> </div> ); }
内容的提问来源于stack exchange,提问作者Krishna Kant
相关产品推荐
相关产品推荐

