Asset request for generic @2x/@3x path fails when package only has platform-specific assets (.ios.png / .android.png)
Summary
When a dependency (e.g. react-native-calendars) ships image assets only as platform-specific files (e.g. [email protected] and [email protected]) and no generic file (e.g. [email protected]), the Metro dev server returns 404 and throws:
Error: 'node_modules/react-native-calendars/src/calendar/img/[email protected]' could not be found, because it is not within the projectRoot or watchFolders, or it is blocked via the resolver.blockList config at getAsset (/path/to/node_modules/metro/src/Assets.js:226:13) at Server._processSingleAssetRequest (/path/to/node_modules/metro/src/Server.js:443:47)The same happens for [email protected]. Production/release builds work; the failure is development only (asset served by Metro on demand).
Environment
- React Native: 0.83.x
- Metro: 0.83.5 (likely 0.83.4+)
- Package: e.g.
[email protected](assets undernode_modules/.../src/calendar/img/)
Current behavior
- The app uses
require('../img/previous.png')from the dependency (or equivalent). - At runtime in dev, the client requests the asset by a path like
.../img/[email protected](generic density name, no platform suffix). - In
getAsset(), Metro usesfileExistsInFileMap(absolutePath)for that exact path. - On disk the package only has
[email protected]and[email protected], so[email protected]is not in the file map. - The check fails and Metro throws the error above instead of resolving to the platform-specific asset (e.g. via
getAbsoluteAssetRecord()/ platform resolution).
So the failure is due to validating the requested path (generic @2x.png) against the file map, instead of treating it as a base name and resolving to the platform-specific file that actually exists.
Expected behavior
When the requested path is a “logical” asset name (e.g. .../[email protected]) and the package only ships platform-specific files ([email protected], [email protected]), Metro should either:
- Resolve the requested path to the correct platform-specific asset before the
fileExistsInFileMapcheck, or - Allow the request when a corresponding platform-specific file exists for that base name,
so that dev server asset serving is consistent with how the bundler resolves platform-specific assets at build time.
Related
- Same pattern reported for
@react-navigation/elementsand[email protected]: #1667. - Affected package (example):
react-native-calendars– only has[email protected]/[email protected]and[email protected]/[email protected], no generic[email protected]/[email protected].
Source: wix/react-native-calendars