react / react/metro

Asset paths (httpServerLocation) invalid when asset is in watchFolders

Open
#290 26 comments 36 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
5.6k
Forks
696
Avg merge
8m
Merged PRs (30d)
7

Description

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
When I specify a directory in watchFolders from outside of my project root, the path reported via httpServerLocation is broken. For example, /symlinked-watch-folder/subdir/image@3x.png.

If the current behavior is a bug, please provide the steps to reproduce and a minimal repository on GitHub that we can yarn install and yarn test.

  1. Create a React Native project in one directory.
  2. Create a sibling directory called symlinked-watch-folder with a Node module in it named symlinked-module.
  3. Add assets to this module, specifically one in subdir/image@3x.png.
  4. In this module, reference the image like so: <Image source={require('../subdir/image.png')} />
  5. Now from the RN project directory, use npm to install the module: npm install ../symlinked-watch-folder.
  6. Make a component in your project root that displays the module's component with the image in it.
  7. Run the React Native project. The image will not appear and a request for the image will 404 because the path is invalid.

What is the expected behavior?
It looks like there are different valid locations, including:
/assets/symlinked-module/subdir/image@3x.png
/assets/subdir/image@3x.png
/subdir/image@3x.png

More info
Because this repo isn't very publicly documented, I can't tell exactly what's going on. But it looks like getAssetData is trying to path.join these two paths:
/assets
../symlinked-watch-folder/subdir/image@3x.png
https://github.com/facebook/metro/blob/bba48f068c6e709187d36170d3e5d49b7e9f6169/packages/metro/src/Assets.js#L181
The ../ wipes out the /assets and we end up with a result that isn't valid:
/symlinked-watch-folder/subdir/image@3x.png

I believe the relative path is coming from here:
https://github.com/facebook/metro/blob/bba48f068c6e709187d36170d3e5d49b7e9f6169/packages/metro/src/DeltaBundler/Serializers/getAssets.js#L44

The asset is being served correctly, it's just that the httpServerLocation that's being generated is not correct.
I can access the asset just fine if I correct the path to one of these:
/assets/symlinked-module/subdir/image@3x.png
/assets/subdir/image@3x.png
/subdir/image@3x.png

If there is some way to handle this using the documented options, please let me know. (cc: @rafeca )

Please provide your exact Metro configuration and mention your Metro, node, yarn/npm version and operating system.
I've tried both Metro 0.47.1 and Metro 0.48.0
Node: 10.11.0
npm: 6.4.1
OS: macOS High Sierra

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/metro/src/Assets.js, especially getAssetData and the httpServerLocation generation, then compare it with packages/metro/src/DeltaBundler/Serializers/getAssets.js. Reproduce the watchFolders case using the listed sibling-directory setup and verify the generated asset URL serves the image instead of returning 404.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react-native
Domain
build-system, mobile-dev, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.