Described how to bundle asset automatically at bundle time, and one function to copy asset to file system or read asset as base64 data url on Android, iOS and Web at debug or release run time.
npm install react-native-get-asset
Note: peerDependencies
are expo-asset
and react-native-fs
.
Use environment.dds
as an example, it's very simple to bundle environment.dds
file into APP as an asset automatically at bundle time:
- add
'dds'
inmetro.config.js
e.g. https://github.com/flyskywhy/GCanvasRNExamples/blob/master/metro.config.js - move file as
APP/public/textures/environment.dds
require('../public/textures/environment.dds')
inAPP/src/SomeComponent.js
Cause appHtml: resolveApp('public/index.html')
in node_modules/react-scripts/config/paths.js
which works with react-native-web and react-app-rewired, so it's better to put assets files into APP/public/
thus Web can use them too, that's why e.g. src: Platform.OS !== 'web' ? require('../public/textures/environment.dds') : 'textures/environment.dds'
below.
PS: The usage of react-app-rewired
can ref to my blog.
e.g. you can modify
const MODEL_URL =
'https://github.com/facebookresearch/playtorch/releases/download/v0.2.0/yolov5s.ptl';
...
const filePath = await MobileModel.download(MODEL_URL);
into
import GetAsset from 'react-native-get-asset';
...
const MODEL_URL =
Platform.OS !== 'web'
? require('../../public/pytorch/yolov5s.ptl')
: 'pytorch/yolov5s.ptl';
...
const filePath = await GetAsset.downloadUrlOrRequireId2Storage({
src: MODEL_URL,
dst:
Platform.OS !== 'web' &&
Platform.select({
android: `${RNFS.ExternalDirectoryPath}/detectObjects.ptl`,
ios: `${RNFS.DocumentDirectoryPath}/detectObjects.ptl`,
}),
iosReleaseRequireIdAvoidCopy: true, // default is false
});
Unlike asset on Android zipped in release.apk so must unzip copy, asset on iOS release is in bundle folder so that can avoid copy to access it directly, so can iosReleaseRequireIdAvoidCopy: true
here.
PS: If react-native-get-asset
does not satisfy your APP situation, you can try react-native-filereader or react-native-blob-util.
e.g. https://github.com/flyskywhy/GCanvasRNExamples/blob/master/src/nonDeclarative.js:
import GetAsset from 'react-native-get-asset';
...
const url = await GetAsset.downloadUrlOrRequireId2DataURL({
// src: 'https://raw.githubusercontent.com/brianzinn/react-babylonjs/v3.1.3/packages/storybook/storyboard-site/assets/textures/environment.dds';
src: Platform.OS !== 'web' ? require('../public/textures/environment.dds') : 'textures/environment.dds',
urlAvoidDataURL: true, // default is false
});
If your other code can deal with http url, you can urlAvoidDataURL: true
here to return url instead of data url.
PS: data-uri.macro can convert files to data-uris at bundle time to avoid these asset matter.
To support my work, please consider donate.