Skip to content

Commit

Permalink
fix(samples): Share monorepo config, remove broken promises resolve, …
Browse files Browse the repository at this point in the history
…add react to blocked packages (#4494)
  • Loading branch information
krystofwoldrich authored Jan 31, 2025
1 parent 40c35c5 commit d997097
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 189 deletions.
1 change: 1 addition & 0 deletions dev-packages/utils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = {};
62 changes: 62 additions & 0 deletions dev-packages/utils/metro.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const path = require('path');
const exclusionList = require('metro-config/src/defaults/exclusionList');

/**
* Packages used by the sample apps
*/
const getMonorepoPackages = monorepoRoot => {
return {
'@sentry/react-native': path.resolve(monorepoRoot, 'packages/core'),
};
};

/**
* Block given packages present in the monorepo packages to avoid conflicts with the sample apps
*/
const getBlockList = (monorepoPackages, excludedPackages) => {
return Object.values(monorepoPackages)
.map(p => excludedPackages.map(e => new RegExp(`${p}/node_modules/${e}/.*`)))
.flat();
};

const withMonorepo = config => {
const projectRoot = config.projectRoot;
if (!projectRoot) {
throw new Error('projectRoot is required');
}

const monorepoRoot = path.resolve(projectRoot, '../..');
const monorepoPackages = getMonorepoPackages(monorepoRoot);

config.resolver = config.resolver || {};

const blockList = [
...((Array.isArray(config.resolver.blockList) && config.resolver.blockList) ||
(!!config.resolver.blockList && [config.resolver.blockList]) ||
[]),
...getBlockList(monorepoPackages, ['react-native', 'react']),
new RegExp('.*\\android\\.*'), // Required for Windows in order to run the Sample.
];
config.resolver.blockList = exclusionList(blockList);

config.watchFolders = [...(config.watchFolders || []), projectRoot, ...Object.values(monorepoPackages)];

config.resolver.extraNodeModules = {
...config.resolver.extraNodeModules,
...monorepoPackages,
'react-native': path.resolve(projectRoot, 'node_modules/react-native'),
react: path.resolve(projectRoot, 'node_modules/react'),
};

config.resolver.nodeModulesPaths = [
...(config.resolver.nodeModulesPaths || []),
path.resolve(projectRoot, 'node_modules'),
...Object.values(monorepoPackages).map(p => path.resolve(p, 'node_modules')),
];

return config;
};

module.exports = {
withMonorepo,
};
11 changes: 11 additions & 0 deletions dev-packages/utils/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "sentry-react-native-samples-utils",
"version": "0.0.1",
"description": "Internal Samples Utils",
"main": "index.js",
"license": "MIT",
"private": true,
"dependencies": {
"metro-config": "^0.81.0"
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"packages/core",
"dev-packages/e2e-tests",
"dev-packages/type-check",
"dev-packages/utils",
"samples/react-native",
"samples/react-native-macos",
"samples/expo",
Expand Down
37 changes: 3 additions & 34 deletions performance-tests/TestAppSentry/metro.config.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,12 @@
const path = require('path');
const exclusionList = require('metro-config/src/defaults/exclusionList');

const projectRoot = __dirname;
const monorepoRoot = path.resolve(projectRoot, '../..');

// Only list the packages within your monorepo that your app uses. No need to add anything else.
// If your monorepo tooling can give you the list of monorepo workspaces linked
// in your app workspace, you can automate this list instead of hardcoding them.
const monorepoPackages = {
'@sentry/react-native': path.resolve(monorepoRoot, 'packages/core'),
};
const { withMonorepo } = require('sentry-react-native-samples-utils/metro');

/**
* Metro configuration for React Native
* https://github.com/facebook/react-native
*
* @format
*/
module.exports = {
module.exports = withMonorepo({
transformer: {
getTransformOptions: async () => ({
transform: {
Expand All @@ -27,24 +16,4 @@ module.exports = {
}),
},
projectRoot: __dirname,
// 1. Watch the local app directory, and only the shared packages (limiting the scope and speeding it up)
// Note how we change this from `monorepoRoot` to `projectRoot`. This is part of the optimization!
watchFolders: [projectRoot, ...Object.values(monorepoPackages)],
resolver: {
blockList: exclusionList([
...Object.values(monorepoPackages).map(p => new RegExp(`${p}/node_modules/react-native/.*`)),
]),
// Add the monorepo workspaces as `extraNodeModules` to Metro.
// If your monorepo tooling creates workspace symlinks in the `node_modules` directory,
// you can either add symlink support to Metro or set the `extraNodeModules` to avoid the symlinks.
// See: https://metrobundler.dev/docs/configuration/#extranodemodules
extraNodeModules: {
...monorepoPackages,
'react-native': path.resolve(projectRoot, 'node_modules/react-native'),
},
nodeModulesPaths: [
path.resolve(projectRoot, 'node_modules'),
...Object.values(monorepoPackages).map(p => path.resolve(p, 'node_modules')),
],
},
};
});
3 changes: 2 additions & 1 deletion performance-tests/TestAppSentry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"devDependencies": {
"@babel/core": "^7.12.9",
"@babel/runtime": "^7.12.5",
"metro-react-native-babel-preset": "^0.72.3"
"metro-react-native-babel-preset": "^0.72.3",
"sentry-react-native-samples-utils": "workspace:^"
},
"jest": {
"preset": "react-native"
Expand Down
42 changes: 3 additions & 39 deletions samples/expo/metro.config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('@expo/metro-config');
const path = require('path');

const { getSentryExpoConfig } = require('@sentry/react-native/metro');

const { withMonorepo } = require('sentry-react-native-samples-utils/metro');

/** @type {import('expo/metro-config').MetroConfig} */
const config = getSentryExpoConfig(__dirname, {
// [Web-only]: Enables CSS support in Metro.
Expand All @@ -12,40 +12,4 @@ const config = getSentryExpoConfig(__dirname, {
annotateReactComponents: true,
});

const projectRoot = __dirname;
const monorepoRoot = path.resolve(projectRoot, '../..');

// Only list the packages within your monorepo that your app uses. No need to add anything else.
// If your monorepo tooling can give you the list of monorepo workspaces linked
// in your app workspace, you can automate this list instead of hardcoding them.
const monorepoPackages = {
'@sentry/react-native': path.resolve(monorepoRoot, 'packages/core'),
};

const exclusionList = [...Object.values(monorepoPackages).map(p => new RegExp(`${p}/node_modules/react-native/.*`))];

if (config.resolver.blacklistRE) {
config.resolver.blacklistRE.push(...exclusionList);
} else {
config.resolver.blacklistRE = exclusionList;
}

// 1. Watch the local app directory, and only the shared packages (limiting the scope and speeding it up)
// Note how we change this from `monorepoRoot` to `projectRoot`. This is part of the optimization!
config.watchFolders = [projectRoot, ...Object.values(monorepoPackages)];

// Add the monorepo workspaces as `extraNodeModules` to Metro.
// If your monorepo tooling creates workspace symlinks in the `node_modules` directory,
// you can either add symlink support to Metro or set the `extraNodeModules` to avoid the symlinks.
// See: https://metrobundler.dev/docs/configuration/#extranodemodules
config.resolver.extraNodeModules = {
...monorepoPackages,
'react-native': path.resolve(projectRoot, 'node_modules/react-native'),
};

config.resolver.nodeModulesPaths = [
path.resolve(projectRoot, 'node_modules'),
...Object.values(monorepoPackages).map(p => path.resolve(p, 'node_modules')),
];

module.exports = config;
module.exports = withMonorepo(config);
3 changes: 2 additions & 1 deletion samples/expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
"@babel/core": "^7.26.0",
"@babel/preset-env": "^7.26.0",
"@sentry/babel-plugin-component-annotate": "^2.18.0",
"@types/node": "20.10.4"
"@types/node": "20.10.4",
"sentry-react-native-samples-utils": "workspace:^"
},
"overrides": {
"react-refresh": "~0.14.0"
Expand Down
64 changes: 7 additions & 57 deletions samples/react-native-macos/metro.config.js
Original file line number Diff line number Diff line change
@@ -1,70 +1,20 @@
const path = require('path');
const { withSentryConfig } = require('@sentry/react-native/metro');
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const exclusionList = require('metro-config/src/defaults/exclusionList');

const projectRoot = __dirname;
const monorepoRoot = path.resolve(projectRoot, '../..');

// Only list the packages within your monorepo that your app uses. No need to add anything else.
// If your monorepo tooling can give you the list of monorepo workspaces linked
// in your app workspace, you can automate this list instead of hardcoding them.
const monorepoPackages = {
'@sentry/react-native': path.resolve(monorepoRoot, 'packages/core'),
};
const { withMonorepo } = require('sentry-react-native-samples-utils/metro');

/**
* Metro configuration
* https://facebook.github.io/metro/docs/configuration
*
* @type {import('metro-config').MetroConfig}
*/
const config = {
projectRoot: __dirname,
// 1. Watch the local app directory, and only the shared packages (limiting the scope and speeding it up)
// Note how we change this from `monorepoRoot` to `projectRoot`. This is part of the optimization!
watchFolders: [projectRoot, ...Object.values(monorepoPackages)],
resolver: {
resolverMainFields: ['react-native', 'main'],
resolveRequest: (context, moduleName, platform) => {
if (moduleName.includes('promise/')) {
return context.resolveRequest(
{
...context,
// Ensures the promise module is resolved from the sample's node_modules.
allowHaste: false,
disableHierarchicalLookup: true,
},
moduleName,
platform,
);
}
return context.resolveRequest(context, moduleName, platform);
},
blockList: exclusionList([
new RegExp('.*\\android\\.*'), // Required for Windows in order to run the Sample.
...Object.values(monorepoPackages).map(
p => new RegExp(`${p}/node_modules/react-native/.*`),
),
]),
// Add the monorepo workspaces as `extraNodeModules` to Metro.
// If your monorepo tooling creates workspace symlinks in the `node_modules` directory,
// you can either add symlink support to Metro or set the `extraNodeModules` to avoid the symlinks.
// See: https://metrobundler.dev/docs/configuration/#extranodemodules
extraNodeModules: {
...monorepoPackages,
'react-native': path.resolve(projectRoot, 'node_modules/react-native'),
},
nodeModulesPaths: [
path.resolve(projectRoot, 'node_modules'),
...Object.values(monorepoPackages).map(p =>
path.resolve(p, 'node_modules'),
),
],
},
};
const config = {};

const mergedConfig = mergeConfig(getDefaultConfig(__dirname), config);

const m = mergeConfig(getDefaultConfig(__dirname), config);
module.exports = withSentryConfig(m, {
const sentryConfig = withSentryConfig(mergedConfig, {
annotateReactComponents: true,
});

module.exports = withMonorepo(sentryConfig);
1 change: 1 addition & 0 deletions samples/react-native-macos/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
"sentry-react-native-samples-utils": "workspace:^",
"typescript": "5.0.4"
},
"engines": {
Expand Down
64 changes: 7 additions & 57 deletions samples/react-native/metro.config.js
Original file line number Diff line number Diff line change
@@ -1,70 +1,20 @@
const path = require('path');
const { withSentryConfig } = require('@sentry/react-native/metro');
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const exclusionList = require('metro-config/src/defaults/exclusionList');

const projectRoot = __dirname;
const monorepoRoot = path.resolve(projectRoot, '../..');

// Only list the packages within your monorepo that your app uses. No need to add anything else.
// If your monorepo tooling can give you the list of monorepo workspaces linked
// in your app workspace, you can automate this list instead of hardcoding them.
const monorepoPackages = {
'@sentry/react-native': path.resolve(monorepoRoot, 'packages/core'),
};
const { withMonorepo } = require('sentry-react-native-samples-utils/metro');

/**
* Metro configuration
* https://reactnative.dev/docs/metro
*
* @type {import('metro-config').MetroConfig}
*/
const config = {
projectRoot: __dirname,
// 1. Watch the local app directory, and only the shared packages (limiting the scope and speeding it up)
// Note how we change this from `monorepoRoot` to `projectRoot`. This is part of the optimization!
watchFolders: [projectRoot, ...Object.values(monorepoPackages)],
resolver: {
resolverMainFields: ['react-native', 'main'],
resolveRequest: (context, moduleName, platform) => {
if (moduleName.includes('promise/')) {
return context.resolveRequest(
{
...context,
// Ensures the promise module is resolved from the sample's node_modules.
allowHaste: false,
disableHierarchicalLookup: true,
},
moduleName,
platform,
);
}
return context.resolveRequest(context, moduleName, platform);
},
blockList: exclusionList([
new RegExp('.*\\android\\.*'), // Required for Windows in order to run the Sample.
...Object.values(monorepoPackages).map(
p => new RegExp(`${p}/node_modules/react-native/.*`),
),
]),
// Add the monorepo workspaces as `extraNodeModules` to Metro.
// If your monorepo tooling creates workspace symlinks in the `node_modules` directory,
// you can either add symlink support to Metro or set the `extraNodeModules` to avoid the symlinks.
// See: https://metrobundler.dev/docs/configuration/#extranodemodules
extraNodeModules: {
...monorepoPackages,
'react-native': path.resolve(projectRoot, 'node_modules/react-native'),
},
nodeModulesPaths: [
path.resolve(projectRoot, 'node_modules'),
...Object.values(monorepoPackages).map(p =>
path.resolve(p, 'node_modules'),
),
],
},
};
const config = {};

const mergedConfig = mergeConfig(getDefaultConfig(__dirname), config);

const m = mergeConfig(getDefaultConfig(__dirname), config);
module.exports = withSentryConfig(m, {
const sentryConfig = withSentryConfig(mergedConfig, {
annotateReactComponents: true,
});

module.exports = withMonorepo(sentryConfig);
1 change: 1 addition & 0 deletions samples/react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"patch-package": "^8.0.0",
"prettier": "2.8.8",
"react-test-renderer": "18.3.1",
"sentry-react-native-samples-utils": "workspace:^",
"typescript": "5.0.4"
},
"engines": {
Expand Down
Loading

0 comments on commit d997097

Please sign in to comment.