NX工作区中如何在MUI主题库正确使用@next/font
问题
我在NX工作区中使用Next.js、MUI组件库,通过@next/font加载谷歌字体。我创建了一个shared-ui库来导出全局统一的MUI主题,主题本身没问题,但字体配置时出现以下错误:
Font loaders cannot be used from within node_modules. Location: ..\..\libs\shared\ui\src\lib\shared-ui.tsx
该库的project.json配置如下:
{ "name": "shared-ui", "$schema": "../../../node_modules/nx/schemas/project-schema.json", "sourceRoot": "libs/shared/ui/src", "projectType": "library", "tags": [], "targets": { "lint": { "executor": "@nrwl/linter:eslint", "outputs": ["{options.outputFile}"], "options": { "lintFilePatterns": ["libs/shared/ui/**/*.{ts,tsx,js,jsx}"] } }, "test": { "executor": "@nrwl/jest:jest", "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { "jestConfig": "libs/shared/ui/jest.config.ts", "passWithNoTests": true } } } }
请问如何在NX工作区中正确结合MUI与@next/font?
解决方案
问题根源是@next/font的加载逻辑仅允许在Next.js应用层执行——NX会将library编译后放入node_modules目录,触发了Next.js的加载限制。按以下步骤调整即可解决:
将字体初始化移至Next.js应用根目录
在你的Next.js应用(如apps/your-app)中创建字体配置文件,比如src/config/fonts.ts,在这里完成谷歌字体的加载:import { Inter } from '@next/font/google'; // 根据需求配置字重、子集等参数 export const interFont = Inter({ subsets: ['latin'], weight: ['300', '400', '500', '700'], variable: '--font-inter', });修改shared-ui库的主题文件,依赖外部字体变量
在shared-ui库的主题文件中,不再直接初始化字体,而是通过CSS变量引用应用层传入的字体:import { createTheme } from '@mui/material/styles'; export const createAppTheme = () => { return createTheme({ typography: { fontFamily: 'var(--font-inter)', }, // 其他主题配置项... }); };在Next.js根组件中注入字体与主题
在apps/your-app/src/app/layout.tsx(或_app.tsx,取决于Next.js版本)中,引入字体和主题,将字体className注入根元素,同时挂载MUI的ThemeProvider:import { interFont } from './config/fonts'; import { createAppTheme } from '@your-workspace/shared-ui'; import { ThemeProvider } from '@mui/material/styles'; import CssBaseline from '@mui/material/CssBaseline'; const theme = createAppTheme(); export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en" className={interFont.className}> <body className={interFont.className}> <ThemeProvider theme={theme}> <CssBaseline /> {children} </ThemeProvider> </body> </html> ); }(可选)优化NX库的构建配置
为避免@next/font被打包进library,可在shared-ui的project.json中添加外部依赖配置:"targets": { // 保留原有targets... "build": { "executor": "@nrwl/js:tsc", "outputs": ["{options.outputPath}"], "options": { "outputPath": "dist/libs/shared/ui", "tsConfig": "libs/shared/ui/tsconfig.lib.json", "packageJson": "libs/shared/ui/package.json", "main": "libs/shared/ui/src/index.ts", "assets": ["libs/shared/ui/*.md"], "externalDependencies": ["@next/font"] } } }
内容的提问来源于stack exchange,提问作者TypeScript student
相关产品推荐
相关产品推荐

