Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impossible to use @react-native/assets-registry with Next.js (turbo & webpack build) #48349

Open
MoOx opened this issue Dec 20, 2024 · 3 comments

Comments

@MoOx
Copy link
Contributor

MoOx commented Dec 20, 2024

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

  1. git clone https://github.com/MoOx/next.js-with-react-native-web
  2. cd next.js-with-react-native-web
  3. git checkout issue/rn-svg
  4. npm install
  5. 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 image
@react-native-bot
Copy link
Collaborator

Tip

Newer version available: You are on a supported minor version, but it looks like there's a newer patch available - 0.76.5. Please upgrade to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases.

@react-native-bot
Copy link
Collaborator

Tip

Newer version available: You are on a supported minor version, but it looks like there's a newer patch available - undefined. Please upgrade to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases.

@MoOx
Copy link
Contributor Author

MoOx commented Dec 20, 2024

Lockfile for the repro correctly use latest RN version with "@react-native/assets-registry": "0.76.5"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants