Asset paths (httpServerLocation) invalid when asset is in watchFolders
See original GitHub issueDo 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
.
- Create a React Native project in one directory.
- Create a sibling directory called
symlinked-watch-folder
with a Node module in it namedsymlinked-module
. - Add assets to this module, specifically one in
subdir/image@3x.png
. - In this module, reference the image like so:
<Image source={require('../subdir/image.png')} />
- Now from the RN project directory, use npm to install the module:
npm install ../symlinked-watch-folder
. - Make a component in your project root that displays the module’s component with the image in it.
- 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
Issue Analytics
- State:
- Created 5 years ago
- Reactions:28
- Comments:22 (1 by maintainers)
Top GitHub Comments
FYI, I abstracted @vitramir fix in a module that I’m using in a monorepo:
get-metro-android-assets-resolution-fix.js
.You can use it this way:
Wondering if we could just default to a huge
depth
(e.g. 20) without drawbacks.Edit: I also published it in
react-native-monorepo-tools
.I got this issue while using yarn workspaces and here is how I solved it:
1)Our first issue is resources destination path outside of
/assets
directory. It breaks both debug server and bundle.There is config
transformer.publicPath
which default value is/assets
. So, I changed it to/assets/dir1/dir2/dir3
(because my watchDir is ‘…/…/…/’). Now it will generate valid destination path for resources outside of projectRoot. For example/assets/dir1/dir2/dir3/../../common/images/image.png
.react-native bundle
will work too.2)The second issue with Metro Server. It should resolve requests for IOS (
http://localhost:8081/assets/dir1/dir2/dir3/../../common/images/image.png
) and Android (http://localhost:8081/assets/dir1/common/images/image.png
) the same way.I changed
server.enhanceMiddleware
config this way:I want to notice here two more things:
1)This code doesn’t use config value
transformer.publicPath
. I think it is wrong. https://github.com/facebook/metro/blob/d9c556c04dc863b334720ab7eed9c94bc2841995/packages/metro/src/Server.js#L306-L3072)And another solution of this issue is to update code of assetUrlPath generation and replace
../
into something like__/
or_.._/
.For example, this line https://github.com/facebook/metro/blob/d9c556c04dc863b334720ab7eed9c94bc2841995/packages/metro/src/Assets.js#L197-L199 may become:
Also we should add reverse operation at Server module. I can make PR with this changes if community approve the idea.
I am currently using this config and it works with yarn workspaces as expected:
I don’t provide babelTransformer. Nothing interesting there.