Create React App中字体preload的使用及引用问题
解决Create React App中字体预加载与@font-face引用的问题
我来帮你梳理两种可行的方案,分别对应字体放在public目录和src目录的场景:
方案一:字体保留在public目录
你已经在index.html中配置了正确的preload标签,现在只需要在CSS的@font-face里用绝对路径引用字体即可:
@font-face { font-family: 'MyCustomFont'; src: url('/myFontFile.woff2') format('woff2'); /* 可选:添加字体权重、样式等属性 */ font-weight: normal; font-style: normal; }
为什么用/开头?因为Create React App会把public目录下的资源直接拷贝到打包产物的根目录,所以根路径就能直接访问到字体文件。而你在index.html里用的%PUBLIC_URL%会被打包工具自动替换为正确的公共基础路径,和CSS里的绝对路径是一致的。
方案二:字体移到src目录(推荐,利于缓存管理)
如果把字体放在src目录下,webpack会自动对字体文件进行哈希命名(比如myFontFile.xyz123.woff2),解决缓存更新的问题。这时候需要按以下步骤操作:
1. 在CSS中引用字体
直接用相对路径指向src目录下的字体文件,webpack会自动处理打包路径:
@font-face { font-family: 'MyCustomFont'; src: url('./assets/fonts/myFontFile.woff2') format('woff2'); /* 调整路径为你实际的字体文件位置 */ font-weight: normal; font-style: normal; }
2. 动态添加preload标签
因为打包后的文件名带哈希,没办法在index.html里写固定路径,所以可以在React组件中动态创建preload标签:
import { useEffect } from 'react'; import myFont from './assets/fonts/myFontFile.woff2'; // 导入字体文件 function App() { useEffect(() => { const preloadLink = document.createElement('link'); preloadLink.rel = 'preload'; preloadLink.href = myFont; // 这里的myFont就是打包后的带哈希的URL preloadLink.as = 'font'; preloadLink.type = 'font/woff2'; preloadLink.crossOrigin = 'anonymous'; // 若字体是跨域资源需要添加,同域可省略 document.head.appendChild(preloadLink); // 组件卸载时移除标签(可选,视需求而定) return () => { document.head.removeChild(preloadLink); }; }, []); return ( <div className="App"> {/* 你的组件内容 */} </div> ); } export default App;
小提示
- 放在
src目录的字体文件会被webpack的asset模块处理,自动添加哈希后缀,发布新版本时浏览器会自动加载新的字体文件,避免缓存问题; - 放在
public目录的字体文件名不会改变,如果需要更新字体,得手动修改文件名或者添加查询参数(比如myFontFile.woff2?v=2)来强制浏览器刷新缓存。
内容的提问来源于stack exchange,提问作者maracuja-juice
相关产品推荐
相关产品推荐

