Next.js15中SCSS模块样式仅在next dev --turbo下生效的问题
Next.js 15 + Mantine 7 SCSS模块样式仅在
next dev --turbo生效问题排查 问题描述
使用Next.js 15(App目录)+ Mantine 7开发项目,通过SCSS模块(*.module.scss)为Mantine组件设置样式时出现差异:
- 仅执行
next dev --turbo时,SCSS模块样式能正确应用到Mantine组件; - 执行普通
next dev或next build→next start启动构建后的项目时,SCSS模块样式完全/部分失效(如font-size、color等样式不生效,需加!important才能覆盖)。
现有配置
next.config.mjs
import path from 'node:path'; import bundleAnalyzer from '@next/bundle-analyzer'; const withBundleAnalyzer = bundleAnalyzer({ enabled: process.env.ANALYZE === 'true', }); export default withBundleAnalyzer({ reactStrictMode: false, eslint: { ignoreDuringBuilds: true, }, experimental: { optimizePackageImports: ['@mantine/core', '@mantine/hooks'], }, sassOptions: { implementation: 'sass-embedded', additionalData: `@use "${path.join(process.cwd(), '_mantine').replace(/\\/g, '/')}" as mantine;`, }, });
package.json(核心依赖片段)
{ "dependencies": { "@mantine/core": "7.16.3", "@mantine/hooks": "7.16.3", "next": "15.1.7", "react": "18.3.1", "react-dom": "18.3.1" }, "devDependencies": { "postcss": "^8.4.38", "postcss-preset-mantine": "1.17.0", "postcss-simple-vars": "^7.0.1", "sass": "^1.85.0", "sass-embedded": "^1.83.4" } }
示例SCSS模块(footer.module.scss)
.footerLink { color: var(--mantine-color-neutral-4) !important; // 加!important才生效 transition: color 0.2s ease; // 正常生效 font-size: 16px; // 不生效 &:hover { color: var(--mantine-color-primary-5); // 不生效 } } .listRoot { column-count: 1; // 正常生效 column-gap: 42px; // 正常生效 @media (min-width: mantine.$mantine-breakpoint-sm) { column-count: 2; // 正常生效 } } .listText { line-height: 13.81px; // 不生效 }
已尝试操作
移除next.config.mjs中的implementation: 'sass-embedded'配置后,部分组件的SCSS模块样式生效,但font-size、color等核心样式仍被Mantine内置样式覆盖,需加!important才能生效。
原因分析
- 编译链差异:Next.js Turbo Dev使用Rspack编译,普通
dev和build使用Webpack,两者对Sass变量注入、CSS模块优先级的处理逻辑不同,Turbo模式下可能默认调整了样式加载顺序,让SCSS模块优先级更高。 - Sass依赖冲突:同时安装
sass和sass-embedded,Webpack编译时可能优先使用了不兼容的版本,导致additionalData中的Mantine变量注入不完整,或者CSS模块类名生成逻辑异常。 - 样式优先级问题:Mantine 7基于Emotion实现CSS-in-JS,其生成的样式优先级默认高于SCSS模块,普通编译模式下未调整加载顺序,导致SCSS样式被覆盖。
解决方案
1. 统一Sass依赖
移除sass-embedded,仅保留sass,避免双版本冲突:
yarn remove sass-embedded
修改next.config.mjs的sassOptions,删除implementation配置:
sassOptions: { additionalData: `@use "${path.join(process.cwd(), '_mantine').replace(/\\/g, '/')}" as mantine;`, },
2. 调整样式优先级
使用clsx合并类名,确保SCSS模块类名正确传递给Mantine组件,或通过组件的classNames prop指定特定部分的样式:
import { Link, List } from '@mantine/core'; import styles from './footer.module.scss'; import clsx from 'clsx'; // 直接合并类名 <Link className={clsx(styles.footerLink)}>链接文本</Link> // 针对组件内部元素指定类名 <List className={styles.listRoot} classNames={{ item: styles.listText }} />
3. 检查PostCSS配置
确保postcss.config.cjs正确配置Mantine预设,避免变量丢失:
module.exports = { plugins: { 'postcss-preset-mantine': {}, 'postcss-simple-vars': { variables: { 'mantine-breakpoint-sm': '576px', // 其他自定义变量 }, }, }, };
4. 禁用实验性包优化
暂时注释next.config.mjs中的optimizePackageImports配置,避免与样式处理冲突:
// experimental: { // optimizePackageImports: ['@mantine/core', '@mantine/hooks'], // },
5. 清除缓存
删除.next、node_modules/.cache目录,清理Yarn缓存后重新编译:
rm -rf .next node_modules/.cache yarn cache clean
验证步骤
- 执行
yarn dev,检查SCSS模块样式是否正常生效; - 执行
yarn build && yarn start,验证生产环境样式表现; - 若仍有样式不生效,使用浏览器开发者工具查看样式优先级,调整选择器或类名传递方式。
内容的提问来源于stack exchange,提问作者gidgud
相关产品推荐
相关产品推荐

