
本文介绍在 React 项目中基于 .env 文件动态配置并加载多种自定义字体的实用方案,涵盖运行时动态注入 @font-face、环境感知路径拼接、React 封装技巧及注意事项。
本文介绍在 react 项目中基于 `.env` 文件动态配置并加载多种自定义字体的实用方案,涵盖运行时动态注入 `@font-face`、环境感知路径拼接、react 封装技巧及注意事项。
在 React 应用中,将字体路径硬编码在 CSS/SCSS 中会导致环境适配困难(如开发用本地 localhost:3000/fonts/xxx.woff2,生产需指向 CDN 域名 https://cdn.example.com/fonts/xxx.woff2)。由于 CSS 预处理器(如 Sass)无法直接读取 JavaScript 运行时环境变量(如 process.env.REACT_APP_FONT_BASE_URL),因此不推荐通过 SCSS 变量 + .env 联动的方式实现动态字体路径——这正是你尝试失败的根本原因:.env 变量仅在构建时注入 JS 环境,Sass 编译阶段不可见。
✅ 推荐方案:运行时动态加载字体(FontFace API) + 环境变量驱动路径配置
FontFace API 是现代浏览器原生支持的标准方案,允许你在 JS 中按需创建、加载并注册字体族,完全绕过 CSS 文件依赖,天然支持环境变量拼接:
// utils/fontLoader.js
export const loadFont = async (family, fileName, options = {}) => {
const baseUrl = process.env.REACT_APP_FONT_BASE_URL || '';
const url = `${baseUrl}/fonts/${fileName}`;
const fontFace = new FontFace(family, `url(${url})`, options);
const loadedFont = await fontFace.load();
document.fonts.add(loadedFont);
};
在 .env 文件中配置不同环境的字体基础路径:
# .env.development REACT_APP_FONT_BASE_URL=http://localhost:3000 # .env.production REACT_APP_FONT_BASE_URL=https://cdn.yourapp.com
然后在组件中按需加载(例如 App 初始化或主题切换时):
// App.jsx
import { useEffect } from 'react';
import { loadFont } from './utils/fontLoader';
const App = () => {
useEffect(() => {
// 动态加载多个字体(支持 Promise.all 并发)
Promise.all([
loadFont('Inter', 'Inter-Regular.woff2', { weight: '400' }),
loadFont('Inter', 'Inter-Bold.woff2', { weight: '700' }),
loadFont('Space Grotesk', 'SpaceGrotesk-Medium.woff2', { weight: '500', style: 'normal' })
]).then(() => {
console.log('All fonts loaded and registered');
}).catch(err => console.error('Font loading failed:', err));
}, []);
return (
<div style="{{" fontfamily: grotesk sans-serif>
<h1>Hello, dynamic fonts!</h1>
<p>This text uses environment-aware fonts.</p>
</div>
);
};
export default App;
⚠️ 注意事项:
-
浏览器兼容性:
FontFace支持 Chrome 35+、Firefox 41+、Safari 10.1+、Edge 17+;旧版 IE 不支持,需降级 fallback(如仅用系统字体); -
字体 FOIT/FOUT 控制:可通过
document.fonts.load()检测加载状态,结合font-display: swap(在 CSS 中声明备用规则)优化渲染体验; -
性能建议:避免在渲染中频繁调用
loadFont;优先批量加载核心字体,非关键字体可懒加载; -
TypeScript 提示:为
loadFont添加类型定义,明确family: string,fileName: string,options?: FontFaceDescriptors。
总结:摒弃“SCSS + 环境变量”的静态编译思路,转向 FontFace API + process.env 的运行时动态加载,是 React 中实现多环境字体路径解耦最灵活、可靠且符合现代 Web 标准的实践方式。











