Skip to content

Instantly share code, notes, and snippets.

@huntie
Last active July 10, 2023 01:53
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save huntie/85ea491763b444bfa1bdc8e997fc2765 to your computer and use it in GitHub Desktop.
Save huntie/85ea491763b444bfa1bdc8e997fc2765 to your computer and use it in GitHub Desktop.
Snippets accompanying my article "A concise guide to configuring React Native with Yarn Workspaces" on Medium
/**
* Metro Bundler configuration
* https://facebook.github.io/metro/docs/en/configuration
*
* eslint-env node, es6
*/
const exclusionList = require('metro-config/src/defaults/exclusionList');
const getWorkspaces = require('get-yarn-workspaces');
const path = require('path');
function getConfig(appDir, options = {}) {
const workspaces = getWorkspaces(appDir);
// Add additional Yarn workspace package roots to the module map
// https://bit.ly/2LHHTP0
const watchFolders = [
path.resolve(appDir, '..', 'node_modules'),
...workspaces.filter(
workspaceDir => !(workspaceDir === appDir),
),
];
return {
watchFolders,
resolver: {
blockList: exclusionList([
// Ignore other resolved react-native installations outside of
// myapp-native - this prevents a module naming collision when mapped.
/^((?!myapp-native).)+[\/\\]node_modules[/\\]react-native[/\\].*/,
// Ignore react-native-svg dependency in myapp-ui, mapped below.
// react-native-svg must only be included once due to a side-effect. It
// has not been hoisted as it requires native module linking here.
// http://bit.ly/2LJ7V4b
/myapp-ui[\/\\]node_modules[/\\]react-native-svg[/\\].*/,
]),
extraNodeModules: {
// Resolve all react-native module imports to the locally-installed version
'react-native': path.resolve(appDir, 'node_modules', 'react-native'),
// Resolve additional nohoist modules depended on by other packages
'react-native-svg': path.resolve(
appDir,
'node_modules',
'react-native-svg',
),
// Resolve core-js imports to the locally installed version
'core-js': path.resolve(appDir, 'node_modules', 'core-js'),
},
},
};
}
module.exports = getConfig(__dirname);
{
"name": "myapp-native",
"version": "1.0.0",
"private": true,
"scripts": {
"postinstall": "jetify",
"start": "react-native start",
"android": "react-native run-android",
"ios": "react-native run-ios",
"pods": "cd ios; pod install"
},
"workspaces": {
"nohoist": [
"@react-native-community/async-storage",
"react-native",
"react-native/**",
"react-native-dev-menu",
"react-native-svg",
"jetifier"
]
},
"dependencies": {
"@react-native-community/async-storage": "^1.6.1",
"myapp-settings": "1.0.0",
"myapp-ui": "1.0.0",
"react": "16.9.0",
"react-native": "0.61.5",
"react-native-dev-menu": "^4.0.0",
"react-native-svg": "^9.12.0"
},
"devDependencies": {
"get-yarn-workspaces": "^1.0.2",
"metro-config": "^0.56.0"
}
}
@AdamGerthel
Copy link

@huntie ok, so that's good because that means that I've understood it correctly :) The thing I'm not entirely getting is the structure of the regex and how to apply it in my project.

Line 30 works in my project, but line 36 doesn't. I'm still getting the Invariant Violation: Tried to register two views with the same name RNSVGSvgView error, meaning that I'm probably getting the regex for my folder structure wrong since it's apparently importing react-native-svg twice. So, for clarity, what would the equivalent of /myapp-ui[\/\\]node_modules[/\\]react-native-svg[/\\].*/ be in the folder structure example I listed in my previous comment? I would assume that this would work:

/libs[\/\\]icons[\/\\]node_modules[/\\]react-native-svg[/\\].*/

But I haven't be able to get working. I feel like I've tried every regex I can think of but nothing seems to exclude it. I've even tried absolute paths. I'm also not sure how (if) I can debug it other than: Reset metro cache, rebuild and hope for the best :D

Any ideas? The name of the package is not the same as the name of the folder, but that shouldn't matter since it's asking for a path, right?

@huntie
Copy link
Author

huntie commented Nov 23, 2020

@AdamGerthel That regex looks right to me - another thing you might want to check is whether there is a react-native-svg conflict between app-one/ and app-two/ (your versions), plus whether there is a duplicate react-native-svg installation within dependencies app-one/.

Hopefully you can find from the debug output from what workspace the invariant violation is triggered.

@steveluscher
Copy link

steveluscher commented Jun 29, 2022

This needs updating for the new metro-config/src/defaults/exclusionList module and the blocklist property in Metro's config.

@huntie
Copy link
Author

huntie commented Jun 30, 2022

Thanks for pointing this out @steveluscher, now updated. Funnily enough I now work on Metro 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment