Next.js 13+ 默认不支持 Less,须用 next-with-less;.module.less 必须与组件同名同级;全局 Less 仅限 app/layout.tsx 顶部导入;动态拼接 class 破坏模块作用域,应优先用 composes 或 clsx。

Next.js 13+ 默认不支持 Less,必须用 next-with-less
Next.js 13(App Router)默认只识别 .css 和 .module.css,.less、.module.less 全部被忽略——不报错、不警告、直接白屏或样式丢失。这不是配置遗漏,是官方关闭了该能力。必须引入社区方案:next-with-less。它不是插件式配置,而是重写 Webpack 规则的“增强包”,会自动复制 Sass 的模块化逻辑并替换为 Less。
安装命令:npm install next-with-less -D。注意不要装 @zeit/next-less(已废弃多年,与 Webpack 5+ 不兼容)或手动配 less-loader(Next.js 内部规则已被封装,外部配置会被覆盖)。
.module.less 命名和路径必须严格匹配
Next.js 的 CSS Modules 绑定靠静态文件名识别,不依赖 import 路径或目录结构。以下任一条件不满足,import styles from './X.module.less' 就会返回空对象:
-
X.module.less必须和组件文件(如X.tsx)同名、同级目录 - 文件名大小写敏感:
button.module.less≠Button.module.less(后者才生效) - 不能把
.module.less放进styles/目录再用相对路径 import——Next.js 不会递归解析模块规则,只认“同名同目录”这一种绑定方式
错误示例:import styles from '@/styles/Button.module.less' → 找不到模块;正确写法:import styles from './Button.module.less'(组件与样式在同一个 components/Button/ 下)。
立即学习“前端免费学习笔记(深入)”;
全局 Less 样式只能在 app/layout.tsx 顶层 import
想加 variables.less 或 reset.less?不能在任意组件里 import,也不能塞进 _app.tsx(App Router 已弃用该文件)。唯一合法位置是 app/layout.tsx 的最顶部:
import './globals.css'
import './theme/variables.less' // ✅ 全局 Less 只能在这里
import './theme/reset.less'
export default function RootLayout({ children }) {
return (
<html lang="zh">
<body>{children}</body>
</html>
)
}
这里 import 的 Less 会走全局规则(非模块化),类名不哈希、可被所有组件访问。但注意:它不会参与 CSS Modules 的作用域隔离,也不受 composes 或 @use 影响——Less 的 @import 在全局上下文中仍有效,但变量和 mixin 需确保路径正确(推荐用 sassOptions.includePaths 类似方式配 lessOptions.paths,需在 next-with-less 的 webpack 配置中手动加)。
动态拼接 class 名会绕过模块作用域,慎用
写 className={`${styles.primary} ${otherClass}` 看似方便,实际破坏了 CSS Modules 的核心价值:局部作用域。其中 otherClass 若来自全局样式、第三方库或字符串字面量,就可能污染或覆盖预期样式。
更安全的做法:
- 用
composes在.module.less内组合:.btn { composes: primary from './Base.module.less'; } - 需要运行时切换时,用
clsx库统一管理:className={clsx(styles.primary, type === 'danger' && styles.danger)} - 避免在模板中硬编码类名字符串,尤其不要拼接用户输入或未定义变量
Less 模块本身不支持 @use(那是 Sass 的语法),所以复用逻辑得靠 @import + composes,且所有被 @import 的文件也必须是 .module.less 后缀,否则变量无法跨模块共享。


















