Description
Description
When not using default RN build system (metro - which is the case when using React Native for Web without Expo), the build system can trigger a syntax error for some files with flow annotations.
Let's assume the following context:
- Next.js App
- React Native for Web
- React Native SVG
React Native SVG currently use @react-native/assets-registry
package.
This package is shipped as JS with flow annotation which make it impossible to build without adding stuff for Flow.
Could we imagine having this file (& maybe similar ones) to have a vanilla .js version ?
Note: sorry the reproducer doesn't follow the template since it's for a web issue (and Reproducer is just a standard iOS/android app)
Currently, I have patched (using patch-package) the problematic file by moving flow syntax code into flow comment as follow.
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict
* @format
*/
'use strict';
/*::
export type AssetDestPathResolver = 'android' | 'generic';
export type PackagerAsset = {
+__packager_asset: boolean,
+fileSystemLocation: string,
+httpServerLocation: string,
+width: ?number,
+height: ?number,
+scales: Array<number>,
+hash: string,
+name: string,
+type: string,
+resolver?: AssetDestPathResolver,
...
};
*/
const assets/*::: Array<PackagerAsset>*/ = [];
function registerAsset(asset/*::: PackagerAsset*/)/*::: number*/ {
// `push` returns new array length, so the first asset will
// get id 1 (not 0) to make the value truthy
return assets.push(asset);
}
function getAssetByID(assetId/*::: number*/)/*::: PackagerAsset*/ {
return assets[assetId - 1];
}
module.exports = {registerAsset, getAssetByID};
Just in case, current patch for this file
diff --git a/node_modules/@react-native/assets-registry/registry.js b/node_modules/@react-native/assets-registry/registry.js
index 64b2735..f218632 100644
--- a/node_modules/@react-native/assets-registry/registry.js
+++ b/node_modules/@react-native/assets-registry/registry.js
@@ -10,6 +10,7 @@
'use strict';
+/*::
export type AssetDestPathResolver = 'android' | 'generic';
export type PackagerAsset = {
@@ -25,16 +26,16 @@ export type PackagerAsset = {
+resolver?: AssetDestPathResolver,
...
};
+*/
+const assets/*::: Array<PackagerAsset>*/ = [];
-const assets: Array<PackagerAsset> = [];
-
-function registerAsset(asset: PackagerAsset): number {
+function registerAsset(asset/*::: PackagerAsset*/)/*::: number*/ {
// `push` returns new array length, so the first asset will
// get id 1 (not 0) to make the value truthy
return assets.push(asset);
}
-function getAssetByID(assetId: number): PackagerAsset {
+function getAssetByID(assetId/*::: number*/)/*::: PackagerAsset*/ {
return assets[assetId - 1];
}
I am not sure you will be open to move all this code to comment, but maybe we could find a way to have a flow js file + a vanilla js file for other builder that don't accept flow code by default ?
Steps to reproduce
git clone https://github.com/MoOx/next.js-with-react-native-web
cd next.js-with-react-native-web
git checkout issue/rn-svg
npm install
npm run dev
& open show url
React Native Version
0.76.5
Affected Platforms
Runtime - Web
Output of npx react-native info
(node:18109) [DEP0040] DeprecationWarning: The `punycode` module is depr(node:18109) [DEP0040] DeprecationWarning: The `punycode` module is depr(Use `node --trace-deprecation ...` to show where the warning was create(Use `node --trace-deprecation ...` to show where the warning was createinfo Fetching system and libraries information...
System:
OS: macOS 15.2
CPU: (10) arm64 Apple M1 Pro
Memory: 103.02 MB / 16.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 22.10.0
path: ~/.local/state/fnm_multishells/13980_1734684895281/bin/node
Yarn:
version: 1.22.19
path: ~/.yarn/bin/yarn
npm:
version: 10.9.0
path: ~/.local/state/fnm_multishells/13980_1734684895281/bin/npm
Watchman:
version: 2024.12.02.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods: Not Found
SDKs:
iOS SDK:
Platforms:
- DriverKit 24.2
- iOS 18.2
- macOS 15.2
- tvOS 18.2
- visionOS 2.2
- watchOS 11.2
Android SDK: Not Found
IDEs:
Android Studio: 2024.1 AI-241.18034.62.2411.12071903
Xcode:
version: 16.2/16C5032a
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.11
path: /usr/bin/javac
Ruby:
version: 2.6.10
path: /Users/moox/.rbenv/shims/ruby
npmPackages:
"@react-native-community/cli":
installed: 15.1.3
wanted: latest
react:
installed: 19.0.0
wanted: 19.0.0
react-native:
installed: 0.76.5
wanted: ^0.76.2
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: Not found
newArchEnabled: Not found
iOS:
hermesEnabled: Not found
newArchEnabled: Not found
Stacktrace or Logs
✓ Ready in 816ms
○ Compiling / ...
✓ Compiled / in 2.4s
⨯ ./node_modules/@react-native/assets-registry/registry.js:13:13
Parsing ecmascript source code failed
11 | 'use strict';
12 |
> 13 | export type AssetDestPathResolver = 'android' | 'generic';
| ^^^^^^^^^^^^^^^^^^^^^
14 |
15 | export type PackagerAsset = {
16 | +__packager_asset: boolean,
Expected ',', got 'AssetDestPathResolver'
./node_modules/react-native-svg/lib/module/lib/resolveAssetUri.js:3:1
Export getAssetByID doesn't exist in target module
1 | import { PixelRatio } from 'react-native';
2 | // @ts-expect-error react-native/assets-registry doesn't export types.
> 3 | import { getAssetByID } from '@react-native/assets-registry/registry';
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 | const svgDataUriPattern = /^(data:image\/svg\+xml;utf8,)(.*)/;
5 |
6 | // Based on that function: https://github.com/necolas/react-native-web/blob/54c14d64dabd175e8055e1dc92e9196c821f9b7d/packages/react-native-web/src/exports/Image/index.js#L118-L156
The export getAssetByID was not found in module [project]/node_modules/@react-native/assets-registry/registry.js [app-client] (ecmascript).
The module has no exports at all.
All exports of the module are statically known (It doesn't have dynamic exports). So it's known statically that the requested export doesn't exist.
./node_modules/react-native-svg/lib/module/lib/resolveAssetUri.js:3:1
Export getAssetByID doesn't exist in target module
1 | import { PixelRatio } from 'react-native';
2 | // @ts-expect-error react-native/assets-registry doesn't export types.
> 3 | import { getAssetByID } from '@react-native/assets-registry/registry';
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 | const svgDataUriPattern = /^(data:image\/svg\+xml;utf8,)(.*)/;
5 |
6 | // Based on that function: https://github.com/necolas/react-native-web/blob/54c14d64dabd175e8055e1dc92e9196c821f9b7d/packages/react-native-web/src/exports/Image/index.js#L118-L156
The export getAssetByID was not found in module [project]/node_modules/@react-native/assets-registry/registry.js [app-ssr] (ecmascript).
The module has no exports at all.
All exports of the module are statically known (It doesn't have dynamic exports). So it's known statically that the requested export doesn't exist.
○ Compiling /_error ...
✓ Compiled /_error in 611ms
GET / 500 in 3096ms
Reproducer
https://github.com/MoOx/next.js-with-react-native-web
Screenshots and Videos
![image](https://private-user-images.githubusercontent.com/157534/397675654-1c732a36-d8ea-4e58-b8aa-0f4249beb12e.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzg5MzE1OTEsIm5iZiI6MTczODkzMTI5MSwicGF0aCI6Ii8xNTc1MzQvMzk3Njc1NjU0LTFjNzMyYTM2LWQ4ZWEtNGU1OC1iOGFhLTBmNDI0OWJlYjEyZS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjA3JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIwN1QxMjI4MTFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0yZDgxNmY2YzhmYzIzOTk4MWM1Y2RiMzIxZGI2NDI4M2MxZGQxNmNlODRmNzBkNzFhYWNiNTQ0NWJhZGY3MjU4JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.Lv-2G8Ul1OmUYqtba-8d_laqC-6cI-5yd8h3gujf77s)
![image](https://private-user-images.githubusercontent.com/157534/397679135-59bd0a68-1abb-471c-a813-14a3262d09eb.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzg5MzE1OTEsIm5iZiI6MTczODkzMTI5MSwicGF0aCI6Ii8xNTc1MzQvMzk3Njc5MTM1LTU5YmQwYTY4LTFhYmItNDcxYy1hODEzLTE0YTMyNjJkMDllYi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjA3JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIwN1QxMjI4MTFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT00OWZjYWUwN2NhYTY5NDM0NTk3ODc5YjdjNTlmZGQ5MjY0ZjAxMDAxODNjMzRmNWU1OWQ4MjE0NjdmNzI3Y2M5JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.zmN0wDMyO5RqTZmBI9PadpPSqVDGOLa1JvAPZF1CBg4)