expo
expo copied to clipboard
[SDK50] Load custom fonts with expo-font
Minimal reproducible example
https://github.com/TomCorvus/ExpoMonorepo
Summary
Hi,
I would like to know what is the good behavior to use expo-font since SDK50 in bare workflow?
I'm using useFont hook with requires which it usually worked on SDK49 but fonts don't load anymore since SDK50 and I have this error:
[Error: Module "1" is missing from the asset registry]
I tried to add the fonts in Xcode ressources but the only font I can load successfully is my custom icons font from Icomoon generator called by createIconSetFromIcoMoon
from @expo/vector-icons
But I don't know if we need to use useFont AND add fonts in Xcode ressources or use one of both options. Both of these options don't work for me btw.
I don't see any issue about this, so I don't know if it is a bug or I missed something.
I'm working on a monorepo. The app entry is in another folder. The minimal reproducible example is representative of my environment
Thanks for your replies and help.
Environment
expo-env-info 1.2.0 environment info:
System:
OS: macOS 14.2.1
Shell: 5.9 - /bin/zsh
Binaries:
Node: 20.9.0 - /usr/local/bin/node
Yarn: 4.0.1 - /usr/local/bin/yarn
npm: 10.1.0 - /usr/local/bin/npm
Watchman: 2023.07.10.00 - /usr/local/bin/watchman
Managers:
CocoaPods: 1.14.3 - /Users/nickname/.rbenv/shims/pod
SDKs:
iOS SDK:
Platforms: DriverKit 23.2, iOS 17.2, macOS 14.2, tvOS 17.2, visionOS 1.0, watchOS 10.2
Android SDK:
API Levels: 23, 26, 28, 29, 30, 31, 33, 34
Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.2, 30.0.3, 31.0.0, 33.0.0, 33.0.1, 34.0.0
System Images: android-26 | Google APIs Intel x86 Atom, android-27 | Google APIs Intel x86 Atom, android-27 | Google Play Intel x86 Atom, android-28 | Google APIs Intel x86 Atom, android-29 | Google APIs Intel x86 Atom, android-30 | Google APIs Intel x86 Atom, android-30 | Google Play Intel x86 Atom, android-31 | Google APIs ARM 64 v8a, android-31 | Google APIs Intel x86_64 Atom, android-33 | Google APIs Intel x86_64 Atom
IDEs:
Android Studio: 2023.1 AI-231.9392.1.2311.11255304
Xcode: 15.2/15C500b - /usr/bin/xcodebuild
npmPackages:
expo: ~50.0.3 => 50.0.3
react: 18.2.0 => 18.2.0
react-native: 0.73.2 => 0.73.2
Expo Workflow: bare
I think I have this problem too...
await Font.loadAsync({
Inter: require('@tamagui/font-inter/otf/Inter-Medium.otf'),
InterBold: require('@tamagui/font-inter/otf/Inter-Bold.otf'),
});
Just does not work on SDK 50 and all of my icons from @expo/vector-icons
are gone, instead, got this error:
Module "26" is missing from the asset registry
Platform: Web
I have the same problem, since switching to SDK 50, the icons from react-native-paper no longer work. The checkboxes don't even appear anymore. Also I added expo-font in the configuration file and it doesn't work either :/
[ "expo-font", { "fonts": [ "./assets/fonts/Poppins.ttf", "./assets/fonts/PoppinsBold.ttf" ] } ],
I think it is for both platforms (Android and iOS). I can't build Android release app because of that.
AssertionError [ERR_ASSERTION]: Assets must have hashed files. Ensure the expo-asset plugin is installed.
> Task :app:createBundleReleaseJsAndAssets FAILED
Execution failed for task ':app:createBundleReleaseJsAndAssets'.
> Process 'command 'node'' finished with non-zero exit value 1
EDIT: on Web/iOS/Android, when I see the @likeSo reply.
I am facing the same issue and getting Unable to resolve "missing-asset-registry-path" from "src/assets/fonts/Aeonik/Aeonik-Bold.ttf"
I'm having the same issue here: cannot load any custom font.
I tried using directly expo/vector-icons
, I tried loading custom font with expo-font
(tried both approaches seen here: https://docs.expo.dev/develop/user-interface/fonts/#use-a-custom-font).
Nothing worked, nothing is rendered on screen and I have the following error : Module "XX" is missing from the asset registry
I also had the same issue when I was on expo 49.
expo-env-info 1.2.0 environment info: System: OS: Linux 6.5 Ubuntu 22.04.3 LTS 22.04.3 LTS (Jammy Jellyfish) Shell: 5.1.16 - /bin/bash Binaries: Node: 14.21.3 - ~/.nvm/versions/node/v14.21.3/bin/node Yarn: 1.22.19 - /usr/bin/yarn npm: 6.14.18 - ~/.nvm/versions/node/v14.21.3/bin/npm npmPackages: expo: ^50.0.2 => 50.0.2 react: 18.2.0 => 18.2.0 react-native: 0.73.2 => 0.73.2 npmGlobalPackages: eas-cli: 7.0.0 Expo Workflow: managed
The cumbersome "workaround" I found is to use react-native-svg
to recreate the icon components I want to use with the help of https://reactsvgicons.com/
I think I get the same issue, after I upgraded to expo SDK 50 I get this error:
[Error: Module "1" is missing from the asset registry]
If I delete all fonts from the useFont hook (including expo vector Icons) it works, but then no symbols will be displayed. The module which is missing, changed in my case after I removed one of the fonts I used.
Before i upgraded to SDK 50 it worked in my case.
Error:
can someone please share a minimal reproducible example without using a monorepo?
While trying to create a minimal example, I created another expo app with fresh deps and custom font loading worked 😱 So I updated expo from 50.0.2 to 50.0.4 and @babel/core in my main project and it is now working
I update Expo but I have the same error.
I had this issue during SDK50 beta but I thought it was a compatibility problem. @myagoo do you just call font with useFont? For now, I try with useFont like on SDK49 and I add plugins config in app.config:
plugins: [
[
'expo-font',
{
fonts: [
'../core/src/assets/fonts/CircularBook.ttf',
'../core/src/assets/fonts/CircularMedium.ttf',
'../core/src/assets/fonts/CircularBold.ttf',
'../core/src/assets/fonts/Icons.ttf',
],
},
],
'expo-secure-store',
'expo-tracking-transparency',
],
But I don't know if I need to set both.
I only tried dynamic font loading with useFont.You dont need to the app.json part if you use useFont.
For me, a lot of things were not working : expo vector icons did not show up, sound loading did not properly work, custom font loading did not work.
But everything is new resolved since I updated all my dependencies to latest
While trying to create a minimal example, I created another expo app with fresh deps and custom font loading worked 😱 So I updated expo from 50.0.2 to 50.0.4 and @babel/core in my main project and it is now working
what version did you use for @babel/core?
I am using expo managed workflow and noticed that font are successfully getting copied but issue happens during metro bundler
ScreenShots
Metro Config
/**
* Metro configuration for React Native
* https://github.com/facebook/react-native
*
* @format
*/
const { getDefaultConfig } = require('expo/metro-config');
// extra config is needed to enable `react-native-svg-transformer`
module.exports = (async () => {
const {
resolver: { sourceExts, assetExts, resolverMainFields },
} = await getDefaultConfig(__dirname);
return {
transformer: {
babelTransformerPath: require.resolve('react-native-svg-transformer'),
assetPlugins: ['expo-asset/tools/hashAssetFiles'],
},
resolver: {
assetExts: assetExts.filter((ext) => ext !== 'svg'),
sourceExts: [...sourceExts, 'svg', 'd.ts'],
resolverMainFields: ['sbmodern', ...resolverMainFields],
},
};
})();
Any suggestions would be highly appreciated, Thanks in advance
@TomCorvus were you able to get any fix?
@Ankur-Magan No, I tried a few things, but it doesn't work. Can you give us a minimal repro of your environment? On my side, I can't reproduce it on a simple repo.
But it is very strange, if I set Icons font on Xcode, it is working but not with letters font.
I don't have any clue to find a solution. I don't know if it causes by react-native or expo.
I find this issue on react-native project (https://github.com/facebook/react-native/issues/42693) This user seems to get the same problem without Expo but he is not really precise in his description.
I keep trying to reproduce this problem.
I believe this problem happens only when UPGRADING the expo to SDK50. What did I do?
- vim
package.json
, editexpo
package from49.0.15
to50.0.2
or50.0.4
-
$ bun i
-
$ bun expo install --fix
- Remove
'expo-router/babel',
frombabel.config.js
-
$ bun expo start --web -c
, and an errorModule "22" is missing from the asset registry
appears!
But for a minimal reproducible example, I cannot create an old version of the expo!
SDK 49: No Error!
SDK 50: No Error!
SDK 49 -> SDK 50: Error!
My package.json
:
{
"name": "",
"main": "expo-router/entry",
"version": "1.0.0",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"test": "jest --watchAll"
},
"jest": {
"preset": "jest-expo"
},
"dependencies": {
"@expo/vector-icons": "^14.0.0",
"@react-native-async-storage/async-storage": "1.21.0",
"@react-navigation/native": "^6.0.2",
"@shopify/flash-list": "1.6.3",
"@tamagui/animations-react-native": "^1.84.1",
"@tamagui/babel-plugin": "^1.84.1",
"@tamagui/font-inter": "^1.84.1",
"@tamagui/react-native-media-driver": "^1.84.1",
"@tamagui/shorthands": "^1.84.1",
"@tamagui/themes": "^1.84.1",
"axios": "^1.6.5",
"expo": "~50.0.4",
"expo-font": "~11.10.2",
"expo-image": "~1.10.5",
"expo-image-picker": "~14.7.1",
"expo-linking": "~6.2.2",
"expo-router": "~3.4.6",
"expo-splash-screen": "~0.26.4",
"expo-status-bar": "~1.11.1",
"expo-system-ui": "~2.9.3",
"expo-web-browser": "~12.8.2",
"i18next": "^23.7.16",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-i18next": "^14.0.0",
"react-native": "0.73.2",
"react-native-gesture-handler": "~2.14.0",
"react-native-network-logger": "^1.15.0",
"react-native-reanimated": "~3.6.2",
"react-native-safe-area-context": "4.8.2",
"react-native-screens": "~3.29.0",
"react-native-web": "~0.19.6",
"react-native-webview": "13.6.4",
"tamagui": "^1.84.1"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@types/react": "~18.2.14",
"jest": "^29.2.1",
"jest-expo": "~50.0.1",
"prettier": "^3.1.1",
"react-test-renderer": "18.2.0",
"typescript": "^5.1.3"
},
"overrides": {
"react-refresh": "~0.14.0"
},
"resolutions": {
"react-refresh": "~0.14.0"
},
"private": true
}
My babel.config.js
:
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: [
[
"@tamagui/babel-plugin",
{
components: ["tamagui"],
config: "./tamagui.config.ts",
logTimings: true,
},
],
"react-native-reanimated/plugin"
],
};
};
+1
Kind of same. After upgrading to SDK 50, I get:
Error: Unable to resolve module missing-asset-registry-path from .../assets/fonts/MuseoSans_300.otf: missing-asset-registry-path could not be found within the project or in these directories: node_modules
1 | OTTO �0CFF ��� GPOS���+�#�GSUB���\�OS/2L� `cmap�e���4head��?��6hheay��$hmtx��h�� maxp�Pname��$u�4post��� �S"_<�����������.@s���j����@�P�,������2���@Jxljb ����� ���....
I have the same issue, I downgraded the @react-native/assets-registry
from 0.74
to 0.73
to work
I am able to recreate this issue with new expo app and here is the reproducible git repo for same:
https://github.com/MaganAnkur/expo-test
Issue happens when I added svg support in the code after adding metro.config.js and I added react-native-svg-transformer, app start giving
Issue 1: Asset must have hashed files, Ensure the expo-asset plugin is installed Note: expo-asset is already installed
Issue 2:
I modified the metro config a little bit and added assetPlugins: ['expo-asset/tools/hashAssetFiles']
it fixed the above issue but not it started giving:
Unable to resolve module missing-asset-registry-path
cc: @brentvatne
So far I have managed to build Android app in release and debug mode and fonts are loaded. Thanks to @Ankur-Magan, I followed steps on https://github.com/kristerkari/react-native-svg-transformer and modified my metro config by adding:
babelTransformerPath: require.resolve("react-native-svg-transformer")
and
assetExts: assetExts.filter((ext) => ext !== "svg"),
sourceExts: [...sourceExts, "svg"]
I also added:
yarn add -D @react-native/js-polyfills metro-config @react-native/metro-babel-transformer metro-runtime @react-native/metro-config react-native-svg-transformer
See: https://github.com/react-navigation/react-navigation/issues/11192#issuecomment-1916837933
After that, I had an error with ProGuard and R8. I needed to add in ProGuard rules:
-dontwarn javax.lang.model.element.Element
-dontwarn javax.lang.model.type.TypeMirror
-dontwarn javax.lang.model.type.TypeVisitor
-dontwarn javax.lang.model.util.SimpleTypeVisitor7
Despite all this, I had to add my fonts in android/app/src/main/assets/fonts
(See: https://github.com/unimonkiez/react-native-asset)
Now I see my custom fonts on release or debug (emulator) mode BUT I always this error [Error: Module "1" is missing from the asset registry]
according to useFont hook.
But it doesn't work on iOS.
Please don't follow these steps above to unblock your project in production mode. I have not testing if all of this is stable and it's specific to my project, but this may give you some ideas on how to resolve the issue.
While trying to create a minimal example, I created another expo app with fresh deps and custom font loading worked 😱 So I updated expo from 50.0.2 to 50.0.4 and @babel/core in my main project and it is now working
what version did you use for @babel/core?
After investigating the package-lock.json, it seems that I was already using the latest version of @babel/core 7.23.7. So the only thing that i did to fix my issue was to upgrade expo to 50.0.4
@TomCorvus @Ankur-Magan - the recommended approach to extend the babel transformer is this: https://docs.expo.dev/versions/latest/config/metro/#extending-the-babel-transformer
basically, create a file that exports a transform function, add your custom logic and then return a call to the expo babel transformer
does anyone want to take a stab at fixing this in the react-native-svg-transformer readme?
Thanks @brentvatne for taking look into this, but seems like in v1.3.0 react-native-svg-transformer
is already using @expo/metro-config/babel-transformer
here : https://github.com/kristerkari/react-native-svg-transformer/blob/c2f6c81c754ab8d586b50b457f80480ead3c1806/index.js#L14C21-L14C57
but despite that I tried extracting the code and only use @expo/metro-config/babel-transformer
metro.transformer.js
const { resolveConfig, transform } = require("@svgr/core");
const resolveConfigDir = require("path-dirname");
/**
* `metro-react-native-babel-transformer` has recently been migrated to the React Native
* repository and published under the `@react-native/metro-babel-transformer` name.
* The new package is default on `react-native` >= 0.73.0, so we need to conditionally load it.
*
* Additionally, Expo v50.0.0 has begun using @expo/metro-config/babel-transformer as its upstream transformer.
* To avoid breaking projects, we should prioritze that package if it is available.
*/
const upstreamTransformer = require('@expo/metro-config/babel-transformer');
const defaultSVGRConfig = {
native: true,
plugins: ["@svgr/plugin-svgo", "@svgr/plugin-jsx"],
svgoConfig: {
plugins: [
{
name: "preset-default",
params: {
overrides: {
inlineStyles: {
onlyMatchedOnce: false
},
removeViewBox: false,
removeUnknownsAndDefaults: false,
convertColors: false
}
}
}
]
}
};
module.exports.transform = async ({ src, filename, options }) => {
if (filename.endsWith(".svg")) {
const config = await resolveConfig(resolveConfigDir(filename));
const svgrConfig = config
? { ...defaultSVGRConfig, ...config }
: defaultSVGRConfig;
return upstreamTransformer.transform({
src: await transform(src, svgrConfig),
filename,
options
});
}
return upstreamTransformer.transform({ src, filename, options });
};
metro.config.js
/**
* Metro configuration
* https://facebook.github.io/metro/docs/configuration
*
* @type {import('metro-config').MetroConfig}
*/
const { getDefaultConfig } = require("expo/metro-config");
const defaultConfig = getDefaultConfig(__dirname);
const { assetExts, sourceExts } = defaultConfig.resolver;
const config = {
...defaultConfig,
transformer: {
babelTransformerPath: require.resolve("./metro.transformer.js"),
assetPlugins: ['expo-asset/tools/hashAssetFiles']
},
resolver: {
assetExts: assetExts.filter((ext) => ext !== "svg"),
sourceExts: [...sourceExts, "svg"]
}
};
module.exports = config
Issue still persist. Thanks in advance
ah i see. one potential issue i see there is that it is clobbering the resolver and the transformer. make sure you keep those values around from the original config:
const config = {
...defaultConfig,
transformer: {
...defaultConfig.transformer,
babelTransformerPath: require.resolve("./metro.transformer.js"),
},
resolver: {
...defaultConfig.resolver,
assetExts: assetExts.filter((ext) => ext !== "svg"),
sourceExts: [...sourceExts, "svg"]
}
};
notice that the react-native-svg-transformer docs correctly demonstrate this:
const { getDefaultConfig } = require("expo/metro-config");
module.exports = (() => {
const config = getDefaultConfig(__dirname);
const { transformer, resolver } = config;
config.transformer = {
...transformer,
babelTransformerPath: require.resolve("react-native-svg-transformer")
};
config.resolver = {
...resolver,
assetExts: resolver.assetExts.filter((ext) => ext !== "svg"),
sourceExts: [...resolver.sourceExts, "svg"]
};
return config;
})();
https://github.com/kristerkari/react-native-svg-transformer/tree/c2f6c81c754ab8d586b50b457f80480ead3c1806?tab=readme-ov-file#for-expo-sdk-v4100-or-newer
Thank you so much @brentvatne for your suggestion, it fixes the issue for me, Really appreciate your time and effort
good to hear @Ankur-Magan!
@TomCorvus - if you can create a minimal repro that doesn't use a monorepo that'd be appreciated. we currently still recommend yarn classic for monorepos (see this doc) but @byCedric has put in a bunch of work to improve out-of-the-box support in react-native for other pkg manager setups, it's just not quite there yet. you may have some success using other tools in the ecosystem to help make those monorepo tools work though.
@brentvatne Not needed. My metro config was a mess. I used https://github.com/microsoft/rnx-kit since SDK49 to get symlinks available with yarn and monorepo. I followed your message, took @byCedric monorepo metro config as example and cleaned my metro config. Fonts appear now on iOS and Android. Thanks a lot for your help.
I post my Metro config if it can help someone else. Monorepo, Turbo, SVG, Lottie, Storybook and some blacklisted modules not needed for my project.
// Learn more https://docs.expo.dev/guides/monorepos
const { getDefaultConfig } = require('expo/metro-config');
const { FileStore } = require('metro-cache');
const path = require('path');
const projectRoot = __dirname;
const workspaceRoot = path.resolve(projectRoot, '../..');
const config = getDefaultConfig(projectRoot);
const blacklistedModules = ['fs', 'ejs'];
config.transformer.getTransformOptions = async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
});
config.transformer.babelTransformerPath = require.resolve('react-native-svg-transformer');
config.watchFolders = [workspaceRoot];
config.resolver.disableHierarchicalLookup = true;
config.resolver.resolverMainFields = ['sbmodern', 'react-native', 'browser', 'main'];
config.resolver.nodeModulesPaths = [
path.resolve(projectRoot, 'node_modules'),
path.resolve(workspaceRoot, 'node_modules'),
];
config.resolver.resolveRequest = (context, moduleName, platform) => {
if (blacklistedModules.includes(moduleName)) {
return {
filePath: path.resolve(__dirname + '/shim-module.js'),
type: 'sourceFile',
};
}
// Optionally, chain to the standard Metro resolver.
return context.resolveRequest(context, moduleName, platform);
};
config.resolver.assetExts = [...config.resolver.assetExts.filter((ext) => ext !== 'svg'), 'lottie'];
config.resolver.sourceExts = [...config.resolver.sourceExts, 'svg'];
// Use turborepo to restore the cache when possible
config.cacheStores = [new FileStore({ root: path.join(projectRoot, 'node_modules', '.cache', 'metro') })];
module.exports = config;
@0xPT it was related to metro config, and what exactly you are facing, for fonts if you will refer to official documentation - https://docs.expo.dev/versions/latest/sdk/font/ it should be good
guys this is a big issue, i'm still have this issue. like your cases i did the upgrade from previous version of expo (45 in my case) to the 50, and i fixed a lot of issues in the meanwhile, but this about the Assets still here. in my case this is the first error i encontering when i launch the run:ios: node_modules/@expo-google-fonts/nunito/Nunito_500Medium.ttf: Assets must have hashed files. Ensure the expo-asset plugin is installed.
but if i commenting the part of my code about the fonts, i have the same issues but on expo-vectors.
please fix it @expo-bot
@DeabitTech - please read the thread, you are not configuring metro config correctly. also try running npx expo-doctor@latest
which will tell you the same. this page explains how to extend metro safely: https://docs.expo.dev/guides/customizing-metro/