-
Notifications
You must be signed in to change notification settings - Fork 905
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
Default metro.config.js should be configured to support symbol links to packages #1238
Comments
Thanks for this, it helps us to manage a bigger codebase where we use a lot of symlinks caused by multirepos. But we had a problem the symlinks where not considered even with your metro.config.js. The problem is, you use |
Thanks @Braincompiler for sharing back your findings! I read the link you shared and it certainly sounds like Also, I tested it out with |
We debugged the metro bundler start and found out that Our directory structure looks like:
The only problem we now have: In case we change something in one of the linked modules, the app reloads but is not rebundled. Thus we have to restart the bundler |
That's really interesting, I don't think we see any of those issues. We have exactly the same directory structure as you describe above and no issues with the link resolution even with |
Do you use Mac Books? We have currently Mid 2015 Mac Books, could this be a problem? I don't think so. The refresh works (at least the app is reloading (fast)) but the changes we made in one of the dependent modules are not there. We have to exit the bundler and start it again. But this takes a lot of time, obviously. |
Yes we use both Mac and Windows. We did have an issue at one point kind of like what you are describing, but for us if we saved the top level App.js it would refresh as expected. However this stopped reproing before we had a chance to investigate so we assumed it was fixed by a React Native update. |
Since you said you saved the "App.js", means you don't use Typescript? We use Typescript (formerly the cli generated typescript project with babel, now we use a custom build step using tsc so we can use tsconfig and better typechecking support). So maybe the problem is indicated due to the extra transpile step? But the changes were never built in even after manual refresh ( |
We use TypeScript + Babel, I just said App.js to keep things simple. In reality it is App.tsx for us. What version of React Native and the CLI tools are you using? I’m not sure what other tools come into play here... node, watchman, other? |
We use always the latest versions for all the tools and clis you named. Currently we don't use symlinks anymore because the problems with the bundler were too hard to work with. But hopefully there will be a solution for this provided by the metro bundler itself. I cannot imagine Facebook is not using symlinks or similar in there big dev environments. |
Thanks for your solution 👍 |
We found that in cases where you sym link to a package that has |
Thanks for this @ryantrem ! I've been searching for a way to do this for many weeks.
And in fact, it's looking for files in the linked path:
It compiles ok, but when I try to open the app I get the following error:
When open the symlink path, the package is there. |
It looks like you are trying to use this with What is |
Hi @ryantrem and thanks for sharing your solution. I've been trying to link modules with msw, and haul, now I am trying your ultimate solution which is the closest to the desired result. One thing that still doesn't work is the hot reload, despite that I reload the app with This forced me to do the following in order to get the updated sources:
I've tried to update the configuration without success: watchFolders: [
...Object.values(moduleMappings),
+ join(__dirname, 'node_modules', '@pass-culture', 'id-check', 'src'),
], Do you have a clue why I can't get the hot reload on that folder? This is what I have in ['/home/dka/.config/yarn/link/@pass-culture/id-check'] This is what I have when I run watchman watch-list
{
"version": "20210124.162314.0",
"roots": [
"/home/dka/workspace/github.com/pass-culture/id-check-front/packages/id-check",
"/home/dka/workspace/github.com/pass-culture/pass-culture-app-native"
]
} Thanks a lot for this solution, I wonder why this is not the default if it can work well. |
@kopax-polyconseil that sounds similar to the issue @Braincompiler was hitting. I've not run into this problem before, so I'm not sure why others do. You can check out our OSS project where we use this configuration and see if it works for you there, and if so, maybe you can find the difference between your repo and ours. https://github.com/babylonjs/babylonreactnative |
Thanks for sharing the link, I had a look and it look equal. That's our |
This is magic! Thank you @ryantrem - was able to integrate this immediately into an example app from |
I found that with NPM 7+, if you |
New metro.config.js to support metro-config v0.66.2 const path = require('path');
const exclusionList = require('metro-config/src/defaults/exclusionList');
const escape = require('escape-string-regexp');
const pak = require('../package.json');
const root = path.resolve(__dirname, '..');
const modules = Object.keys({
...pak.peerDependencies,
});
module.exports = {
projectRoot: __dirname,
watchFolders: [root],
resolver: {
blockList: exclusionList(
modules.map(
m => new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`),
),
),
extraNodeModules: modules.reduce((acc, name) => {
acc[name] = path.join(__dirname, 'node_modules', name);
return acc;
}, {}),
},
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
}; |
@ryantrem Your solution works for me, but I faced an Invariant Violation problem, in the lib I'm building it has some dependencies like:
These dependencies are also present in the application that will use this lib, so the error occurs, for example: Invariant Violation: Tried to register two views with the same name BVLinearGradient If I generate a build of the lib, and send it to NPM and install it in the app, it works normally, is there any solution so that I can use these libs in the development environment? I tried to replace: const appendExclusions = require('metro-config/src/defaults/blacklist'); per: const exclusionList = require('metro-config/src/defaults/exclusionList');
const escape = require('escape-string-regexp'); And I added this in the resolver: blockList: exclusionList(
['@react-native-community/slider', 'react-native-linear-gradient'].map(
m => new RegExp(`^${escape(path.join(path.resolve(__dirname), 'node_modules/MY_LIB_HERE/node_modules', m))}\\/.*$`),
),
), I thought that this would block these packages from my lib, thus keeping the ones that exist in the app, but it didn't work. |
There hasn't been any activity on this issue in the past 3 months, so it has been marked as stale and it will be closed automatically if no further activity occurs in the next 7 days. |
Describe the Feature
npm install <path to local package>
creates a symbolic link to the package directory. This is useful for monorepos as well as iterating on a package in the context of the consuming app. Unfortunately, the Metro bundler does not support this out of the box (see facebook/metro#1). It is possible though to configure the Metro bundler (viametro.config.js
) to make it work with symbolically linked packages. It would be extremely helpful ifreact-native init MyApp
provided ametro.config.js
that made symbolically linked packages work by default.Possible Implementations
There are many work arounds proposed in facebook/metro#1. All of them had problems for me. My solution (used in multiple projects) is to modify
metro.config.js
to manually follow symbolic links:Related Issues
facebook/metro#1
The text was updated successfully, but these errors were encountered: