-
Notifications
You must be signed in to change notification settings - Fork 634
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
Asset paths (httpServerLocation) invalid when asset is in watchFolders #290
Comments
Hi, Here's the repo to reproduce the issue: https://github.com/adrianha/metro-symlink/tree/0.57.2 - Assets path incorrect |
Thanks @adrianha, moving back to RN 0.57.1 (with metro 0.45.6) fixed this for me. Must be a regression in metro 46 or 47, and/or RN 0.57.2. |
@treyp how did you fix the issue can you share your rn-cli.config.js, i have not been able to get it working |
@ivan-jorge001 I generate my const path = require('path');
const extraNodeModules = {
'react': path.resolve(__dirname, 'node_modules/react'),
'react-native': path.resolve(__dirname, 'node_modules/react-native')
};
const blacklistRegexes = [
/[/\\]path[/\\]to[/\\]code[/\\]rn-component-one[/\\]node_modules[/\\]react-native[/\\].*/,
/[/\\]path[/\\]to[/\\]code[/\\]rn-component-two[/\\]node_modules[/\\]react-native[/\\].*/,
/[/\\]path[/\\]to[/\\]code[/\\]rn-component-three[/\\]node_modules[/\\]react-native[/\\].*/
];
const watchFolders = [
path.resolve('/path/to/code/rn-component-one'),
path.resolve('/path/to/code/rn-component-two'),
path.resolve('/path/to/code/rn-component-three')
];
module.exports = {
resolver: {
extraNodeModules,
blacklistRE: require('metro-config/src/defaults/blacklist')(blacklistRegexes)
},
watchFolders
}; My directory structure is:
|
I'm facing the same problem. I can't display local images if they are on my watchFolders. Here is my project stucture :
And here is my metro config, present in the native folder : module.exports = {
getTransformModulePath() {
return require.resolve("react-native-typescript-transformer");
},
getSourceExts() {
return ["ts", "tsx"];
},
resolver: {
extraNodeModules: {
react: path.resolve(__dirname, "node_modules/react"),
"react-native": path.resolve(__dirname, "node_modules/react-native")
}
},
projectRoot: path.resolve(__dirname),
watchFolders: [path.resolve(__dirname, "../shared")]
}; Do you see where is my problem here ? 😕 React-Native : 0.57.4 |
I bumped into this problem too! Currently as a workaround I did what suggested in #322. Also, for Androd I need the patch only in dev mode (using metro server) while for iOS I have to do the opposite (when I build the bundle). 😕 React-Native: 0.59.0 |
I created a simple repro for this using yarn workspaces: https://github.com/brentvatne/metro-issue-290 we're running into this in the expo monorepo, only solution for us for now is to use perhaps the path should be given a uri param? eg: |
Yep, I think changing the asset path to be given as a query param is the only way forward here. Brief recap for others:
Unless there's some way to configure More info was posted in #322 (comment) and a fix was supposed to be in 0eaa741 but looks like that didn't fully solve it. Unfortunately, the author @rafeca left Facebook earlier this year, so probably won't get much more attention from him. |
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 There is config 2)The second issue with Metro Server. It should resolve requests for I changed server: {
enhanceMiddleware: (middleware, server) => {
return (req, res, next) => {
if(req.url.startsWith("/assets/dir1/dir2/dir3")){
req.url = req.url.replace('/assets/dir1/dir2/dir3', '/assets');
}else if(req.url.startsWith("/assets/dir1/dir2")){
req.url = req.url.replace('/assets/dir1/dir2', '/assets/..');
}else if(req.url.startsWith("/assets/dir1")){
req.url = req.url.replace('/assets/dir1', '/assets/../..');
}else if(req.url.startsWith("/assets")){
req.url = req.url.replace('/assets', '/assets/../../..');
}
return middleware(req, res, next);
};
},
}, I want to notice here two more things: 1)This code doesn't use config value metro/packages/metro/src/Server.js Lines 306 to 307 in d9c556c
2)And another solution of this issue is to update code of assetUrlPath generation and replace For example, this line metro/packages/metro/src/Assets.js Lines 197 to 199 in d9c556c
may become: let assetUrlPath =path.join(publicPath, path.dirname(localPath).replace(/..\//g, '__/')); Also we should add reverse operation at Server module. I am currently using this config and it works with yarn workspaces as expected: module.exports = {
watchFolders: [path.resolve(__dirname, '../../../')],
server: {
enhanceMiddleware: (middleware, server) => {
return (req, res, next) => {
if(req.url.startsWith("/assets/dir1/dir2/dir3")){
req.url = req.url.replace('/assets/dir1/dir2/dir3', '/assets');
}else if(req.url.startsWith("/assets/dir1/dir2")){
req.url = req.url.replace('/assets/dir1/dir2', '/assets/..');
}else if(req.url.startsWith("/assets/dir1")){
req.url = req.url.replace('/assets/dir1', '/assets/../..');
}else if(req.url.startsWith("/assets")){
req.url = req.url.replace('/assets', '/assets/../../..');
}
return middleware(req, res, next);
};
},
},
transformer: {
publicPath: '/assets/dir1/dir2/dir3',
babelTransformerPath: path.resolve(
__dirname,
'./metro-transformer/index.js'
),
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
}),
},
}; I don't provide babelTransformer. Nothing interesting there. |
I'm having the same issue: iOS not showing watchFolder images only on release build - debug build works fine. |
@papigers I have found that I've got it working by making a small patch to Original:
New:
That's fixed it for me... is this something about the treatment of out-of-root paths that could be standardised? |
@papigers Actually, a nicer solution is to use an asset plugin. I created
Then in
|
@karlvr I think there are at least two issues with this solution.
You can check my note about it |
@vitramir thanks for your comment. My workflow has only just changed to include the asset plugin solution above, but so far it has worked for release builds of iOS and Android versions (ie. with the javascript bundled) and for debug builds of iOS and Android versions running in simulators (with Metro Bundler as a server). So at the moment I'm satisfied for my usage. Perhaps the asset plugin could be improve to collapse multiple Oh, one other thing I had to do. Sorry, this is important: I had to make a symlink named That way the Metro Bundler server could find my assets. I'm not sure about other possible collisions, but agree they could be a problem! |
Cool, now I understand how you made it work. If you have single directory with assets outside of your project’s root, then it is pretty simple solution. Do you have any idea how to make the solution more general and remove symlink? |
@vitramir sorry no I don't. I feel like this whole symlinking area is so off-label as far as Metro Bundler and jest haste or whatever it is that I'm just pleased when it works and isn't too complex! |
If you have a monorepo setup, and are experiencing issues resolving assets in |
Thanks @Ashoat , implementing that patch with patch-package worked perfectly for me. |
FYI, I abstracted @vitramir fix in a module that I'm using in a monorepo: You can use it this way: const {
getMetroAndroidAssetsResolutionFix,
} = require("@rnup/build-tools");
const androidAssetsResolutionFix = getMetroAndroidAssetsResolutionFix({
depth: 3,
});
module.exports = {
transformer: {
// Apply the Android assets resolution fix to the public path...
publicPath: androidAssetsResolutionFix.publicPath,
},
server: {
// ...and to the server middleware.
enhanceMiddleware: (middleware) => {
return androidAssetsResolutionFix.applyMiddleware(middleware);
},
}
}; Wondering if we could just default to a huge Edit: I also published it in |
Thank you @mmazzarolo !!! |
Thanks @vitramir & @mmazzarolo 🙏 FYI @mmazzarolo the link in your answer results in 404, it needs to be updated to this :) |
Thanks @mmazzarolo !!! You saved my day man :) |
@mmazzarolo did great work on this, but their repo hasn't been updated in a couple of years, and I noticed that |
There is metro-config from rnx-kit that provide metro config setup for monorepo (+ plugins): |
Do you have an abstract solution to share for the rewrite? |
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 viahttpServerLocation
is broken. For example,/symlinked-watch-folder/subdir/[email protected]
.If the current behavior is a bug, please provide the steps to reproduce and a minimal repository on GitHub that we can
yarn install
andyarn test
.symlinked-watch-folder
with a Node module in it namedsymlinked-module
.subdir/[email protected]
.<Image source={require('../subdir/image.png')} />
npm install ../symlinked-watch-folder
.What is the expected behavior?
It looks like there are different valid locations, including:
/assets/symlinked-module/subdir/[email protected]
/assets/subdir/[email protected]
/subdir/[email protected]
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 topath.join
these two paths:/assets
../symlinked-watch-folder/subdir/[email protected]
metro/packages/metro/src/Assets.js
Line 181 in bba48f0
The
../
wipes out the/assets
and we end up with a result that isn't valid:/symlinked-watch-folder/subdir/[email protected]
I believe the relative path is coming from here:
metro/packages/metro/src/DeltaBundler/Serializers/getAssets.js
Line 44 in bba48f0
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/[email protected]
/assets/subdir/[email protected]
/subdir/[email protected]
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
The text was updated successfully, but these errors were encountered: