From 73c80fc1bfbd361c04ef6759c5e312ef6919500f Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 1 Aug 2024 21:32:21 -0300 Subject: [PATCH 01/34] soft rollback later --- samples/react-native/android/app/build.gradle | 9 +- samples/react-native/babel.config.js | 6 +- samples/react-native/index.js | 4 - samples/react-native/metro.config.js | 54 +++- samples/react-native/package.json | 1 + samples/react-native/react-native.config.js | 2 + samples/react-native/src/App.tsx | 4 - samples/react-native/tsconfig.json | 4 +- samples/react-native/yarn.lock | 234 +++++++++++++++++- src/js/tools/metroconfig.ts | 67 ++++- 10 files changed, 358 insertions(+), 27 deletions(-) diff --git a/samples/react-native/android/app/build.gradle b/samples/react-native/android/app/build.gradle index 6bd2dd465..ef596721e 100644 --- a/samples/react-native/android/app/build.gradle +++ b/samples/react-native/android/app/build.gradle @@ -10,17 +10,16 @@ project.ext.vectoricons = [ apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle") project.ext.sentryCli = [ - collectModulesScript: "../../../../dist/js/tools/collectModules.js", + collectModulesScript: "../../node_modules/@sentry/react-native/dist/js/tools/collectModules.js", modulesPaths: [ "node_modules", - "../../..", ], skipCollectModules: false, - copyDebugIdScript: "../../../../scripts/copy-debugid.js", - hasSourceMapDebugIdScript: "../../../../scripts/has-sourcemap-debugid.js", + copyDebugIdScript: "../../node_modules/@sentry/react-native/scripts/copy-debugid.js", + hasSourceMapDebugIdScript: "../../node_modules/@sentry/react-native/scripts/has-sourcemap-debugid.js", ] -apply from: "../../../../sentry.gradle" +apply from: "../../node_modules/@sentry/react-native/sentry.gradle" sentry { // Whether the plugin should attempt to auto-upload the mapping file to Sentry or not. diff --git a/samples/react-native/babel.config.js b/samples/react-native/babel.config.js index 8c8fb9c1a..624211983 100644 --- a/samples/react-native/babel.config.js +++ b/samples/react-native/babel.config.js @@ -4,9 +4,9 @@ module.exports = { [ 'module-resolver', { - alias: { - '@sentry/react-native': '../../dist/js', - }, + // alias: { + // '@sentry/react-native': '../../dist/js', + // }, }, ], 'react-native-reanimated/plugin', diff --git a/samples/react-native/index.js b/samples/react-native/index.js index e1dd8be53..75821c54d 100644 --- a/samples/react-native/index.js +++ b/samples/react-native/index.js @@ -1,7 +1,3 @@ -/** - * @format - */ - import { AppRegistry } from 'react-native'; import App from './src/App'; diff --git a/samples/react-native/metro.config.js b/samples/react-native/metro.config.js index 9e1e8c7f1..265877c31 100644 --- a/samples/react-native/metro.config.js +++ b/samples/react-native/metro.config.js @@ -2,8 +2,8 @@ const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const path = require('path'); const blacklist = require('metro-config/src/defaults/exclusionList'); -const { withSentryConfig } = require('../../metro'); -const parentDir = path.resolve(__dirname, '../..'); +const { withSentryConfig } = require('@sentry/react-native/metro'); +const parentDir = path.resolve(__dirname, 'node_modules/@sentry/react-native'); /** * Metro configuration @@ -17,9 +17,11 @@ const config = { path.resolve(__dirname, 'node_modules'), `${parentDir}/dist`, `${parentDir}/node_modules`, - ], + ],resolveRequest: resolver: { resolveRequest: (context, moduleName, platform) => { + console.log("hi") + if (1 == 1)throw new Error("hi"); if (moduleName.includes('promise/')) { return context.resolveRequest( { @@ -32,11 +34,19 @@ const config = { platform, ); } + if (moduleName.includes('@sentry/replay')) { + return { + type: 'empty', + // filePath: path.resolve(__dirname, 'empty-module.js'), + }; + } + return context.resolveRequest(context, moduleName, platform); }, blacklistRE: blacklist([ new RegExp(`${parentDir}/node_modules/react-native/.*`), new RegExp('.*\\android\\.*'), // Required for Windows in order to run the Sample. + // new RegExp(`/node_modules/@sentry/replay/.*`), ]), extraNodeModules: new Proxy( { @@ -60,6 +70,38 @@ const config = { }; const m = mergeConfig(getDefaultConfig(__dirname), config); -module.exports = withSentryConfig(m, { - annotateReactComponents: true, -}); +//const last = withSentryConfig(m, { +// annotateReactComponents: true, +//}); +if (m.resolve) { + m.resolve.resolveRequest = (context, moduleName, platform) => { + console.log("hi") + if (1 == 1) throw new Error("hi"); + 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, + ); + } + if (moduleName.includes('@sentry/replay')) { + return { + type: 'empty', + // filePath: path.resolve(__dirname, 'empty-module.js'), + }; + } + + return context.resolveRequest(context, moduleName, platform); + }; +} +else { + console.log(" :( "); +} + +module.exports = m; + diff --git a/samples/react-native/package.json b/samples/react-native/package.json index b08d31a63..f2ebb74b6 100644 --- a/samples/react-native/package.json +++ b/samples/react-native/package.json @@ -24,6 +24,7 @@ "@react-navigation/native": "^6.1.9", "@react-navigation/native-stack": "^6.9.17", "@react-navigation/stack": "^6.3.20", + "@sentry/react-native": "file:.yalc/@sentry/react-native", "delay": "^6.0.0", "react": "18.2.0", "react-native": "0.73.2", diff --git a/samples/react-native/react-native.config.js b/samples/react-native/react-native.config.js index af1600362..fc4cedfe0 100644 --- a/samples/react-native/react-native.config.js +++ b/samples/react-native/react-native.config.js @@ -9,9 +9,11 @@ module.exports = { automaticPodsInstallation: true, }, }, + /* dependencies: { RNSentry: { root: path.resolve(__dirname, '../../'), }, }, + */ }; diff --git a/samples/react-native/src/App.tsx b/samples/react-native/src/App.tsx index 338a3cef9..0df1acacd 100644 --- a/samples/react-native/src/App.tsx +++ b/samples/react-native/src/App.tsx @@ -49,10 +49,6 @@ Sentry.init({ dsn: SENTRY_INTERNAL_DSN, debug: true, environment: 'dev', - beforeSend: (event: Sentry.Event) => { - logWithoutTracing('Event beforeSend:', event.event_id); - return event; - }, beforeSendTransaction(event) { logWithoutTracing('Transaction beforeSend:', event.event_id); return event; diff --git a/samples/react-native/tsconfig.json b/samples/react-native/tsconfig.json index 361f7005c..01581635f 100644 --- a/samples/react-native/tsconfig.json +++ b/samples/react-native/tsconfig.json @@ -7,8 +7,10 @@ /* Completeness */ "skipLibCheck": true, /* Skip type checking all .d.ts files. */ "baseUrl": ".", +/* "paths": { "@sentry/react-native": ["../../"] }, - }, +*/ + }, } diff --git a/samples/react-native/yarn.lock b/samples/react-native/yarn.lock index 0c5340d4c..f289a9844 100644 --- a/samples/react-native/yarn.lock +++ b/samples/react-native/yarn.lock @@ -3428,11 +3428,185 @@ color "^4.2.3" warn-once "^0.1.0" +"@sentry-internal/feedback@7.117.0": + version "7.117.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-7.117.0.tgz#4ca62cc469611720e76877a756cf24b792cb178e" + integrity sha512-4X+NnnY17W74TymgLFH7/KPTVYpEtoMMJh8HzVdCmHTOE6j32XKBeBMRaXBhmNYmEgovgyRKKf2KvtSfgw+V1Q== + dependencies: + "@sentry/core" "7.117.0" + "@sentry/types" "7.117.0" + "@sentry/utils" "7.117.0" + +"@sentry-internal/replay-canvas@7.117.0": + version "7.117.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/replay-canvas/-/replay-canvas-7.117.0.tgz#d6b3b711453c88e040f31ebab1d4bc627b4a6505" + integrity sha512-7hjIhwEcoosr+BIa0AyEssB5xwvvlzUpvD5fXu4scd3I3qfX8gdnofO96a8r+LrQm3bSj+eN+4TfKEtWb7bU5A== + dependencies: + "@sentry/core" "7.117.0" + "@sentry/replay" "7.117.0" + "@sentry/types" "7.117.0" + "@sentry/utils" "7.117.0" + +"@sentry-internal/tracing@7.117.0": + version "7.117.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.117.0.tgz#c7d2357dae8d7ea2bc130e4513ac4ffc8dc7553c" + integrity sha512-fAIyijNvKBZNA12IcKo+dOYDRTNrzNsdzbm3DP37vJRKVQu19ucqP4Y6InvKokffDP2HZPzFPDoGXYuXkDhUZg== + dependencies: + "@sentry/core" "7.117.0" + "@sentry/types" "7.117.0" + "@sentry/utils" "7.117.0" + +"@sentry/babel-plugin-component-annotate@2.20.1": + version "2.20.1" + resolved "https://registry.yarnpkg.com/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.20.1.tgz#204c63ed006a048f48f633876e1b8bacf87a9722" + integrity sha512-4mhEwYTK00bIb5Y9UWIELVUfru587Vaeg0DQGswv4aIRHIiMKLyNqCEejaaybQ/fNChIZOKmvyqXk430YVd7Qg== + "@sentry/babel-plugin-component-annotate@^2.18.0": version "2.18.0" resolved "https://registry.yarnpkg.com/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.18.0.tgz#3bee98f94945643b0762ceed1f6cca60db52bdbd" integrity sha512-9L4RbhS3WNtc/SokIhc0dwgcvs78YSQPakZejsrIgnzLzCi8mS6PeT+BY0+QCtsXxjd1egM8hqcJeB0lukBkXA== +"@sentry/browser@7.117.0": + version "7.117.0" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.117.0.tgz#3030073f360974dadcf5a5f2e1542497b3be2482" + integrity sha512-29X9HlvDEKIaWp6XKlNPPSNND0U6P/ede5WA2nVHfs1zJLWdZ7/ijuMc0sH/CueEkqHe/7gt94hBcI7HOU/wSw== + dependencies: + "@sentry-internal/feedback" "7.117.0" + "@sentry-internal/replay-canvas" "7.117.0" + "@sentry-internal/tracing" "7.117.0" + "@sentry/core" "7.117.0" + "@sentry/integrations" "7.117.0" + "@sentry/replay" "7.117.0" + "@sentry/types" "7.117.0" + "@sentry/utils" "7.117.0" + +"@sentry/cli-darwin@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli-darwin/-/cli-darwin-2.31.2.tgz#faeb87d09d8b21b8b8dd2e2aa848b538f01ddd26" + integrity sha512-BHA/JJXj1dlnoZQdK4efRCtHRnbBfzbIZUKAze7oRR1RfNqERI84BVUQeKateD3jWSJXQfEuclIShc61KOpbKw== + +"@sentry/cli-linux-arm64@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.31.2.tgz#669c9c3f7f9130d26f5db732f793378863d58869" + integrity sha512-FLVKkJ/rWvPy/ka7OrUdRW63a/z8HYI1Gt8Pr6rWs50hb7YJja8lM8IO10tYmcFE/tODICsnHO9HTeUg2g2d1w== + +"@sentry/cli-linux-arm@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm/-/cli-linux-arm-2.31.2.tgz#3e36ed7db09e922f00221281252e58dfd8755ea5" + integrity sha512-W8k5mGYYZz/I/OxZH65YAK7dCkQAl+wbuoASGOQjUy5VDgqH0QJ8kGJufXvFPM+f3ZQGcKAnVsZ6tFqZXETBAw== + +"@sentry/cli-linux-i686@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli-linux-i686/-/cli-linux-i686-2.31.2.tgz#02b7da274369b78a5676c20bb26cc37caed5244b" + integrity sha512-A64QtzaPi3MYFpZ+Fwmi0mrSyXgeLJ0cWr4jdeTGrzNpeowSteKgd6tRKU+LVq0k5shKE7wdnHk+jXnoajulMA== + +"@sentry/cli-linux-x64@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli-linux-x64/-/cli-linux-x64-2.31.2.tgz#54f74a9e5925db9ddafebc0efd4056c5377be5fd" + integrity sha512-YL/r+15R4mOEiU3mzn7iFQOeFEUB6KxeKGTTrtpeOGynVUGIdq4nV5rHow5JDbIzOuBS3SpOmcIMluvo1NCh0g== + +"@sentry/cli-win32-i686@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli-win32-i686/-/cli-win32-i686-2.31.2.tgz#5dab845a824be0927566171aa05f015e887fe82d" + integrity sha512-Az/2bmW+TFI059RE0mSBIxTBcoShIclz7BDebmIoCkZ+retrwAzpmBnBCDAHow+Yi43utOow+3/4idGa2OxcLw== + +"@sentry/cli-win32-x64@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli-win32-x64/-/cli-win32-x64-2.31.2.tgz#e12fec0a54f6d9cced5235fbc68ba8f94165634b" + integrity sha512-XIzyRnJu539NhpFa+JYkotzVwv3NrZ/4GfHB/JWA2zReRvsk39jJG8D5HOmm0B9JA63QQT7Dt39RW8g3lkmb6w== + +"@sentry/cli@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-2.31.2.tgz#39df8e52966aa8db4f9c51f4bc77abd62b6a630e" + integrity sha512-2aKyUx6La2P+pplL8+2vO67qJ+c1C79KYWAyQBE0JIT5kvKK9JpwtdNoK1F0/2mRpwhhYPADCz3sVIRqmL8cQQ== + dependencies: + https-proxy-agent "^5.0.0" + node-fetch "^2.6.7" + progress "^2.0.3" + proxy-from-env "^1.1.0" + which "^2.0.2" + optionalDependencies: + "@sentry/cli-darwin" "2.31.2" + "@sentry/cli-linux-arm" "2.31.2" + "@sentry/cli-linux-arm64" "2.31.2" + "@sentry/cli-linux-i686" "2.31.2" + "@sentry/cli-linux-x64" "2.31.2" + "@sentry/cli-win32-i686" "2.31.2" + "@sentry/cli-win32-x64" "2.31.2" + +"@sentry/core@7.117.0": + version "7.117.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.117.0.tgz#eebdb6e700d5fbdf3102c4abfb4ff92ef79ae9a5" + integrity sha512-1XZ4/d/DEwnfM2zBMloXDwX+W7s76lGKQMgd8bwgPJZjjEztMJ7X0uopKAGwlQcjn242q+hsCBR6C+fSuI5kvg== + dependencies: + "@sentry/types" "7.117.0" + "@sentry/utils" "7.117.0" + +"@sentry/hub@7.117.0": + version "7.117.0" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-7.117.0.tgz#924462cd083b57b45559eb5a25850e5b3004a7f8" + integrity sha512-pQrXnbzsRHCUsVIqz/sZ0vggnxuuHqsmyjoy2Ha1qn1Ya4QbyAWEEGoZTnZx6I/Vt3dzVvRnR3YCywatdkaFxg== + dependencies: + "@sentry/core" "7.117.0" + "@sentry/types" "7.117.0" + "@sentry/utils" "7.117.0" + +"@sentry/integrations@7.117.0": + version "7.117.0" + resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.117.0.tgz#4613dae3bc1d257c3c870461327fd4f70dbda229" + integrity sha512-U3suSZysmU9EiQqg0ga5CxveAyNbi9IVdsapMDq5EQGNcVDvheXtULs+BOc11WYP3Kw2yWB38VDqLepfc/Fg2g== + dependencies: + "@sentry/core" "7.117.0" + "@sentry/types" "7.117.0" + "@sentry/utils" "7.117.0" + localforage "^1.8.1" + +"@sentry/react-native@file:.yalc/@sentry/react-native": + version "5.26.0" + dependencies: + "@sentry/babel-plugin-component-annotate" "2.20.1" + "@sentry/browser" "7.117.0" + "@sentry/cli" "2.31.2" + "@sentry/core" "7.117.0" + "@sentry/hub" "7.117.0" + "@sentry/integrations" "7.117.0" + "@sentry/react" "7.117.0" + "@sentry/types" "7.117.0" + "@sentry/utils" "7.117.0" + +"@sentry/react@7.117.0": + version "7.117.0" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.117.0.tgz#0a6e729f5d17782a02a48728821536ede569bc8d" + integrity sha512-aK+yaEP2esBhaczGU96Y7wkqB4umSIlRAzobv7ER88EGHzZulRaocTpQO8HJJGDHm4D8rD+E893BHnghkoqp4Q== + dependencies: + "@sentry/browser" "7.117.0" + "@sentry/core" "7.117.0" + "@sentry/types" "7.117.0" + "@sentry/utils" "7.117.0" + hoist-non-react-statics "^3.3.2" + +"@sentry/replay@7.117.0": + version "7.117.0" + resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.117.0.tgz#c41844b60ad5d711d663a562e2df77fe14c51bbb" + integrity sha512-V4DfU+x4UsA4BsufbQ8jHYa5H0q5PYUgso2X1PR31g1fpx7yiYguSmCfz1UryM6KkH92dfTnqXapDB44kXOqzQ== + dependencies: + "@sentry-internal/tracing" "7.117.0" + "@sentry/core" "7.117.0" + "@sentry/types" "7.117.0" + "@sentry/utils" "7.117.0" + +"@sentry/types@7.117.0": + version "7.117.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.117.0.tgz#c4d89aba487c05f4e5cbfa2f1c65180b536393b4" + integrity sha512-5dtdulcUttc3F0Te7ekZmpSp/ebt/CA71ELx0uyqVGjWsSAINwskFD77sdcjqvZWek//WjiYX1+GRKlpJ1QqsA== + +"@sentry/utils@7.117.0": + version "7.117.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.117.0.tgz#ac367a6f623bd09440b39d947437009c0ffe52b2" + integrity sha512-KkcLY8643SGBiDyPvMQOubBkwVX5IPknMHInc7jYC8pDVncGp7C65Wi506bCNPpKCWspUd/0VDNWOOen51/qKA== + dependencies: + "@sentry/types" "7.117.0" + "@sideway/address@^4.1.3": version "4.1.4" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" @@ -3893,6 +4067,13 @@ acorn@^8.5.0, acorn@^8.8.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -4748,6 +4929,13 @@ debug@2.6.9, debug@^2.2.0, debug@^2.6.9: dependencies: ms "2.0.0" +debug@4: + version "4.3.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" + integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== + dependencies: + ms "2.1.2" + debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -5806,6 +5994,14 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -5828,6 +6024,11 @@ image-size@^1.0.2: dependencies: queue "6.0.2" +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" @@ -6778,6 +6979,13 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lie@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + integrity sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw== + dependencies: + immediate "~3.0.5" + lighthouse-logger@^1.0.0: version "1.4.2" resolved "https://registry.yarnpkg.com/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz#aef90f9e97cd81db367c7634292ee22079280aaa" @@ -6791,6 +6999,13 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +localforage@^1.8.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4" + integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg== + dependencies: + lie "3.1.1" + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -7418,6 +7633,13 @@ node-fetch@^2.2.0, node-fetch@^2.6.0: dependencies: whatwg-url "^5.0.0" +node-fetch@^2.6.7: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -7815,6 +8037,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +progress@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + promise@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" @@ -7839,6 +8066,11 @@ prop-types@^15.7.2, prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -9044,7 +9276,7 @@ which-typed-array@^1.1.9: has-tostringtag "^1.0.0" is-typed-array "^1.1.10" -which@^2.0.1: +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 6e5854475..d1574cafb 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -1,5 +1,5 @@ import { logger } from '@sentry/utils'; -import type { MetroConfig, MixedOutput, Module, ReadOnlyGraph } from 'metro'; +import { type MetroConfig, type MixedOutput, type Module, type ReadOnlyGraph,mergeConfig } from 'metro'; import * as process from 'process'; import { env } from 'process'; @@ -18,6 +18,11 @@ export interface SentryMetroConfigOptions { * @default false */ annotateReactComponents?: boolean; + /** + * Adds the Sentry replay for web. + * @default false + */ + includeWebReplay?: boolean; } export interface SentryExpoConfigOptions { @@ -35,7 +40,7 @@ export interface SentryExpoConfigOptions { */ export function withSentryConfig( config: MetroConfig, - { annotateReactComponents = false }: SentryMetroConfigOptions = {}, + { annotateReactComponents = false, includeWebReplay = false }: SentryMetroConfigOptions = {}, ): MetroConfig { setSentryMetroDevServerEnvFlag(); @@ -46,8 +51,9 @@ export function withSentryConfig( if (annotateReactComponents) { newConfig = withSentryBabelTransformer(newConfig); } + newConfig = excludeSentryWebReplay(config); - return newConfig; + return newConfig; } /** @@ -146,6 +152,61 @@ function withSentryDebugId(config: MetroConfig): MetroConfig { }; } +function excludeSentryWebReplay(config: MetroConfig): MetroConfig { + console.log("sad") + return { + ...config.transformerPath, + transformer: { + ...config.transformer, + getTransformOptions: async () => ({ + transform: { + experimentalImportSupport: false, + inlineRequires: false, + }, + preloadedModules: false, + publicPath: '/assets', + plugins: [ + [ + require.resolve('babel-plugin-transform-inline-environment-variables'), + { + include: [ + "RRWEB_EXCLUDE_IFRAME", + "RRWEB_EXCLUDE_SHADOW_DOM", + "SENTRY_EXCLUDE_REPLAY_WORKER" + ] + } + ] + ] + }) + } + }; + /* + + const originalResolver = config.resolver?.resolveRequest; + + return mergeConfig(config, { + resolver: { + resolveRequest: (context, moduleName, platform) => { + // eslint-disable-next-line no-console + console.log(`resolving the request ${ moduleName}`); + + + if (moduleName.includes('@sentry/replay')) { + return { type: 'empty' }; + } + if (moduleName) { + throw new Error('we found replay'); + } + if (originalResolver) { + return originalResolver(context, moduleName, platform); + } + return context.resolveRequest(context, moduleName, platform); + } + } + }); + */ +} + type MetroFrame = Parameters['symbolicator']>['customizeFrame']>[0]; type MetroCustomizeFrame = { readonly collapse?: boolean }; type MetroCustomizeFrameReturnValue = From 8b42ad9778551d7ea1398c0d8f7d503a9c9d2bda Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 8 Aug 2024 21:58:37 -0300 Subject: [PATCH 02/34] add sentry exclude for replay --- .gitignore | 3 +++ src/js/tools/metroconfig.ts | 47 +++++-------------------------------- 2 files changed, 9 insertions(+), 41 deletions(-) diff --git a/.gitignore b/.gitignore index 87a34b65e..6750e5796 100644 --- a/.gitignore +++ b/.gitignore @@ -72,6 +72,9 @@ wheelhouse .yalc/ yalc.lock +# Yarn +.yarn + # E2E tests test/react-native/versions diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index d1574cafb..d7652d85d 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -51,9 +51,11 @@ export function withSentryConfig( if (annotateReactComponents) { newConfig = withSentryBabelTransformer(newConfig); } - newConfig = excludeSentryWebReplay(config); + if (includeWebReplay === false) { + newConfig = excludeSentryWebReplay(config); + } - return newConfig; + return newConfig; } /** @@ -153,58 +155,21 @@ function withSentryDebugId(config: MetroConfig): MetroConfig { } function excludeSentryWebReplay(config: MetroConfig): MetroConfig { - console.log("sad") - return { - ...config.transformerPath, - transformer: { - ...config.transformer, - getTransformOptions: async () => ({ - transform: { - experimentalImportSupport: false, - inlineRequires: false, - }, - preloadedModules: false, - publicPath: '/assets', - plugins: [ - [ - require.resolve('babel-plugin-transform-inline-environment-variables'), - { - include: [ - "RRWEB_EXCLUDE_IFRAME", - "RRWEB_EXCLUDE_SHADOW_DOM", - "SENTRY_EXCLUDE_REPLAY_WORKER" - ] - } - ] - ] - }) - } - }; - /* - const originalResolver = config.resolver?.resolveRequest; return mergeConfig(config, { resolver: { resolveRequest: (context, moduleName, platform) => { - // eslint-disable-next-line no-console - console.log(`resolving the request ${ moduleName}`); - - if (moduleName.includes('@sentry/replay')) { return { type: 'empty' }; } - if (moduleName) { - throw new Error('we found replay'); + if (originalResolver) { + return originalResolver(context, moduleName, platform); } - if (originalResolver) { - return originalResolver(context, moduleName, platform); - } return context.resolveRequest(context, moduleName, platform); } } }); - */ } type MetroFrame = Parameters['symbolicator']>['customizeFrame']>[0]; From 76764d1a21567ffe35a5adee69b1c0bf6affb03a Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 8 Aug 2024 22:12:39 -0300 Subject: [PATCH 03/34] changelog --- CHANGELOG.md | 1 + src/js/tools/metroconfig.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0a5b995d..33d0da44e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fixes +- Exclude Sentry Web Replay by default, reducing the code in 130KB. ([#4006](https://github.com/getsentry/sentry-react-native/pull/4006)) - `Sentry.captureMessage` stack trace is in `event.exception` (moved from `event.threads`) ([#3635](https://github.com/getsentry/sentry-react-native/pull/3635), [#3988](https://github.com/getsentry/sentry-react-native/pull/3988)) - To revert to the old behavior (causing the stack to be unsymbolicated) use `useThreadsForMessageStack` option diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index d7652d85d..03b9217bf 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -19,7 +19,7 @@ export interface SentryMetroConfigOptions { */ annotateReactComponents?: boolean; /** - * Adds the Sentry replay for web. + * Adds the Sentry replay package for web. * @default false */ includeWebReplay?: boolean; From ce604ba8c3e6452bda33c96dcf79fa7e97a73637 Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 8 Aug 2024 22:20:40 -0300 Subject: [PATCH 04/34] clear tests --- samples/react-native/android/app/build.gradle | 9 +- samples/react-native/babel.config.js | 6 +- samples/react-native/index.js | 3 + samples/react-native/metro.config.js | 55 +--- samples/react-native/package.json | 1 - samples/react-native/react-native.config.js | 2 - samples/react-native/src/App.tsx | 4 + samples/react-native/tsconfig.json | 5 +- samples/react-native/yarn.lock | 234 +----------------- src/js/tools/metroconfig.ts | 7 +- 10 files changed, 28 insertions(+), 298 deletions(-) diff --git a/samples/react-native/android/app/build.gradle b/samples/react-native/android/app/build.gradle index 869f0ba5f..54b1f126a 100644 --- a/samples/react-native/android/app/build.gradle +++ b/samples/react-native/android/app/build.gradle @@ -10,16 +10,17 @@ project.ext.vectoricons = [ apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle") project.ext.sentryCli = [ - collectModulesScript: "../../node_modules/@sentry/react-native/dist/js/tools/collectModules.js", + collectModulesScript: "../../../../dist/js/tools/collectModules.js", modulesPaths: [ "node_modules", + "../../..", ], skipCollectModules: false, - copyDebugIdScript: "../../node_modules/@sentry/react-native/scripts/copy-debugid.js", - hasSourceMapDebugIdScript: "../../node_modules/@sentry/react-native/scripts/has-sourcemap-debugid.js", + copyDebugIdScript: "../../../../scripts/copy-debugid.js", + hasSourceMapDebugIdScript: "../../../../scripts/has-sourcemap-debugid.js", ] -apply from: "../../node_modules/@sentry/react-native/sentry.gradle" +apply from: "../../../../sentry.gradle" sentry { // Whether the plugin should attempt to auto-upload the mapping file to Sentry or not. diff --git a/samples/react-native/babel.config.js b/samples/react-native/babel.config.js index 624211983..8c8fb9c1a 100644 --- a/samples/react-native/babel.config.js +++ b/samples/react-native/babel.config.js @@ -4,9 +4,9 @@ module.exports = { [ 'module-resolver', { - // alias: { - // '@sentry/react-native': '../../dist/js', - // }, + alias: { + '@sentry/react-native': '../../dist/js', + }, }, ], 'react-native-reanimated/plugin', diff --git a/samples/react-native/index.js b/samples/react-native/index.js index 75821c54d..93d65ae2c 100644 --- a/samples/react-native/index.js +++ b/samples/react-native/index.js @@ -1,3 +1,6 @@ +/** + * @format + */ import { AppRegistry } from 'react-native'; import App from './src/App'; diff --git a/samples/react-native/metro.config.js b/samples/react-native/metro.config.js index 265877c31..ec804e212 100644 --- a/samples/react-native/metro.config.js +++ b/samples/react-native/metro.config.js @@ -2,8 +2,8 @@ const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const path = require('path'); const blacklist = require('metro-config/src/defaults/exclusionList'); -const { withSentryConfig } = require('@sentry/react-native/metro'); -const parentDir = path.resolve(__dirname, 'node_modules/@sentry/react-native'); +const { withSentryConfig } = require('../../metro'); +const parentDir = path.resolve(__dirname, '../..'); /** * Metro configuration @@ -17,11 +17,8 @@ const config = { path.resolve(__dirname, 'node_modules'), `${parentDir}/dist`, `${parentDir}/node_modules`, - ],resolveRequest: - resolver: { + ], resolver: { resolveRequest: (context, moduleName, platform) => { - console.log("hi") - if (1 == 1)throw new Error("hi"); if (moduleName.includes('promise/')) { return context.resolveRequest( { @@ -34,19 +31,11 @@ const config = { platform, ); } - if (moduleName.includes('@sentry/replay')) { - return { - type: 'empty', - // filePath: path.resolve(__dirname, 'empty-module.js'), - }; - } - return context.resolveRequest(context, moduleName, platform); }, blacklistRE: blacklist([ new RegExp(`${parentDir}/node_modules/react-native/.*`), new RegExp('.*\\android\\.*'), // Required for Windows in order to run the Sample. - // new RegExp(`/node_modules/@sentry/replay/.*`), ]), extraNodeModules: new Proxy( { @@ -70,38 +59,6 @@ const config = { }; const m = mergeConfig(getDefaultConfig(__dirname), config); -//const last = withSentryConfig(m, { -// annotateReactComponents: true, -//}); -if (m.resolve) { - m.resolve.resolveRequest = (context, moduleName, platform) => { - console.log("hi") - if (1 == 1) throw new Error("hi"); - 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, - ); - } - if (moduleName.includes('@sentry/replay')) { - return { - type: 'empty', - // filePath: path.resolve(__dirname, 'empty-module.js'), - }; - } - - return context.resolveRequest(context, moduleName, platform); - }; -} -else { - console.log(" :( "); -} - -module.exports = m; - +module.exports = withSentryConfig(m, { + annotateReactComponents: true, +}); diff --git a/samples/react-native/package.json b/samples/react-native/package.json index 94f581e55..a6f0f01c8 100644 --- a/samples/react-native/package.json +++ b/samples/react-native/package.json @@ -24,7 +24,6 @@ "@react-navigation/native": "^6.1.9", "@react-navigation/native-stack": "^6.9.17", "@react-navigation/stack": "^6.3.20", - "@sentry/react-native": "file:.yalc/@sentry/react-native", "delay": "^6.0.0", "react": "18.2.0", "react-native": "0.73.9", diff --git a/samples/react-native/react-native.config.js b/samples/react-native/react-native.config.js index fc4cedfe0..af1600362 100644 --- a/samples/react-native/react-native.config.js +++ b/samples/react-native/react-native.config.js @@ -9,11 +9,9 @@ module.exports = { automaticPodsInstallation: true, }, }, - /* dependencies: { RNSentry: { root: path.resolve(__dirname, '../../'), }, }, - */ }; diff --git a/samples/react-native/src/App.tsx b/samples/react-native/src/App.tsx index 5e4ad5929..c60ee4769 100644 --- a/samples/react-native/src/App.tsx +++ b/samples/react-native/src/App.tsx @@ -49,6 +49,10 @@ Sentry.init({ dsn: SENTRY_INTERNAL_DSN, debug: true, environment: 'dev', + beforeSend: (event: Sentry.Event) => { + logWithoutTracing('Event beforeSend:', event.event_id); + return event; + }, beforeSendTransaction(event) { logWithoutTracing('Transaction beforeSend:', event.event_id); return event; diff --git a/samples/react-native/tsconfig.json b/samples/react-native/tsconfig.json index 01581635f..c983542f8 100644 --- a/samples/react-native/tsconfig.json +++ b/samples/react-native/tsconfig.json @@ -7,10 +7,9 @@ /* Completeness */ "skipLibCheck": true, /* Skip type checking all .d.ts files. */ "baseUrl": ".", -/* + "paths": { "@sentry/react-native": ["../../"] }, -*/ - }, + }, } diff --git a/samples/react-native/yarn.lock b/samples/react-native/yarn.lock index 06935d84e..2b6f45788 100644 --- a/samples/react-native/yarn.lock +++ b/samples/react-native/yarn.lock @@ -3136,185 +3136,11 @@ color "^4.2.3" warn-once "^0.1.0" -"@sentry-internal/feedback@7.117.0": - version "7.117.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-7.117.0.tgz#4ca62cc469611720e76877a756cf24b792cb178e" - integrity sha512-4X+NnnY17W74TymgLFH7/KPTVYpEtoMMJh8HzVdCmHTOE6j32XKBeBMRaXBhmNYmEgovgyRKKf2KvtSfgw+V1Q== - dependencies: - "@sentry/core" "7.117.0" - "@sentry/types" "7.117.0" - "@sentry/utils" "7.117.0" - -"@sentry-internal/replay-canvas@7.117.0": - version "7.117.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/replay-canvas/-/replay-canvas-7.117.0.tgz#d6b3b711453c88e040f31ebab1d4bc627b4a6505" - integrity sha512-7hjIhwEcoosr+BIa0AyEssB5xwvvlzUpvD5fXu4scd3I3qfX8gdnofO96a8r+LrQm3bSj+eN+4TfKEtWb7bU5A== - dependencies: - "@sentry/core" "7.117.0" - "@sentry/replay" "7.117.0" - "@sentry/types" "7.117.0" - "@sentry/utils" "7.117.0" - -"@sentry-internal/tracing@7.117.0": - version "7.117.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.117.0.tgz#c7d2357dae8d7ea2bc130e4513ac4ffc8dc7553c" - integrity sha512-fAIyijNvKBZNA12IcKo+dOYDRTNrzNsdzbm3DP37vJRKVQu19ucqP4Y6InvKokffDP2HZPzFPDoGXYuXkDhUZg== - dependencies: - "@sentry/core" "7.117.0" - "@sentry/types" "7.117.0" - "@sentry/utils" "7.117.0" - -"@sentry/babel-plugin-component-annotate@2.20.1": - version "2.20.1" - resolved "https://registry.yarnpkg.com/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.20.1.tgz#204c63ed006a048f48f633876e1b8bacf87a9722" - integrity sha512-4mhEwYTK00bIb5Y9UWIELVUfru587Vaeg0DQGswv4aIRHIiMKLyNqCEejaaybQ/fNChIZOKmvyqXk430YVd7Qg== - "@sentry/babel-plugin-component-annotate@^2.18.0": version "2.18.0" resolved "https://registry.yarnpkg.com/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.18.0.tgz#3bee98f94945643b0762ceed1f6cca60db52bdbd" integrity sha512-9L4RbhS3WNtc/SokIhc0dwgcvs78YSQPakZejsrIgnzLzCi8mS6PeT+BY0+QCtsXxjd1egM8hqcJeB0lukBkXA== -"@sentry/browser@7.117.0": - version "7.117.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.117.0.tgz#3030073f360974dadcf5a5f2e1542497b3be2482" - integrity sha512-29X9HlvDEKIaWp6XKlNPPSNND0U6P/ede5WA2nVHfs1zJLWdZ7/ijuMc0sH/CueEkqHe/7gt94hBcI7HOU/wSw== - dependencies: - "@sentry-internal/feedback" "7.117.0" - "@sentry-internal/replay-canvas" "7.117.0" - "@sentry-internal/tracing" "7.117.0" - "@sentry/core" "7.117.0" - "@sentry/integrations" "7.117.0" - "@sentry/replay" "7.117.0" - "@sentry/types" "7.117.0" - "@sentry/utils" "7.117.0" - -"@sentry/cli-darwin@2.31.2": - version "2.31.2" - resolved "https://registry.yarnpkg.com/@sentry/cli-darwin/-/cli-darwin-2.31.2.tgz#faeb87d09d8b21b8b8dd2e2aa848b538f01ddd26" - integrity sha512-BHA/JJXj1dlnoZQdK4efRCtHRnbBfzbIZUKAze7oRR1RfNqERI84BVUQeKateD3jWSJXQfEuclIShc61KOpbKw== - -"@sentry/cli-linux-arm64@2.31.2": - version "2.31.2" - resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.31.2.tgz#669c9c3f7f9130d26f5db732f793378863d58869" - integrity sha512-FLVKkJ/rWvPy/ka7OrUdRW63a/z8HYI1Gt8Pr6rWs50hb7YJja8lM8IO10tYmcFE/tODICsnHO9HTeUg2g2d1w== - -"@sentry/cli-linux-arm@2.31.2": - version "2.31.2" - resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm/-/cli-linux-arm-2.31.2.tgz#3e36ed7db09e922f00221281252e58dfd8755ea5" - integrity sha512-W8k5mGYYZz/I/OxZH65YAK7dCkQAl+wbuoASGOQjUy5VDgqH0QJ8kGJufXvFPM+f3ZQGcKAnVsZ6tFqZXETBAw== - -"@sentry/cli-linux-i686@2.31.2": - version "2.31.2" - resolved "https://registry.yarnpkg.com/@sentry/cli-linux-i686/-/cli-linux-i686-2.31.2.tgz#02b7da274369b78a5676c20bb26cc37caed5244b" - integrity sha512-A64QtzaPi3MYFpZ+Fwmi0mrSyXgeLJ0cWr4jdeTGrzNpeowSteKgd6tRKU+LVq0k5shKE7wdnHk+jXnoajulMA== - -"@sentry/cli-linux-x64@2.31.2": - version "2.31.2" - resolved "https://registry.yarnpkg.com/@sentry/cli-linux-x64/-/cli-linux-x64-2.31.2.tgz#54f74a9e5925db9ddafebc0efd4056c5377be5fd" - integrity sha512-YL/r+15R4mOEiU3mzn7iFQOeFEUB6KxeKGTTrtpeOGynVUGIdq4nV5rHow5JDbIzOuBS3SpOmcIMluvo1NCh0g== - -"@sentry/cli-win32-i686@2.31.2": - version "2.31.2" - resolved "https://registry.yarnpkg.com/@sentry/cli-win32-i686/-/cli-win32-i686-2.31.2.tgz#5dab845a824be0927566171aa05f015e887fe82d" - integrity sha512-Az/2bmW+TFI059RE0mSBIxTBcoShIclz7BDebmIoCkZ+retrwAzpmBnBCDAHow+Yi43utOow+3/4idGa2OxcLw== - -"@sentry/cli-win32-x64@2.31.2": - version "2.31.2" - resolved "https://registry.yarnpkg.com/@sentry/cli-win32-x64/-/cli-win32-x64-2.31.2.tgz#e12fec0a54f6d9cced5235fbc68ba8f94165634b" - integrity sha512-XIzyRnJu539NhpFa+JYkotzVwv3NrZ/4GfHB/JWA2zReRvsk39jJG8D5HOmm0B9JA63QQT7Dt39RW8g3lkmb6w== - -"@sentry/cli@2.31.2": - version "2.31.2" - resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-2.31.2.tgz#39df8e52966aa8db4f9c51f4bc77abd62b6a630e" - integrity sha512-2aKyUx6La2P+pplL8+2vO67qJ+c1C79KYWAyQBE0JIT5kvKK9JpwtdNoK1F0/2mRpwhhYPADCz3sVIRqmL8cQQ== - dependencies: - https-proxy-agent "^5.0.0" - node-fetch "^2.6.7" - progress "^2.0.3" - proxy-from-env "^1.1.0" - which "^2.0.2" - optionalDependencies: - "@sentry/cli-darwin" "2.31.2" - "@sentry/cli-linux-arm" "2.31.2" - "@sentry/cli-linux-arm64" "2.31.2" - "@sentry/cli-linux-i686" "2.31.2" - "@sentry/cli-linux-x64" "2.31.2" - "@sentry/cli-win32-i686" "2.31.2" - "@sentry/cli-win32-x64" "2.31.2" - -"@sentry/core@7.117.0": - version "7.117.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.117.0.tgz#eebdb6e700d5fbdf3102c4abfb4ff92ef79ae9a5" - integrity sha512-1XZ4/d/DEwnfM2zBMloXDwX+W7s76lGKQMgd8bwgPJZjjEztMJ7X0uopKAGwlQcjn242q+hsCBR6C+fSuI5kvg== - dependencies: - "@sentry/types" "7.117.0" - "@sentry/utils" "7.117.0" - -"@sentry/hub@7.117.0": - version "7.117.0" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-7.117.0.tgz#924462cd083b57b45559eb5a25850e5b3004a7f8" - integrity sha512-pQrXnbzsRHCUsVIqz/sZ0vggnxuuHqsmyjoy2Ha1qn1Ya4QbyAWEEGoZTnZx6I/Vt3dzVvRnR3YCywatdkaFxg== - dependencies: - "@sentry/core" "7.117.0" - "@sentry/types" "7.117.0" - "@sentry/utils" "7.117.0" - -"@sentry/integrations@7.117.0": - version "7.117.0" - resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.117.0.tgz#4613dae3bc1d257c3c870461327fd4f70dbda229" - integrity sha512-U3suSZysmU9EiQqg0ga5CxveAyNbi9IVdsapMDq5EQGNcVDvheXtULs+BOc11WYP3Kw2yWB38VDqLepfc/Fg2g== - dependencies: - "@sentry/core" "7.117.0" - "@sentry/types" "7.117.0" - "@sentry/utils" "7.117.0" - localforage "^1.8.1" - -"@sentry/react-native@file:.yalc/@sentry/react-native": - version "5.26.0" - dependencies: - "@sentry/babel-plugin-component-annotate" "2.20.1" - "@sentry/browser" "7.117.0" - "@sentry/cli" "2.31.2" - "@sentry/core" "7.117.0" - "@sentry/hub" "7.117.0" - "@sentry/integrations" "7.117.0" - "@sentry/react" "7.117.0" - "@sentry/types" "7.117.0" - "@sentry/utils" "7.117.0" - -"@sentry/react@7.117.0": - version "7.117.0" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.117.0.tgz#0a6e729f5d17782a02a48728821536ede569bc8d" - integrity sha512-aK+yaEP2esBhaczGU96Y7wkqB4umSIlRAzobv7ER88EGHzZulRaocTpQO8HJJGDHm4D8rD+E893BHnghkoqp4Q== - dependencies: - "@sentry/browser" "7.117.0" - "@sentry/core" "7.117.0" - "@sentry/types" "7.117.0" - "@sentry/utils" "7.117.0" - hoist-non-react-statics "^3.3.2" - -"@sentry/replay@7.117.0": - version "7.117.0" - resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.117.0.tgz#c41844b60ad5d711d663a562e2df77fe14c51bbb" - integrity sha512-V4DfU+x4UsA4BsufbQ8jHYa5H0q5PYUgso2X1PR31g1fpx7yiYguSmCfz1UryM6KkH92dfTnqXapDB44kXOqzQ== - dependencies: - "@sentry-internal/tracing" "7.117.0" - "@sentry/core" "7.117.0" - "@sentry/types" "7.117.0" - "@sentry/utils" "7.117.0" - -"@sentry/types@7.117.0": - version "7.117.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.117.0.tgz#c4d89aba487c05f4e5cbfa2f1c65180b536393b4" - integrity sha512-5dtdulcUttc3F0Te7ekZmpSp/ebt/CA71ELx0uyqVGjWsSAINwskFD77sdcjqvZWek//WjiYX1+GRKlpJ1QqsA== - -"@sentry/utils@7.117.0": - version "7.117.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.117.0.tgz#ac367a6f623bd09440b39d947437009c0ffe52b2" - integrity sha512-KkcLY8643SGBiDyPvMQOubBkwVX5IPknMHInc7jYC8pDVncGp7C65Wi506bCNPpKCWspUd/0VDNWOOen51/qKA== - dependencies: - "@sentry/types" "7.117.0" - "@sideway/address@^4.1.3": version "4.1.4" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" @@ -3768,13 +3594,6 @@ acorn@^8.5.0, acorn@^8.8.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -4592,13 +4411,6 @@ debug@2.6.9, debug@^2.2.0, debug@^2.6.9: dependencies: ms "2.0.0" -debug@4: - version "4.3.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" - integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== - dependencies: - ms "2.1.2" - debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -5657,14 +5469,6 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -5687,11 +5491,6 @@ image-size@^1.0.2: dependencies: queue "6.0.2" -immediate@~3.0.5: - version "3.0.6" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" - integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== - import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" @@ -6616,13 +6415,6 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -lie@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" - integrity sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw== - dependencies: - immediate "~3.0.5" - lighthouse-logger@^1.0.0: version "1.4.2" resolved "https://registry.yarnpkg.com/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz#aef90f9e97cd81db367c7634292ee22079280aaa" @@ -6636,13 +6428,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -localforage@^1.8.1: - version "1.10.0" - resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4" - integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg== - dependencies: - lie "3.1.1" - locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -7084,13 +6869,6 @@ node-fetch@^2.2.0, node-fetch@^2.6.0: dependencies: whatwg-url "^5.0.0" -node-fetch@^2.6.7: - version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -7483,11 +7261,6 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -progress@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - promise@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" @@ -7512,11 +7285,6 @@ prop-types@^15.7.2, prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -8718,7 +8486,7 @@ which-typed-array@^1.1.9: has-tostringtag "^1.0.0" is-typed-array "^1.1.10" -which@^2.0.1, which@^2.0.2: +which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 03b9217bf..3af69ea40 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -1,5 +1,6 @@ import { logger } from '@sentry/utils'; -import { type MetroConfig, type MixedOutput, type Module, type ReadOnlyGraph,mergeConfig } from 'metro'; +import type { MetroConfig, MixedOutput, Module, ReadOnlyGraph } from 'metro'; +import { mergeConfig } from 'metro'; import * as process from 'process'; import { env } from 'process'; @@ -167,8 +168,8 @@ function excludeSentryWebReplay(config: MetroConfig): MetroConfig { return originalResolver(context, moduleName, platform); } return context.resolveRequest(context, moduleName, platform); - } - } + }, + }, }); } From 3f909f15213e025b419383b128d857b46c5eb752 Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 8 Aug 2024 22:23:28 -0300 Subject: [PATCH 05/34] clearup PT2 --- samples/react-native/index.js | 1 + samples/react-native/metro.config.js | 3 ++- samples/react-native/tsconfig.json | 1 - src/js/tools/metroconfig.ts | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/samples/react-native/index.js b/samples/react-native/index.js index 93d65ae2c..e1dd8be53 100644 --- a/samples/react-native/index.js +++ b/samples/react-native/index.js @@ -1,6 +1,7 @@ /** * @format */ + import { AppRegistry } from 'react-native'; import App from './src/App'; diff --git a/samples/react-native/metro.config.js b/samples/react-native/metro.config.js index ec804e212..9e1e8c7f1 100644 --- a/samples/react-native/metro.config.js +++ b/samples/react-native/metro.config.js @@ -17,7 +17,8 @@ const config = { path.resolve(__dirname, 'node_modules'), `${parentDir}/dist`, `${parentDir}/node_modules`, - ], resolver: { + ], + resolver: { resolveRequest: (context, moduleName, platform) => { if (moduleName.includes('promise/')) { return context.resolveRequest( diff --git a/samples/react-native/tsconfig.json b/samples/react-native/tsconfig.json index c983542f8..361f7005c 100644 --- a/samples/react-native/tsconfig.json +++ b/samples/react-native/tsconfig.json @@ -7,7 +7,6 @@ /* Completeness */ "skipLibCheck": true, /* Skip type checking all .d.ts files. */ "baseUrl": ".", - "paths": { "@sentry/react-native": ["../../"] }, diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 3af69ea40..564a67bb0 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -53,7 +53,7 @@ export function withSentryConfig( newConfig = withSentryBabelTransformer(newConfig); } if (includeWebReplay === false) { - newConfig = excludeSentryWebReplay(config); + newConfig = excludeSentryWebReplay(newConfig); } return newConfig; From 93182968abfda73967f53385c5ee8874748a6106 Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 8 Aug 2024 23:01:59 -0300 Subject: [PATCH 06/34] mergeConfig not compatible with old RN 0.65.3 --- src/js/tools/metroconfig.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 564a67bb0..7959595b3 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -1,6 +1,5 @@ import { logger } from '@sentry/utils'; import type { MetroConfig, MixedOutput, Module, ReadOnlyGraph } from 'metro'; -import { mergeConfig } from 'metro'; import * as process from 'process'; import { env } from 'process'; @@ -158,8 +157,10 @@ function withSentryDebugId(config: MetroConfig): MetroConfig { function excludeSentryWebReplay(config: MetroConfig): MetroConfig { const originalResolver = config.resolver?.resolveRequest; - return mergeConfig(config, { + return { + ...config, resolver: { + ...config.resolver, resolveRequest: (context, moduleName, platform) => { if (moduleName.includes('@sentry/replay')) { return { type: 'empty' }; @@ -170,7 +171,7 @@ function excludeSentryWebReplay(config: MetroConfig): MetroConfig { return context.resolveRequest(context, moduleName, platform); }, }, - }); + } } type MetroFrame = Parameters['symbolicator']>['customizeFrame']>[0]; From 3d1b3a194351398aa6765723565d9b8249c8579c Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 8 Aug 2024 23:15:16 -0300 Subject: [PATCH 07/34] add changelog snippet, also remove it on expo --- CHANGELOG.md | 13 +++++++++++++ src/js/tools/metroconfig.ts | 3 +++ 2 files changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b89e5b79..7cb4ff421 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,19 @@ ### Fixes - Exclude Sentry Web Replay by default, reducing the code in 130KB. ([#4006](https://github.com/getsentry/sentry-react-native/pull/4006)) +You can keep Sentry Web Replay by setting `includeWebReplay`as `true` on your metro config as shown on the snippet: +```js + // For Expo + const { getSentryExpoConfig } = require("@sentry/react-native/metro"); + const config = getSentryExpoConfig(__dirname, { includeWebReplay: true }); + + // For RN + const { getDefaultConfig } = require('@react-native/metro-config'); + const { withSentryConfig } = require('@sentry/react-native/metro'); + module.exports = withSentryConfig(getDefaultConfig(__dirname), { includeWebReplay: true }); + +``` + - Support `metro@0.80.10` new `sourceMapString` export ([#4004](https://github.com/getsentry/sentry-react-native/pull/4004)) - `Sentry.captureMessage` stack trace is in `event.exception` (moved from `event.threads`) ([#3635](https://github.com/getsentry/sentry-react-native/pull/3635), [#3988](https://github.com/getsentry/sentry-react-native/pull/3988)) - To revert to the old behavior (causing the stack to be unsymbolicated) use `useThreadsForMessageStack` option diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 7959595b3..bbf5071e1 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -80,6 +80,9 @@ export function getSentryExpoConfig( if (options.annotateReactComponents) { newConfig = withSentryBabelTransformer(newConfig); } + if (options.includeWebReplay === false) { + newConfig = excludeSentryWebReplay(newConfig); + } return newConfig; } From c0556fc336ed28079a6413e0aeaf34f1884e1824 Mon Sep 17 00:00:00 2001 From: LucasZF Date: Wed, 14 Aug 2024 22:01:25 -0300 Subject: [PATCH 08/34] Update CHANGELOG.md Co-authored-by: Krystof Woldrich <31292499+krystofwoldrich@users.noreply.github.com> --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cb4ff421..0a19f89df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,9 @@ ### Fixes - Exclude Sentry Web Replay by default, reducing the code in 130KB. ([#4006](https://github.com/getsentry/sentry-react-native/pull/4006)) -You can keep Sentry Web Replay by setting `includeWebReplay`as `true` on your metro config as shown on the snippet: -```js + - You can keep Sentry Web Replay by setting `includeWebReplay` to `true` in your metro config as shown in the snippet: + + ```js // For Expo const { getSentryExpoConfig } = require("@sentry/react-native/metro"); const config = getSentryExpoConfig(__dirname, { includeWebReplay: true }); @@ -15,8 +16,7 @@ You can keep Sentry Web Replay by setting `includeWebReplay`as `true` on your me const { getDefaultConfig } = require('@react-native/metro-config'); const { withSentryConfig } = require('@sentry/react-native/metro'); module.exports = withSentryConfig(getDefaultConfig(__dirname), { includeWebReplay: true }); - -``` + ``` - Support `metro@0.80.10` new `sourceMapString` export ([#4004](https://github.com/getsentry/sentry-react-native/pull/4004)) - `Sentry.captureMessage` stack trace is in `event.exception` (moved from `event.threads`) ([#3635](https://github.com/getsentry/sentry-react-native/pull/3635), [#3988](https://github.com/getsentry/sentry-react-native/pull/3988)) From 0799e0e2b82375976a76a3e8a01f10cd325f871c Mon Sep 17 00:00:00 2001 From: LucasZF Date: Wed, 14 Aug 2024 22:01:38 -0300 Subject: [PATCH 09/34] Update src/js/tools/metroconfig.ts Co-authored-by: Krystof Woldrich <31292499+krystofwoldrich@users.noreply.github.com> --- src/js/tools/metroconfig.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index bbf5071e1..7159f3f0e 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -18,6 +18,7 @@ export interface SentryMetroConfigOptions { * @default false */ annotateReactComponents?: boolean; + /** * Adds the Sentry replay package for web. * @default false From 271bebc54f459890f60d3f97e3cd7e4c665604a6 Mon Sep 17 00:00:00 2001 From: lucas Date: Wed, 14 Aug 2024 23:51:01 -0300 Subject: [PATCH 10/34] add tests and requested changes --- src/js/tools/metroconfig.ts | 22 ++++--- test/tools/metroconfig.test.ts | 108 ++++++++++++++++++++++++++++++++- 2 files changed, 120 insertions(+), 10 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 7159f3f0e..07102c4f4 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -18,10 +18,9 @@ export interface SentryMetroConfigOptions { * @default false */ annotateReactComponents?: boolean; - /** * Adds the Sentry replay package for web. - * @default false + * @default false (Mobile) undefined (Web) */ includeWebReplay?: boolean; } @@ -41,7 +40,7 @@ export interface SentryExpoConfigOptions { */ export function withSentryConfig( config: MetroConfig, - { annotateReactComponents = false, includeWebReplay = false }: SentryMetroConfigOptions = {}, + { annotateReactComponents = false, includeWebReplay }: SentryMetroConfigOptions = {}, ): MetroConfig { setSentryMetroDevServerEnvFlag(); @@ -52,8 +51,8 @@ export function withSentryConfig( if (annotateReactComponents) { newConfig = withSentryBabelTransformer(newConfig); } - if (includeWebReplay === false) { - newConfig = excludeSentryWebReplay(newConfig); + if (includeWebReplay !== true) { + newConfig = excludeSentryWebReplay(newConfig, includeWebReplay); } return newConfig; @@ -81,8 +80,9 @@ export function getSentryExpoConfig( if (options.annotateReactComponents) { newConfig = withSentryBabelTransformer(newConfig); } - if (options.includeWebReplay === false) { - newConfig = excludeSentryWebReplay(newConfig); + + if (options.includeWebReplay !== true) { + newConfig = excludeSentryWebReplay(newConfig, options.includeWebReplay); } return newConfig; @@ -158,7 +158,10 @@ function withSentryDebugId(config: MetroConfig): MetroConfig { }; } -function excludeSentryWebReplay(config: MetroConfig): MetroConfig { +/** + * + */ +export function excludeSentryWebReplay(config: MetroConfig, includeWebReplay: boolean | undefined): MetroConfig { const originalResolver = config.resolver?.resolveRequest; return { @@ -166,7 +169,8 @@ function excludeSentryWebReplay(config: MetroConfig): MetroConfig { resolver: { ...config.resolver, resolveRequest: (context, moduleName, platform) => { - if (moduleName.includes('@sentry/replay')) { + if (includeWebReplay === false || platform !== 'web' && + moduleName.includes('@sentry/replay')) { return { type: 'empty' }; } if (originalResolver) { diff --git a/test/tools/metroconfig.test.ts b/test/tools/metroconfig.test.ts index a0ee9533f..9b5205d59 100644 --- a/test/tools/metroconfig.test.ts +++ b/test/tools/metroconfig.test.ts @@ -11,7 +11,7 @@ import type { MetroConfig } from 'metro'; import * as path from 'path'; import * as process from 'process'; -import { withSentryBabelTransformer, withSentryFramesCollapsed } from '../../src/js/tools/metroconfig'; +import { excludeSentryWebReplay,withSentryBabelTransformer, withSentryFramesCollapsed } from '../../src/js/tools/metroconfig'; type MetroFrame = Parameters['symbolicator']>['customizeFrame']>[0]; @@ -108,9 +108,115 @@ describe('metroconfig', () => { ); }); }); + + describe('excludeSentryWebReplay', () => { + let originalResolverMock : any; + + // @ts-expect-error Can't see type CustomResolutionContext + let contextMock : CustomResolutionContext; + let config : MetroConfig = {}; + + beforeEach(() => { + originalResolverMock = jest.fn(); + contextMock = { + resolveRequest: jest.fn(), + }; + + config = { + resolver: { + resolveRequest: originalResolverMock, + }, + }; + }); + + test('keep Web Replay when platform is web and includeWebReplay is true', () => { + const modifiedConfig = excludeSentryWebReplay(config, true); + resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'web'); + + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'web'); + }); + + test('removes Web Replay when platform is web and includeWebReplay is false', () => { + const modifiedConfig = excludeSentryWebReplay(config, false); + const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'web'); + + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); + +/* Test expected to fail but not required since excludeSentryWebReplay is not run when includeWebReplay is true. + test('keep Web Replay when platform is android and includeWebReplay is true', () => { + const modifiedConfig = excludeSentryWebReplay(config, true); + resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); + + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'android'); + }); +*/ + + test('removes Web Replay when platform is android and includeWebReplay is false', () => { + const modifiedConfig = excludeSentryWebReplay(config, false); + const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); + + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); + + test('removes Web Replay when platform is android and includeWebReplay is undefined', () => { + const modifiedConfig = excludeSentryWebReplay(config, undefined); + const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); + + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); + +/* Test expected to fail but not required since excludeSentryWebReplay is not run when includeWebReplay is true. + test('keep Web Replay when platform is ios and includeWebReplay is true', () => { + const modifiedConfig = excludeSentryWebReplay(config, true); + resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); + + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'ios'); + }); +*/ + + test('removes Web Replay when platform is ios and includeWebReplay is false', () => { + const modifiedConfig = excludeSentryWebReplay(config, false); + const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); + + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); + + test('removes Web Replay when platform is ios and includeWebReplay is undefined', () => { + const modifiedConfig = excludeSentryWebReplay(config, undefined); + const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); + + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); + + test('calls originalResolver when moduleName is not @sentry/replay', () => { + const modifiedConfig = excludeSentryWebReplay(config, true); + const moduleName = 'some/other/module'; + resolveRequest(modifiedConfig,contextMock, moduleName, 'web'); + + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, moduleName, 'web'); + }); + + test('calls context.resolveRequest when originalResolver is not provided', () => { + const modifiedConfig = excludeSentryWebReplay({ resolver: {} }, true); + const moduleName = 'some/other/module'; + resolveRequest(modifiedConfig,contextMock, moduleName, 'web'); + + expect(contextMock.resolveRequest).toHaveBeenCalledWith(contextMock, moduleName, 'web'); + }); + }); }); // function create mock metro frame function createMockSentryInstrumentMetroFrame(): MetroFrame { return { file: 'node_modules/@sentry/utils/cjs/instrument.js' }; } + +// @ts-expect-error Can't see type Resolution. +function resolveRequest(metroConfig: MetroConfig, context: any, moduleName: string, platform: string): Resolution { + return metroConfig.resolver?.resolveRequest && metroConfig.resolver.resolveRequest(context, moduleName, platform);} From 060294d3ac77aa960822c1522fc4560b95ce2930 Mon Sep 17 00:00:00 2001 From: lucas Date: Wed, 14 Aug 2024 23:53:07 -0300 Subject: [PATCH 11/34] changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2e73fe81..6457603d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,15 @@ ## Unreleased +### Features + - Add `spotlight` option ([#4023](https://github.com/getsentry/sentry-react-native/pull/4023)) - Deprecating `enableSpotlight` and `spotlightSidecarUrl` +### Fixes + +- Exclude Sentry Web Replay on mobile by default, reducing the code in 130KB. ([#4006](https://github.com/getsentry/sentry-react-native/pull/4006)) + ## 5.29.0 ### Features From 27132ce7c6557df1c9ed081ef732ddbe44fbace3 Mon Sep 17 00:00:00 2001 From: lucas Date: Wed, 14 Aug 2024 23:53:41 -0300 Subject: [PATCH 12/34] fix --- src/js/tools/metroconfig.ts | 5 ++--- test/tools/metroconfig.test.ts | 23 ++++++++++++++--------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 07102c4f4..8bebc2329 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -169,8 +169,7 @@ export function excludeSentryWebReplay(config: MetroConfig, includeWebReplay: bo resolver: { ...config.resolver, resolveRequest: (context, moduleName, platform) => { - if (includeWebReplay === false || platform !== 'web' && - moduleName.includes('@sentry/replay')) { + if (includeWebReplay === false || (platform !== 'web' && moduleName.includes('@sentry/replay'))) { return { type: 'empty' }; } if (originalResolver) { @@ -179,7 +178,7 @@ export function excludeSentryWebReplay(config: MetroConfig, includeWebReplay: bo return context.resolveRequest(context, moduleName, platform); }, }, - } + }; } type MetroFrame = Parameters['symbolicator']>['customizeFrame']>[0]; diff --git a/test/tools/metroconfig.test.ts b/test/tools/metroconfig.test.ts index 9b5205d59..9957cbfc4 100644 --- a/test/tools/metroconfig.test.ts +++ b/test/tools/metroconfig.test.ts @@ -11,7 +11,11 @@ import type { MetroConfig } from 'metro'; import * as path from 'path'; import * as process from 'process'; -import { excludeSentryWebReplay,withSentryBabelTransformer, withSentryFramesCollapsed } from '../../src/js/tools/metroconfig'; +import { + excludeSentryWebReplay, + withSentryBabelTransformer, + withSentryFramesCollapsed, +} from '../../src/js/tools/metroconfig'; type MetroFrame = Parameters['symbolicator']>['customizeFrame']>[0]; @@ -110,11 +114,11 @@ describe('metroconfig', () => { }); describe('excludeSentryWebReplay', () => { - let originalResolverMock : any; + let originalResolverMock: any; // @ts-expect-error Can't see type CustomResolutionContext - let contextMock : CustomResolutionContext; - let config : MetroConfig = {}; + let contextMock: CustomResolutionContext; + let config: MetroConfig = {}; beforeEach(() => { originalResolverMock = jest.fn(); @@ -144,7 +148,7 @@ describe('metroconfig', () => { expect(originalResolverMock).not.toHaveBeenCalled(); }); -/* Test expected to fail but not required since excludeSentryWebReplay is not run when includeWebReplay is true. + /* Test expected to fail but not required since excludeSentryWebReplay is not run when includeWebReplay is true. test('keep Web Replay when platform is android and includeWebReplay is true', () => { const modifiedConfig = excludeSentryWebReplay(config, true); resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); @@ -169,7 +173,7 @@ describe('metroconfig', () => { expect(originalResolverMock).not.toHaveBeenCalled(); }); -/* Test expected to fail but not required since excludeSentryWebReplay is not run when includeWebReplay is true. + /* Test expected to fail but not required since excludeSentryWebReplay is not run when includeWebReplay is true. test('keep Web Replay when platform is ios and includeWebReplay is true', () => { const modifiedConfig = excludeSentryWebReplay(config, true); resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); @@ -197,7 +201,7 @@ describe('metroconfig', () => { test('calls originalResolver when moduleName is not @sentry/replay', () => { const modifiedConfig = excludeSentryWebReplay(config, true); const moduleName = 'some/other/module'; - resolveRequest(modifiedConfig,contextMock, moduleName, 'web'); + resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); expect(originalResolverMock).toHaveBeenCalledWith(contextMock, moduleName, 'web'); }); @@ -205,7 +209,7 @@ describe('metroconfig', () => { test('calls context.resolveRequest when originalResolver is not provided', () => { const modifiedConfig = excludeSentryWebReplay({ resolver: {} }, true); const moduleName = 'some/other/module'; - resolveRequest(modifiedConfig,contextMock, moduleName, 'web'); + resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); expect(contextMock.resolveRequest).toHaveBeenCalledWith(contextMock, moduleName, 'web'); }); @@ -219,4 +223,5 @@ function createMockSentryInstrumentMetroFrame(): MetroFrame { // @ts-expect-error Can't see type Resolution. function resolveRequest(metroConfig: MetroConfig, context: any, moduleName: string, platform: string): Resolution { - return metroConfig.resolver?.resolveRequest && metroConfig.resolver.resolveRequest(context, moduleName, platform);} + return metroConfig.resolver?.resolveRequest && metroConfig.resolver.resolveRequest(context, moduleName, platform); +} From e6636791296467c0391f36077c0e6a7927049c61 Mon Sep 17 00:00:00 2001 From: Krystof Woldrich <31292499+krystofwoldrich@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:14:52 +0200 Subject: [PATCH 13/34] bad merge --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 226312079..db9c642e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,8 +27,6 @@ ### Features -### Features - - Add `spotlight` option ([#4023](https://github.com/getsentry/sentry-react-native/pull/4023)) - Deprecating `enableSpotlight` and `spotlightSidecarUrl` From 262c1a71b9a1c880ba3c49c160557740c0be46a4 Mon Sep 17 00:00:00 2001 From: Krystof Woldrich <31292499+krystofwoldrich@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:15:56 +0200 Subject: [PATCH 14/34] Update CHANGELOG.md change to feature --- CHANGELOG.md | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db9c642e8..97131f569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,21 @@ ## Unreleased -### Fixes +### Features + +- Exclude Sentry Web Replay by default, reducing the code in 130KB. ([#4006](https://github.com/getsentry/sentry-react-native/pull/4006)) + - You can keep Sentry Web Replay by setting `includeWebReplay` to `true` in your metro config as shown in the snippet: -- Exclude Sentry Web Replay on mobile by default, reducing the code in 130KB. ([#4006](https://github.com/getsentry/sentry-react-native/pull/4006)) + ```js + // For Expo + const { getSentryExpoConfig } = require("@sentry/react-native/metro"); + const config = getSentryExpoConfig(__dirname, { includeWebReplay: true }); + + // For RN + const { getDefaultConfig } = require('@react-native/metro-config'); + const { withSentryConfig } = require('@sentry/react-native/metro'); + module.exports = withSentryConfig(getDefaultConfig(__dirname), { includeWebReplay: true }); + ``` ## 5.31.0 @@ -66,20 +78,6 @@ ### Fixes -- Exclude Sentry Web Replay by default, reducing the code in 130KB. ([#4006](https://github.com/getsentry/sentry-react-native/pull/4006)) - - You can keep Sentry Web Replay by setting `includeWebReplay` to `true` in your metro config as shown in the snippet: - - ```js - // For Expo - const { getSentryExpoConfig } = require("@sentry/react-native/metro"); - const config = getSentryExpoConfig(__dirname, { includeWebReplay: true }); - - // For RN - const { getDefaultConfig } = require('@react-native/metro-config'); - const { withSentryConfig } = require('@sentry/react-native/metro'); - module.exports = withSentryConfig(getDefaultConfig(__dirname), { includeWebReplay: true }); - ``` - - Support `metro@0.80.10` new `sourceMapString` export ([#4004](https://github.com/getsentry/sentry-react-native/pull/4004)) - `Sentry.captureMessage` stack trace is in `event.exception` (moved from `event.threads`) ([#3635](https://github.com/getsentry/sentry-react-native/pull/3635), [#3988](https://github.com/getsentry/sentry-react-native/pull/3988)) - To revert to the old behavior (causing the stack to be unsymbolicated) use `useThreadsForMessageStack` option From ea84b51da6fc0f916b456d4ef22f60646dcdfd9e Mon Sep 17 00:00:00 2001 From: lucas Date: Fri, 30 Aug 2024 12:49:35 -0300 Subject: [PATCH 15/34] requested changes --- src/js/tools/metroconfig.ts | 13 ++++++------ test/tools/metroconfig.test.ts | 36 +++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 8bebc2329..67bb2c241 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -20,7 +20,7 @@ export interface SentryMetroConfigOptions { annotateReactComponents?: boolean; /** * Adds the Sentry replay package for web. - * @default false (Mobile) undefined (Web) + * @default false (Mobile) true (Web) */ includeWebReplay?: boolean; } @@ -52,7 +52,7 @@ export function withSentryConfig( newConfig = withSentryBabelTransformer(newConfig); } if (includeWebReplay !== true) { - newConfig = excludeSentryWebReplay(newConfig, includeWebReplay); + newConfig = withSentryResolver(newConfig, includeWebReplay); } return newConfig; @@ -82,7 +82,7 @@ export function getSentryExpoConfig( } if (options.includeWebReplay !== true) { - newConfig = excludeSentryWebReplay(newConfig, options.includeWebReplay); + newConfig = withSentryResolver(newConfig, options.includeWebReplay); } return newConfig; @@ -159,9 +159,9 @@ function withSentryDebugId(config: MetroConfig): MetroConfig { } /** - * + * Includes `@sentry/replay` packages based on the `includeWebReplay` flag and current bundle `platform`. */ -export function excludeSentryWebReplay(config: MetroConfig, includeWebReplay: boolean | undefined): MetroConfig { +export function withSentryResolver(config: MetroConfig, includeWebReplay: boolean | undefined): MetroConfig { const originalResolver = config.resolver?.resolveRequest; return { @@ -169,7 +169,8 @@ export function excludeSentryWebReplay(config: MetroConfig, includeWebReplay: bo resolver: { ...config.resolver, resolveRequest: (context, moduleName, platform) => { - if (includeWebReplay === false || (platform !== 'web' && moduleName.includes('@sentry/replay'))) { + if ((includeWebReplay === false || (includeWebReplay === undefined && platform !== 'web')) + && moduleName.includes('@sentry/replay')) { return { type: 'empty' }; } if (originalResolver) { diff --git a/test/tools/metroconfig.test.ts b/test/tools/metroconfig.test.ts index 9957cbfc4..3fb6f752a 100644 --- a/test/tools/metroconfig.test.ts +++ b/test/tools/metroconfig.test.ts @@ -12,9 +12,9 @@ import * as path from 'path'; import * as process from 'process'; import { - excludeSentryWebReplay, withSentryBabelTransformer, withSentryFramesCollapsed, + withSentryResolver, } from '../../src/js/tools/metroconfig'; type MetroFrame = Parameters['symbolicator']>['customizeFrame']>[0]; @@ -113,7 +113,7 @@ describe('metroconfig', () => { }); }); - describe('excludeSentryWebReplay', () => { + describe('withSentryResolver', () => { let originalResolverMock: any; // @ts-expect-error Can't see type CustomResolutionContext @@ -134,31 +134,29 @@ describe('metroconfig', () => { }); test('keep Web Replay when platform is web and includeWebReplay is true', () => { - const modifiedConfig = excludeSentryWebReplay(config, true); + const modifiedConfig = withSentryResolver(config, true); resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'web'); expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'web'); }); test('removes Web Replay when platform is web and includeWebReplay is false', () => { - const modifiedConfig = excludeSentryWebReplay(config, false); + const modifiedConfig = withSentryResolver(config, false); const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'web'); expect(result).toEqual({ type: 'empty' }); expect(originalResolverMock).not.toHaveBeenCalled(); }); - /* Test expected to fail but not required since excludeSentryWebReplay is not run when includeWebReplay is true. test('keep Web Replay when platform is android and includeWebReplay is true', () => { - const modifiedConfig = excludeSentryWebReplay(config, true); + const modifiedConfig = withSentryResolver(config, true); resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'android'); }); -*/ test('removes Web Replay when platform is android and includeWebReplay is false', () => { - const modifiedConfig = excludeSentryWebReplay(config, false); + const modifiedConfig = withSentryResolver(config, false); const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); expect(result).toEqual({ type: 'empty' }); @@ -166,24 +164,22 @@ describe('metroconfig', () => { }); test('removes Web Replay when platform is android and includeWebReplay is undefined', () => { - const modifiedConfig = excludeSentryWebReplay(config, undefined); + const modifiedConfig = withSentryResolver(config, undefined); const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); expect(result).toEqual({ type: 'empty' }); expect(originalResolverMock).not.toHaveBeenCalled(); }); - /* Test expected to fail but not required since excludeSentryWebReplay is not run when includeWebReplay is true. test('keep Web Replay when platform is ios and includeWebReplay is true', () => { - const modifiedConfig = excludeSentryWebReplay(config, true); + const modifiedConfig = withSentryResolver(config, true); resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'ios'); }); -*/ test('removes Web Replay when platform is ios and includeWebReplay is false', () => { - const modifiedConfig = excludeSentryWebReplay(config, false); + const modifiedConfig = withSentryResolver(config, false); const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); expect(result).toEqual({ type: 'empty' }); @@ -191,7 +187,7 @@ describe('metroconfig', () => { }); test('removes Web Replay when platform is ios and includeWebReplay is undefined', () => { - const modifiedConfig = excludeSentryWebReplay(config, undefined); + const modifiedConfig = withSentryResolver(config, undefined); const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); expect(result).toEqual({ type: 'empty' }); @@ -199,7 +195,15 @@ describe('metroconfig', () => { }); test('calls originalResolver when moduleName is not @sentry/replay', () => { - const modifiedConfig = excludeSentryWebReplay(config, true); + const modifiedConfig = withSentryResolver(config, true); + const moduleName = 'some/other/module'; + resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); + + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, moduleName, 'web'); + }); + + test('calls originalResolver when moduleName is not @sentry/replay and includeWebReplay set to false', () => { + const modifiedConfig = withSentryResolver(config, false); const moduleName = 'some/other/module'; resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); @@ -207,7 +211,7 @@ describe('metroconfig', () => { }); test('calls context.resolveRequest when originalResolver is not provided', () => { - const modifiedConfig = excludeSentryWebReplay({ resolver: {} }, true); + const modifiedConfig = withSentryResolver({ resolver: {} }, true); const moduleName = 'some/other/module'; resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); From ff7a00141445de2dc44c5d685ddda516a274203f Mon Sep 17 00:00:00 2001 From: lucas Date: Mon, 2 Sep 2024 19:40:30 -0300 Subject: [PATCH 16/34] lint fix --- src/js/tools/metroconfig.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 67bb2c241..b508705fe 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -169,8 +169,10 @@ export function withSentryResolver(config: MetroConfig, includeWebReplay: boolea resolver: { ...config.resolver, resolveRequest: (context, moduleName, platform) => { - if ((includeWebReplay === false || (includeWebReplay === undefined && platform !== 'web')) - && moduleName.includes('@sentry/replay')) { + if ( + (includeWebReplay === false || (includeWebReplay === undefined && platform !== 'web')) && + moduleName.includes('@sentry/replay') + ) { return { type: 'empty' }; } if (originalResolver) { From 984c19e4c6a3988cbdee50df520f5226bfa042de Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 3 Sep 2024 11:08:30 -0300 Subject: [PATCH 17/34] test disable code --- src/js/tools/metroconfig.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index b508705fe..8014ab300 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -51,7 +51,8 @@ export function withSentryConfig( if (annotateReactComponents) { newConfig = withSentryBabelTransformer(newConfig); } - if (includeWebReplay !== true) { + const tes = 2; + if (includeWebReplay !== true && 2 == tes-1) { newConfig = withSentryResolver(newConfig, includeWebReplay); } @@ -80,8 +81,9 @@ export function getSentryExpoConfig( if (options.annotateReactComponents) { newConfig = withSentryBabelTransformer(newConfig); } + const tes = 2; - if (options.includeWebReplay !== true) { + if (options.includeWebReplay !== true && 2 == tes-1) { newConfig = withSentryResolver(newConfig, options.includeWebReplay); } From 9b155ed335f223ce1dc278bf60b53f83155fad3e Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 3 Sep 2024 14:58:32 -0300 Subject: [PATCH 18/34] test compatibility with old metro --- .gitignore | 2 +- src/js/tools/metroconfig.ts | 89 +++++++++++++++++++++++++++------- test/tools/metroconfig.test.ts | 5 ++ 3 files changed, 77 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index e10f2c3b6..a34c5a185 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ node_modules # Mac OS X .DS_Store - +samples/MySampleApp653 # Xcode ## Build generated diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 8014ab300..7d0d5bd80 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -1,5 +1,6 @@ import { logger } from '@sentry/utils'; import type { MetroConfig, MixedOutput, Module, ReadOnlyGraph } from 'metro'; +import type { CustomResolutionContext, Resolution } from 'metro-resolver'; import * as process from 'process'; import { env } from 'process'; @@ -7,7 +8,6 @@ import { enableLogger } from './enableLogger'; import { cleanDefaultBabelTransformerPath, saveDefaultBabelTransformerPath } from './sentryBabelTransformerUtils'; import { createSentryMetroSerializer, unstable_beforeAssetSerializationPlugin } from './sentryMetroSerializer'; import type { DefaultConfigOptions } from './vendor/expo/expoconfig'; - export * from './sentryMetroSerializer'; enableLogger(); @@ -51,8 +51,7 @@ export function withSentryConfig( if (annotateReactComponents) { newConfig = withSentryBabelTransformer(newConfig); } - const tes = 2; - if (includeWebReplay !== true && 2 == tes-1) { + if (includeWebReplay !== true) { newConfig = withSentryResolver(newConfig, includeWebReplay); } @@ -81,9 +80,8 @@ export function getSentryExpoConfig( if (options.annotateReactComponents) { newConfig = withSentryBabelTransformer(newConfig); } - const tes = 2; - if (options.includeWebReplay !== true && 2 == tes-1) { + if (options.includeWebReplay !== true) { newConfig = withSentryResolver(newConfig, options.includeWebReplay); } @@ -160,28 +158,83 @@ function withSentryDebugId(config: MetroConfig): MetroConfig { }; } +type ResolverThreeParams = ( + context: CustomResolutionContext, + moduleName: string, + platform: string | null, +) => Resolution; +type ResolverFourParams = ( + context: CustomResolutionContext, + moduleName: string, + platform: string | null, + realModuleName?: string, +) => Resolution; + /** * Includes `@sentry/replay` packages based on the `includeWebReplay` flag and current bundle `platform`. */ export function withSentryResolver(config: MetroConfig, includeWebReplay: boolean | undefined): MetroConfig { - const originalResolver = config.resolver?.resolveRequest; + const originalResolver = config.resolver?.resolveRequest as ResolverThreeParams | ResolverFourParams; + + const hasSentryReplay = (platform: string | null, moduleName: string): boolean => { + return ( + (includeWebReplay === false || (includeWebReplay === undefined && platform !== 'web')) && + moduleName.includes('@sentry/replay') + ); + }; + + let resolver: ResolverThreeParams | ResolverFourParams; + + // eslint-disable-next-line @typescript-eslint/no-var-requires + const metro = require('metro/package.json') as { version: string }; + const [major, minor] = metro.version.split('.').map(Number); + + if (minor >= 68 || major >= 1) { + // New method introduced on metro 0.68 and newer. + resolver = (context: CustomResolutionContext, moduleName: string, platform: string | null) => { + if (hasSentryReplay(platform, moduleName)) { + return { type: 'empty' } as Resolution; + } + if (originalResolver) { + return originalResolver(context, moduleName, platform); + } + return context.resolveRequest(context, moduleName, platform); + }; + } else { + // On older Metro, the given context from resolver is not the defaultResolver but the called function itself. + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-var-requires, import/no-extraneous-dependencies + const defaultResolver = require('metro-resolver').resolve; + + resolver = ( + context: CustomResolutionContext, + realModuleName: string, + platform: string | null, + moduleName?: string, + ) => { + if (moduleName && hasSentryReplay(platform, moduleName)) { + return { type: 'empty' }; + } + if (originalResolver) { + return originalResolver(context, realModuleName, platform, moduleName); + } + + return defaultResolver( + { + ...context, + resolveRequest: null, + }, + moduleName, + platform, + realModuleName, + ); + }; + } return { ...config, resolver: { ...config.resolver, - resolveRequest: (context, moduleName, platform) => { - if ( - (includeWebReplay === false || (includeWebReplay === undefined && platform !== 'web')) && - moduleName.includes('@sentry/replay') - ) { - return { type: 'empty' }; - } - if (originalResolver) { - return originalResolver(context, moduleName, platform); - } - return context.resolveRequest(context, moduleName, platform); - }, + resolveRequest: resolver, }, }; } diff --git a/test/tools/metroconfig.test.ts b/test/tools/metroconfig.test.ts index 3fb6f752a..1ae713004 100644 --- a/test/tools/metroconfig.test.ts +++ b/test/tools/metroconfig.test.ts @@ -19,6 +19,11 @@ import { type MetroFrame = Parameters['symbolicator']>['customizeFrame']>[0]; +// Mock metro/package.json +jest.mock('metro/package.json', () => ({ + version: '0.70.0', +})); + describe('metroconfig', () => { beforeEach(() => { jest.clearAllMocks(); From 661a8d00e33b36c7177c27163d5dd9e34791cb1a Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 3 Sep 2024 20:24:14 -0300 Subject: [PATCH 19/34] add tests for old metro --- .gitignore | 2 +- test/tools/metroconfig.test.ts | 275 +++++++++++++++++++++++++-------- 2 files changed, 209 insertions(+), 68 deletions(-) diff --git a/.gitignore b/.gitignore index a34c5a185..e10f2c3b6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ node_modules # Mac OS X .DS_Store -samples/MySampleApp653 + # Xcode ## Build generated diff --git a/test/tools/metroconfig.test.ts b/test/tools/metroconfig.test.ts index 1ae713004..8677b6280 100644 --- a/test/tools/metroconfig.test.ts +++ b/test/tools/metroconfig.test.ts @@ -19,11 +19,6 @@ import { type MetroFrame = Parameters['symbolicator']>['customizeFrame']>[0]; -// Mock metro/package.json -jest.mock('metro/package.json', () => ({ - version: '0.70.0', -})); - describe('metroconfig', () => { beforeEach(() => { jest.clearAllMocks(); @@ -138,89 +133,216 @@ describe('metroconfig', () => { }; }); - test('keep Web Replay when platform is web and includeWebReplay is true', () => { - const modifiedConfig = withSentryResolver(config, true); - resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'web'); + describe('on new metro', () => { + beforeEach(() => { + jest.resetModules(); + // Mock metro/package.json + jest.mock('metro/package.json', () => ({ + version: '0.70.0', + })); + }); - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'web'); - }); + test('keep Web Replay when platform is web and includeWebReplay is true', () => { + const modifiedConfig = withSentryResolver(config, true); + resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'web'); - test('removes Web Replay when platform is web and includeWebReplay is false', () => { - const modifiedConfig = withSentryResolver(config, false); - const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'web'); + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'web'); + }); - expect(result).toEqual({ type: 'empty' }); - expect(originalResolverMock).not.toHaveBeenCalled(); - }); + test('removes Web Replay when platform is web and includeWebReplay is false', () => { + const modifiedConfig = withSentryResolver(config, false); + const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'web'); - test('keep Web Replay when platform is android and includeWebReplay is true', () => { - const modifiedConfig = withSentryResolver(config, true); - resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'android'); - }); + test('keep Web Replay when platform is android and includeWebReplay is true', () => { + const modifiedConfig = withSentryResolver(config, true); + resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); - test('removes Web Replay when platform is android and includeWebReplay is false', () => { - const modifiedConfig = withSentryResolver(config, false); - const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'android'); + }); - expect(result).toEqual({ type: 'empty' }); - expect(originalResolverMock).not.toHaveBeenCalled(); - }); + test('removes Web Replay when platform is android and includeWebReplay is false', () => { + const modifiedConfig = withSentryResolver(config, false); + const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); - test('removes Web Replay when platform is android and includeWebReplay is undefined', () => { - const modifiedConfig = withSentryResolver(config, undefined); - const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); - expect(result).toEqual({ type: 'empty' }); - expect(originalResolverMock).not.toHaveBeenCalled(); - }); + test('removes Web Replay when platform is android and includeWebReplay is undefined', () => { + const modifiedConfig = withSentryResolver(config, undefined); + const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); - test('keep Web Replay when platform is ios and includeWebReplay is true', () => { - const modifiedConfig = withSentryResolver(config, true); - resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'ios'); - }); + test('keep Web Replay when platform is ios and includeWebReplay is true', () => { + const modifiedConfig = withSentryResolver(config, true); + resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); - test('removes Web Replay when platform is ios and includeWebReplay is false', () => { - const modifiedConfig = withSentryResolver(config, false); - const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'ios'); + }); - expect(result).toEqual({ type: 'empty' }); - expect(originalResolverMock).not.toHaveBeenCalled(); - }); + test('removes Web Replay when platform is ios and includeWebReplay is false', () => { + const modifiedConfig = withSentryResolver(config, false); + const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); - test('removes Web Replay when platform is ios and includeWebReplay is undefined', () => { - const modifiedConfig = withSentryResolver(config, undefined); - const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); - expect(result).toEqual({ type: 'empty' }); - expect(originalResolverMock).not.toHaveBeenCalled(); - }); + test('removes Web Replay when platform is ios and includeWebReplay is undefined', () => { + const modifiedConfig = withSentryResolver(config, undefined); + const result = resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); - test('calls originalResolver when moduleName is not @sentry/replay', () => { - const modifiedConfig = withSentryResolver(config, true); - const moduleName = 'some/other/module'; - resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, moduleName, 'web'); - }); + test('calls originalResolver when moduleName is not @sentry/replay', () => { + const modifiedConfig = withSentryResolver(config, true); + const moduleName = 'some/other/module'; + resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); + + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, moduleName, 'web'); + }); + + test('calls originalResolver when moduleName is not @sentry/replay and includeWebReplay set to false', () => { + const modifiedConfig = withSentryResolver(config, false); + const moduleName = 'some/other/module'; + resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); - test('calls originalResolver when moduleName is not @sentry/replay and includeWebReplay set to false', () => { - const modifiedConfig = withSentryResolver(config, false); - const moduleName = 'some/other/module'; - resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, moduleName, 'web'); + }); + + test('calls context.resolveRequest when originalResolver is not provided', () => { + const modifiedConfig = withSentryResolver({ resolver: {} }, true); + const moduleName = 'some/other/module'; + resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, moduleName, 'web'); + expect(contextMock.resolveRequest).toHaveBeenCalledWith(contextMock, moduleName, 'web'); + }); }); - test('calls context.resolveRequest when originalResolver is not provided', () => { - const modifiedConfig = withSentryResolver({ resolver: {} }, true); - const moduleName = 'some/other/module'; - resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); + describe('on old metro', () => { + beforeEach(() => { + jest.resetModules(); + // Mock metro/package.json + jest.mock('metro/package.json', () => ({ + version: '0.67.0', + })); + + jest.mock('metro-resolver', () => ({ + resolve: jest.fn(), + })); + }); + + test('keep Web Replay when platform is web and includeWebReplay is true', () => { + const modifiedConfig = withSentryResolver(config, true); + resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'web', '@sentry/replay'); + + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, 'real@sentry/replay', 'web', '@sentry/replay'); + }); + + test('removes Web Replay when platform is web and includeWebReplay is false', () => { + const modifiedConfig = withSentryResolver(config, false); + const result = resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'web', '@sentry/replay'); + + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); + + test('keep Web Replay when platform is android and includeWebReplay is true', () => { + const modifiedConfig = withSentryResolver(config, true); + resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'android', '@sentry/replay'); + + expect(originalResolverMock).toHaveBeenCalledWith( + contextMock, + 'real@sentry/replay', + 'android', + '@sentry/replay', + ); + }); + + test('removes Web Replay when platform is android and includeWebReplay is false', () => { + const modifiedConfig = withSentryResolver(config, false); + const result = resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'android', '@sentry/replay'); + + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); + + test('removes Web Replay when platform is android and includeWebReplay is undefined', () => { + const modifiedConfig = withSentryResolver(config, undefined); + const result = resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'android', '@sentry/replay'); + + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); + + test('keep Web Replay when platform is ios and includeWebReplay is true', () => { + const modifiedConfig = withSentryResolver(config, true); + resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'ios', '@sentry/replay'); + + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, 'real@sentry/replay', 'ios', '@sentry/replay'); + }); - expect(contextMock.resolveRequest).toHaveBeenCalledWith(contextMock, moduleName, 'web'); + test('removes Web Replay when platform is ios and includeWebReplay is false', () => { + const modifiedConfig = withSentryResolver(config, false); + const result = resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'ios', '@sentry/replay'); + + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); + + test('removes Web Replay when platform is ios and includeWebReplay is undefined', () => { + const modifiedConfig = withSentryResolver(config, undefined); + const result = resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'ios', '@sentry/replay'); + + expect(result).toEqual({ type: 'empty' }); + expect(originalResolverMock).not.toHaveBeenCalled(); + }); + + test('calls originalResolver when moduleName is not @sentry/replay', () => { + const modifiedConfig = withSentryResolver(config, true); + const moduleName = 'some/other/module'; + const realModuleName = `real${moduleName}`; + resolveRequest(modifiedConfig, contextMock, realModuleName, 'web', moduleName); + + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, realModuleName, 'web', moduleName); + }); + + test('calls originalResolver when moduleName is not @sentry/replay and includeWebReplay set to false', () => { + const modifiedConfig = withSentryResolver(config, false); + const moduleName = 'some/other/module'; + const realModuleName = `real${moduleName}`; + resolveRequest(modifiedConfig, contextMock, realModuleName, 'web', moduleName); + + expect(originalResolverMock).toHaveBeenCalledWith(contextMock, realModuleName, 'web', moduleName); + }); + + test('calls default resolver when originalResolver is not provided', () => { + const resolve = require('metro-resolver').resolve; + const modifiedConfig = withSentryResolver({ resolver: {} }, true); + const moduleName = 'some/other/module'; + const realModuleName = `real${moduleName}`; + resolveRequest(modifiedConfig, contextMock, realModuleName, 'web', moduleName); + + expect(contextMock.resolveRequest).not.toHaveBeenCalled(); + expect(resolve).toHaveBeenCalledWith( + { + ...contextMock, + resolveRequest: null, + }, + moduleName, + 'web', + realModuleName, + ); + }); }); }); }); @@ -230,7 +352,26 @@ function createMockSentryInstrumentMetroFrame(): MetroFrame { return { file: 'node_modules/@sentry/utils/cjs/instrument.js' }; } +type ResolverFourParams = ( + // @ts-expect-error Can't see type CustomResolutionContext + context: CustomResolutionContext, + moduleName: string, + platform: string | null, + realModuleName?: string, + // @ts-expect-error Can't see type CustomResolutionContext +) => Resolution; + // @ts-expect-error Can't see type Resolution. -function resolveRequest(metroConfig: MetroConfig, context: any, moduleName: string, platform: string): Resolution { +function resolveRequest( + metroConfig: MetroConfig, + context: any, + moduleName: string, + platform: string, + moduleNameOldMetro?: string, +): Resolution { + if (moduleNameOldMetro) { + const resolver = metroConfig.resolver?.resolveRequest as ResolverFourParams; + return resolver(context, moduleName, platform, moduleNameOldMetro); + } return metroConfig.resolver?.resolveRequest && metroConfig.resolver.resolveRequest(context, moduleName, platform); } From cf29b11382239e88d8a40b3fa518fe06bd083a20 Mon Sep 17 00:00:00 2001 From: lucas Date: Wed, 4 Sep 2024 18:33:15 -0300 Subject: [PATCH 20/34] unified tests and replay check --- src/js/tools/metroconfig.ts | 101 ++++++++-------- test/tools/metroconfig.test.ts | 206 +++++++++++---------------------- 2 files changed, 119 insertions(+), 188 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 7d0d5bd80..dc64a1f82 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -1,6 +1,6 @@ import { logger } from '@sentry/utils'; import type { MetroConfig, MixedOutput, Module, ReadOnlyGraph } from 'metro'; -import type { CustomResolutionContext, Resolution } from 'metro-resolver'; +import type { CustomResolutionContext, CustomResolver, Resolution } from 'metro-resolver'; import * as process from 'process'; import { env } from 'process'; @@ -158,83 +158,80 @@ function withSentryDebugId(config: MetroConfig): MetroConfig { }; } -type ResolverThreeParams = ( +// Based on: https://github.com/facebook/metro/blob/c21daba415ea26511e157f794689caab9abe8236/packages/metro-resolver/src/resolve.js#L86-L91 +type CustomResolverBeforeMetro067 = ( context: CustomResolutionContext, - moduleName: string, + realModuleName: string, platform: string | null, -) => Resolution; -type ResolverFourParams = ( - context: CustomResolutionContext, - moduleName: string, - platform: string | null, - realModuleName?: string, + moduleName?: string, ) => Resolution; /** * Includes `@sentry/replay` packages based on the `includeWebReplay` flag and current bundle `platform`. */ export function withSentryResolver(config: MetroConfig, includeWebReplay: boolean | undefined): MetroConfig { - const originalResolver = config.resolver?.resolveRequest as ResolverThreeParams | ResolverFourParams; - - const hasSentryReplay = (platform: string | null, moduleName: string): boolean => { - return ( - (includeWebReplay === false || (includeWebReplay === undefined && platform !== 'web')) && - moduleName.includes('@sentry/replay') - ); - }; - - let resolver: ResolverThreeParams | ResolverFourParams; + const originalResolver = config.resolver?.resolveRequest as CustomResolver | CustomResolverBeforeMetro067 | undefined; // eslint-disable-next-line @typescript-eslint/no-var-requires const metro = require('metro/package.json') as { version: string }; const [major, minor] = metro.version.split('.').map(Number); - if (minor >= 68 || major >= 1) { - // New method introduced on metro 0.68 and newer. - resolver = (context: CustomResolutionContext, moduleName: string, platform: string | null) => { - if (hasSentryReplay(platform, moduleName)) { - return { type: 'empty' } as Resolution; - } - if (originalResolver) { - return originalResolver(context, moduleName, platform); - } - return context.resolveRequest(context, moduleName, platform); - }; - } else { - // On older Metro, the given context from resolver is not the defaultResolver but the called function itself. - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-var-requires, import/no-extraneous-dependencies - const defaultResolver = require('metro-resolver').resolve; - - resolver = ( - context: CustomResolutionContext, - realModuleName: string, - platform: string | null, - moduleName?: string, - ) => { - if (moduleName && hasSentryReplay(platform, moduleName)) { - return { type: 'empty' }; - } - if (originalResolver) { - return originalResolver(context, realModuleName, platform, moduleName); + let defaultMetro067Resolver: CustomResolverBeforeMetro067 | undefined; + if (major == 0 && minor < 68) { + if (originalResolver === undefined) { + try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-var-requires, import/no-extraneous-dependencies + defaultMetro067Resolver = require('metro-resolver').resolve; + logger.log( + `[@sentry/react-native/metro] Using 'resolve' function from 'metro-resolver/src/resolve' as the default resolver on metro config.`, + ); + } catch (error) { + logger.error( + `[@sentry/react-native/metro] Cannot find 'resolve' function in 'metro-resolver/src/resolve'. +Please check the version of Metro you are using and report the issue at http://www.github.com/getsentry/sentry-react-native/issues`, + ); } + } + } + + const sentryResolverRequest: CustomResolver = ( + context: CustomResolutionContext, + moduleName: string, + platform: string | null, + oldMetroModuleName?: string, + ) => { + if ( + (includeWebReplay === false || + (includeWebReplay === undefined && (platform === 'android' || platform === 'ios'))) && + (oldMetroModuleName ?? moduleName).includes('@sentry/replay') + ) { + return { type: 'empty' } as Resolution; + } + if (originalResolver) { + return oldMetroModuleName + ? originalResolver(context, moduleName, platform, oldMetroModuleName) + : originalResolver(context, moduleName, platform); + } - return defaultResolver( + if (defaultMetro067Resolver) { + return defaultMetro067Resolver( { ...context, - resolveRequest: null, + resolveRequest: {} as CustomResolverBeforeMetro067, }, moduleName, platform, - realModuleName, + oldMetroModuleName, ); - }; - } + } + return context.resolveRequest(context, moduleName, platform); + }; return { ...config, resolver: { ...config.resolver, - resolveRequest: resolver, + resolveRequest: sentryResolverRequest, }, }; } diff --git a/test/tools/metroconfig.test.ts b/test/tools/metroconfig.test.ts index 8677b6280..aeedcaca7 100644 --- a/test/tools/metroconfig.test.ts +++ b/test/tools/metroconfig.test.ts @@ -133,12 +133,19 @@ describe('metroconfig', () => { }; }); - describe('on new metro', () => { + describe.each([ + ['new Metro', false, '0.70.0'], + ['old Metro', true, '0.67.0'], + ])(`on %s`, (description, oldMetro, metroVersion) => { beforeEach(() => { jest.resetModules(); // Mock metro/package.json jest.mock('metro/package.json', () => ({ - version: '0.70.0', + version: metroVersion, + })); + + jest.mock('metro-resolver', () => ({ + resolve: jest.fn(), })); }); @@ -146,7 +153,7 @@ describe('metroconfig', () => { const modifiedConfig = withSentryResolver(config, true); resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'web'); - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'web'); + ExpectToBeCalledWithMetroParameters(originalResolverMock, contextMock, '@sentry/replay', 'web'); }); test('removes Web Replay when platform is web and includeWebReplay is false', () => { @@ -161,7 +168,7 @@ describe('metroconfig', () => { const modifiedConfig = withSentryResolver(config, true); resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'android'); - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'android'); + ExpectToBeCalledWithMetroParameters(originalResolverMock, contextMock, '@sentry/replay', 'android'); }); test('removes Web Replay when platform is android and includeWebReplay is false', () => { @@ -184,7 +191,7 @@ describe('metroconfig', () => { const modifiedConfig = withSentryResolver(config, true); resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, '@sentry/replay', 'ios'); + ExpectToBeCalledWithMetroParameters(originalResolverMock, contextMock, '@sentry/replay', 'ios'); }); test('removes Web Replay when platform is ios and includeWebReplay is false', () => { @@ -208,7 +215,7 @@ describe('metroconfig', () => { const moduleName = 'some/other/module'; resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, moduleName, 'web'); + ExpectToBeCalledWithMetroParameters(originalResolverMock, contextMock, moduleName, 'web'); }); test('calls originalResolver when moduleName is not @sentry/replay and includeWebReplay set to false', () => { @@ -216,133 +223,84 @@ describe('metroconfig', () => { const moduleName = 'some/other/module'; resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, moduleName, 'web'); - }); - - test('calls context.resolveRequest when originalResolver is not provided', () => { - const modifiedConfig = withSentryResolver({ resolver: {} }, true); - const moduleName = 'some/other/module'; - resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); - - expect(contextMock.resolveRequest).toHaveBeenCalledWith(contextMock, moduleName, 'web'); - }); - }); - - describe('on old metro', () => { - beforeEach(() => { - jest.resetModules(); - // Mock metro/package.json - jest.mock('metro/package.json', () => ({ - version: '0.67.0', - })); - - jest.mock('metro-resolver', () => ({ - resolve: jest.fn(), - })); - }); - - test('keep Web Replay when platform is web and includeWebReplay is true', () => { - const modifiedConfig = withSentryResolver(config, true); - resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'web', '@sentry/replay'); - - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, 'real@sentry/replay', 'web', '@sentry/replay'); - }); - - test('removes Web Replay when platform is web and includeWebReplay is false', () => { - const modifiedConfig = withSentryResolver(config, false); - const result = resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'web', '@sentry/replay'); - - expect(result).toEqual({ type: 'empty' }); - expect(originalResolverMock).not.toHaveBeenCalled(); - }); - - test('keep Web Replay when platform is android and includeWebReplay is true', () => { - const modifiedConfig = withSentryResolver(config, true); - resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'android', '@sentry/replay'); - - expect(originalResolverMock).toHaveBeenCalledWith( - contextMock, - 'real@sentry/replay', - 'android', - '@sentry/replay', - ); - }); - - test('removes Web Replay when platform is android and includeWebReplay is false', () => { - const modifiedConfig = withSentryResolver(config, false); - const result = resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'android', '@sentry/replay'); - - expect(result).toEqual({ type: 'empty' }); - expect(originalResolverMock).not.toHaveBeenCalled(); - }); - - test('removes Web Replay when platform is android and includeWebReplay is undefined', () => { - const modifiedConfig = withSentryResolver(config, undefined); - const result = resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'android', '@sentry/replay'); - - expect(result).toEqual({ type: 'empty' }); - expect(originalResolverMock).not.toHaveBeenCalled(); + ExpectToBeCalledWithMetroParameters(originalResolverMock, contextMock, moduleName, 'web'); }); - test('keep Web Replay when platform is ios and includeWebReplay is true', () => { - const modifiedConfig = withSentryResolver(config, true); - resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'ios', '@sentry/replay'); - - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, 'real@sentry/replay', 'ios', '@sentry/replay'); - }); - - test('removes Web Replay when platform is ios and includeWebReplay is false', () => { - const modifiedConfig = withSentryResolver(config, false); - const result = resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'ios', '@sentry/replay'); - - expect(result).toEqual({ type: 'empty' }); - expect(originalResolverMock).not.toHaveBeenCalled(); - }); - - test('removes Web Replay when platform is ios and includeWebReplay is undefined', () => { - const modifiedConfig = withSentryResolver(config, undefined); - const result = resolveRequest(modifiedConfig, contextMock, 'real@sentry/replay', 'ios', '@sentry/replay'); - - expect(result).toEqual({ type: 'empty' }); - expect(originalResolverMock).not.toHaveBeenCalled(); - }); + test('calls default resolver on new metro resolver when originalResolver is not provided', () => { + if (oldMetro) { + return; + } - test('calls originalResolver when moduleName is not @sentry/replay', () => { - const modifiedConfig = withSentryResolver(config, true); + const resolve = require('metro-resolver').resolve; + const modifiedConfig = withSentryResolver({ resolver: {} }, true); const moduleName = 'some/other/module'; - const realModuleName = `real${moduleName}`; - resolveRequest(modifiedConfig, contextMock, realModuleName, 'web', moduleName); + const platform = 'web'; + resolveRequest(modifiedConfig, contextMock, moduleName, platform); - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, realModuleName, 'web', moduleName); + expect(resolve).not.toBeCalled(); + ExpectToBeCalledWithMetroParameters(contextMock.resolveRequest, contextMock, moduleName, platform); }); - test('calls originalResolver when moduleName is not @sentry/replay and includeWebReplay set to false', () => { - const modifiedConfig = withSentryResolver(config, false); - const moduleName = 'some/other/module'; - const realModuleName = `real${moduleName}`; - resolveRequest(modifiedConfig, contextMock, realModuleName, 'web', moduleName); + test('calls old metro resolver when originalResolver is not provided', () => { + if (!oldMetro) { + return; + } - expect(originalResolverMock).toHaveBeenCalledWith(contextMock, realModuleName, 'web', moduleName); - }); - - test('calls default resolver when originalResolver is not provided', () => { const resolve = require('metro-resolver').resolve; const modifiedConfig = withSentryResolver({ resolver: {} }, true); const moduleName = 'some/other/module'; const realModuleName = `real${moduleName}`; - resolveRequest(modifiedConfig, contextMock, realModuleName, 'web', moduleName); + resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); expect(contextMock.resolveRequest).not.toHaveBeenCalled(); expect(resolve).toHaveBeenCalledWith( { ...contextMock, - resolveRequest: null, + resolveRequest: {}, }, - moduleName, - 'web', realModuleName, + 'web', + moduleName, ); }); + + type ResolverFourParams = ( + // @ts-expect-error Can't see type CustomResolutionContext + context: CustomResolutionContext, + realModuleName: string, + platform: string | null, + moduleName?: string, + // @ts-expect-error Can't see type CustomResolutionContext + ) => Resolution; + + function resolveRequest( + metroConfig: MetroConfig, + context: any, + moduleName: string, + platform: string, + // @ts-expect-error Can't see type Resolution. + ): Resolution { + if (oldMetro) { + const resolver = metroConfig.resolver?.resolveRequest as ResolverFourParams; + return resolver(context, `real${moduleName}`, platform, moduleName); + } + return ( + metroConfig.resolver?.resolveRequest && metroConfig.resolver.resolveRequest(context, moduleName, platform) + ); + } + + function ExpectToBeCalledWithMetroParameters( + received: ResolverFourParams, + contextMock: ResolverFourParams, + moduleName: string, + platform: string, + ) { + if (oldMetro) { + expect(received).toBeCalledWith(contextMock, `real${moduleName}`, platform, moduleName); + } else { + expect(received).toBeCalledWith(contextMock, moduleName, platform); + } + } }); }); }); @@ -351,27 +309,3 @@ describe('metroconfig', () => { function createMockSentryInstrumentMetroFrame(): MetroFrame { return { file: 'node_modules/@sentry/utils/cjs/instrument.js' }; } - -type ResolverFourParams = ( - // @ts-expect-error Can't see type CustomResolutionContext - context: CustomResolutionContext, - moduleName: string, - platform: string | null, - realModuleName?: string, - // @ts-expect-error Can't see type CustomResolutionContext -) => Resolution; - -// @ts-expect-error Can't see type Resolution. -function resolveRequest( - metroConfig: MetroConfig, - context: any, - moduleName: string, - platform: string, - moduleNameOldMetro?: string, -): Resolution { - if (moduleNameOldMetro) { - const resolver = metroConfig.resolver?.resolveRequest as ResolverFourParams; - return resolver(context, moduleName, platform, moduleNameOldMetro); - } - return metroConfig.resolver?.resolveRequest && metroConfig.resolver.resolveRequest(context, moduleName, platform); -} From eaa090f6950447a7470b32ec1a1b36a5ef57c654 Mon Sep 17 00:00:00 2001 From: lucas Date: Wed, 4 Sep 2024 18:37:02 -0300 Subject: [PATCH 21/34] add test for null platform --- test/tools/metroconfig.test.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/test/tools/metroconfig.test.ts b/test/tools/metroconfig.test.ts index aeedcaca7..4ec43e598 100644 --- a/test/tools/metroconfig.test.ts +++ b/test/tools/metroconfig.test.ts @@ -187,6 +187,13 @@ describe('metroconfig', () => { expect(originalResolverMock).not.toHaveBeenCalled(); }); + test('keep Web Replay when platform is undefined and includeWebReplay is null', () => { + const modifiedConfig = withSentryResolver(config, undefined); + resolveRequest(modifiedConfig, contextMock, '@sentry/replay', null); + + ExpectToBeCalledWithMetroParameters(originalResolverMock, contextMock, '@sentry/replay', null); + }); + test('keep Web Replay when platform is ios and includeWebReplay is true', () => { const modifiedConfig = withSentryResolver(config, true); resolveRequest(modifiedConfig, contextMock, '@sentry/replay', 'ios'); @@ -264,7 +271,7 @@ describe('metroconfig', () => { ); }); - type ResolverFourParams = ( + type CustomResolverBeforeMetro067 = ( // @ts-expect-error Can't see type CustomResolutionContext context: CustomResolutionContext, realModuleName: string, @@ -277,11 +284,11 @@ describe('metroconfig', () => { metroConfig: MetroConfig, context: any, moduleName: string, - platform: string, + platform: string | null, // @ts-expect-error Can't see type Resolution. ): Resolution { if (oldMetro) { - const resolver = metroConfig.resolver?.resolveRequest as ResolverFourParams; + const resolver = metroConfig.resolver?.resolveRequest as CustomResolverBeforeMetro067; return resolver(context, `real${moduleName}`, platform, moduleName); } return ( @@ -290,10 +297,10 @@ describe('metroconfig', () => { } function ExpectToBeCalledWithMetroParameters( - received: ResolverFourParams, - contextMock: ResolverFourParams, + received: CustomResolverBeforeMetro067, + contextMock: CustomResolverBeforeMetro067, moduleName: string, - platform: string, + platform: string | null, ) { if (oldMetro) { expect(received).toBeCalledWith(contextMock, `real${moduleName}`, platform, moduleName); From 6b5829205eb4bc7c8c68482166bedf3994044094 Mon Sep 17 00:00:00 2001 From: lucas Date: Wed, 4 Sep 2024 18:44:43 -0300 Subject: [PATCH 22/34] test resolveRequest as null --- src/js/tools/metroconfig.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index dc64a1f82..db201ac2a 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -217,7 +217,8 @@ Please check the version of Metro you are using and report the issue at http://w return defaultMetro067Resolver( { ...context, - resolveRequest: {} as CustomResolverBeforeMetro067, + // @ts-expect-error lets test. + resolveRequest: null, }, moduleName, platform, From 25437a40d5e48a01a0eb02718a8fa50b9fd63024 Mon Sep 17 00:00:00 2001 From: lucas Date: Wed, 4 Sep 2024 19:12:05 -0300 Subject: [PATCH 23/34] document why null --- src/js/tools/metroconfig.ts | 2 +- test/tools/metroconfig.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index db201ac2a..649418c94 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -217,7 +217,7 @@ Please check the version of Metro you are using and report the issue at http://w return defaultMetro067Resolver( { ...context, - // @ts-expect-error lets test. + // @ts-expect-error on old metro this field needs to be null. resolveRequest: null, }, moduleName, diff --git a/test/tools/metroconfig.test.ts b/test/tools/metroconfig.test.ts index 4ec43e598..a17e8d106 100644 --- a/test/tools/metroconfig.test.ts +++ b/test/tools/metroconfig.test.ts @@ -263,7 +263,7 @@ describe('metroconfig', () => { expect(resolve).toHaveBeenCalledWith( { ...contextMock, - resolveRequest: {}, + resolveRequest: null, }, realModuleName, 'web', From b48308df8f63abd6f26e69e8b0696eb8e388b050 Mon Sep 17 00:00:00 2001 From: lucas Date: Wed, 4 Sep 2024 19:15:07 -0300 Subject: [PATCH 24/34] nit --- src/js/tools/metroconfig.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 649418c94..241972595 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -159,7 +159,7 @@ function withSentryDebugId(config: MetroConfig): MetroConfig { } // Based on: https://github.com/facebook/metro/blob/c21daba415ea26511e157f794689caab9abe8236/packages/metro-resolver/src/resolve.js#L86-L91 -type CustomResolverBeforeMetro067 = ( +type CustomResolverBeforeMetro068 = ( context: CustomResolutionContext, realModuleName: string, platform: string | null, @@ -170,13 +170,13 @@ type CustomResolverBeforeMetro067 = ( * Includes `@sentry/replay` packages based on the `includeWebReplay` flag and current bundle `platform`. */ export function withSentryResolver(config: MetroConfig, includeWebReplay: boolean | undefined): MetroConfig { - const originalResolver = config.resolver?.resolveRequest as CustomResolver | CustomResolverBeforeMetro067 | undefined; + const originalResolver = config.resolver?.resolveRequest as CustomResolver | CustomResolverBeforeMetro068 | undefined; // eslint-disable-next-line @typescript-eslint/no-var-requires const metro = require('metro/package.json') as { version: string }; const [major, minor] = metro.version.split('.').map(Number); - let defaultMetro067Resolver: CustomResolverBeforeMetro067 | undefined; + let defaultMetro067Resolver: CustomResolverBeforeMetro068 | undefined; if (major == 0 && minor < 68) { if (originalResolver === undefined) { try { From 208ae130479f3b4ee108f3089235b92bc3110747 Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 5 Sep 2024 13:49:51 -0300 Subject: [PATCH 25/34] test refactor --- src/js/tools/metroconfig.ts | 49 ++++++++++++------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 241972595..8ab3f1f3f 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -172,28 +172,7 @@ type CustomResolverBeforeMetro068 = ( export function withSentryResolver(config: MetroConfig, includeWebReplay: boolean | undefined): MetroConfig { const originalResolver = config.resolver?.resolveRequest as CustomResolver | CustomResolverBeforeMetro068 | undefined; - // eslint-disable-next-line @typescript-eslint/no-var-requires - const metro = require('metro/package.json') as { version: string }; - const [major, minor] = metro.version.split('.').map(Number); - - let defaultMetro067Resolver: CustomResolverBeforeMetro068 | undefined; - if (major == 0 && minor < 68) { - if (originalResolver === undefined) { - try { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-var-requires, import/no-extraneous-dependencies - defaultMetro067Resolver = require('metro-resolver').resolve; - logger.log( - `[@sentry/react-native/metro] Using 'resolve' function from 'metro-resolver/src/resolve' as the default resolver on metro config.`, - ); - } catch (error) { - logger.error( - `[@sentry/react-native/metro] Cannot find 'resolve' function in 'metro-resolver/src/resolve'. -Please check the version of Metro you are using and report the issue at http://www.github.com/getsentry/sentry-react-native/issues`, - ); - } - } - } - + let oldMetroWarningEmitted = false; const sentryResolverRequest: CustomResolver = ( context: CustomResolutionContext, moduleName: string, @@ -213,18 +192,22 @@ Please check the version of Metro you are using and report the issue at http://w : originalResolver(context, moduleName, platform); } - if (defaultMetro067Resolver) { - return defaultMetro067Resolver( - { - ...context, - // @ts-expect-error on old metro this field needs to be null. - resolveRequest: null, - }, - moduleName, - platform, - oldMetroModuleName, - ); + // Prior 0.68, resolve context.resolveRequest is sentryResolver itself, where on later version it is the default resolver. + if (context.resolveRequest === sentryResolverRequest) { + if (!oldMetroWarningEmitted) { + logger.error( + `[@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. +Please follow one of the following options: +- Include your resolverRequest on your metroconfig. +- Update your Metro version to 0.68 or higher. +- Set includeWebReplay as true on your metro config. +- If you are still facing issues, report the issue at http://www.github.com/getsentry/sentry-react-native/issues`, + ); + oldMetroWarningEmitted = true; + } + return { } as Resolution; } + return context.resolveRequest(context, moduleName, platform); }; From a843d7360a2d276b877cdefe6bdfb71dafd12271 Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 5 Sep 2024 16:34:08 -0300 Subject: [PATCH 26/34] add error --- src/js/tools/metroconfig.ts | 10 +++------ test/tools/metroconfig.test.ts | 40 +++++++++++++++++----------------- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 8ab3f1f3f..ebbca5f31 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -172,7 +172,7 @@ type CustomResolverBeforeMetro068 = ( export function withSentryResolver(config: MetroConfig, includeWebReplay: boolean | undefined): MetroConfig { const originalResolver = config.resolver?.resolveRequest as CustomResolver | CustomResolverBeforeMetro068 | undefined; - let oldMetroWarningEmitted = false; + const oldMetroWarningEmitted = false; const sentryResolverRequest: CustomResolver = ( context: CustomResolutionContext, moduleName: string, @@ -194,18 +194,14 @@ export function withSentryResolver(config: MetroConfig, includeWebReplay: boolea // Prior 0.68, resolve context.resolveRequest is sentryResolver itself, where on later version it is the default resolver. if (context.resolveRequest === sentryResolverRequest) { - if (!oldMetroWarningEmitted) { - logger.error( - `[@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. + throw new Error( + `[@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. Please follow one of the following options: - Include your resolverRequest on your metroconfig. - Update your Metro version to 0.68 or higher. - Set includeWebReplay as true on your metro config. - If you are still facing issues, report the issue at http://www.github.com/getsentry/sentry-react-native/issues`, ); - oldMetroWarningEmitted = true; - } - return { } as Resolution; } return context.resolveRequest(context, moduleName, platform); diff --git a/test/tools/metroconfig.test.ts b/test/tools/metroconfig.test.ts index a17e8d106..5746cc15a 100644 --- a/test/tools/metroconfig.test.ts +++ b/test/tools/metroconfig.test.ts @@ -143,10 +143,6 @@ describe('metroconfig', () => { jest.mock('metro/package.json', () => ({ version: metroVersion, })); - - jest.mock('metro-resolver', () => ({ - resolve: jest.fn(), - })); }); test('keep Web Replay when platform is web and includeWebReplay is true', () => { @@ -238,37 +234,38 @@ describe('metroconfig', () => { return; } - const resolve = require('metro-resolver').resolve; const modifiedConfig = withSentryResolver({ resolver: {} }, true); const moduleName = 'some/other/module'; const platform = 'web'; resolveRequest(modifiedConfig, contextMock, moduleName, platform); - expect(resolve).not.toBeCalled(); ExpectToBeCalledWithMetroParameters(contextMock.resolveRequest, contextMock, moduleName, platform); }); - test('calls old metro resolver when originalResolver is not provided', () => { + test('throws error when running on old metro and includeWebReplay is set to false', () => { if (!oldMetro) { return; } - const resolve = require('metro-resolver').resolve; const modifiedConfig = withSentryResolver({ resolver: {} }, true); const moduleName = 'some/other/module'; - const realModuleName = `real${moduleName}`; - resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); + let capturedError: Error | unknown; + try { + resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); + } + catch (error) { + capturedError = error; + } - expect(contextMock.resolveRequest).not.toHaveBeenCalled(); - expect(resolve).toHaveBeenCalledWith( - { - ...contextMock, - resolveRequest: null, - }, - realModuleName, - 'web', - moduleName, - ); + expect(capturedError).toBeInstanceOf(Error); + if (capturedError instanceof Error ) { + expect(capturedError.message).toBe(`[@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. +Please follow one of the following options: +- Include your resolverRequest on your metroconfig. +- Update your Metro version to 0.68 or higher. +- Set includeWebReplay as true on your metro config. +- If you are still facing issues, report the issue at http://www.github.com/getsentry/sentry-react-native/issues`); + } }); type CustomResolverBeforeMetro067 = ( @@ -288,7 +285,10 @@ describe('metroconfig', () => { // @ts-expect-error Can't see type Resolution. ): Resolution { if (oldMetro) { + const resolver = metroConfig.resolver?.resolveRequest as CustomResolverBeforeMetro067; + // On older Metro the resolveRequest is the creater resolver. + context.resolveRequest = resolver; return resolver(context, `real${moduleName}`, platform, moduleName); } return ( From 73669286277ba92ec824cf8e5de06beffa4eef17 Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 5 Sep 2024 16:40:05 -0300 Subject: [PATCH 27/34] force error on all versions. --- src/js/tools/metroconfig.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index ebbca5f31..e0d92ac34 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -172,7 +172,6 @@ type CustomResolverBeforeMetro068 = ( export function withSentryResolver(config: MetroConfig, includeWebReplay: boolean | undefined): MetroConfig { const originalResolver = config.resolver?.resolveRequest as CustomResolver | CustomResolverBeforeMetro068 | undefined; - const oldMetroWarningEmitted = false; const sentryResolverRequest: CustomResolver = ( context: CustomResolutionContext, moduleName: string, @@ -193,6 +192,8 @@ export function withSentryResolver(config: MetroConfig, includeWebReplay: boolea } // Prior 0.68, resolve context.resolveRequest is sentryResolver itself, where on later version it is the default resolver. + // @ts-expect-error test. + context.resolveRequest = sentryResolverRequest if (context.resolveRequest === sentryResolverRequest) { throw new Error( `[@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. From 204db68ac2f9b0dbcca621aca3196f2bc86e9826 Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 5 Sep 2024 16:46:48 -0300 Subject: [PATCH 28/34] test console error. --- src/js/tools/metroconfig.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index e0d92ac34..12a5cfb05 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -195,7 +195,8 @@ export function withSentryResolver(config: MetroConfig, includeWebReplay: boolea // @ts-expect-error test. context.resolveRequest = sentryResolverRequest if (context.resolveRequest === sentryResolverRequest) { - throw new Error( + // eslint-disable-next-line no-console + console.error( `[@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. Please follow one of the following options: - Include your resolverRequest on your metroconfig. @@ -203,6 +204,7 @@ Please follow one of the following options: - Set includeWebReplay as true on your metro config. - If you are still facing issues, report the issue at http://www.github.com/getsentry/sentry-react-native/issues`, ); + throw new Error(); } return context.resolveRequest(context, moduleName, platform); From 631e930be8018cf06e7ad6397be4af81167e0d97 Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 5 Sep 2024 16:53:22 -0300 Subject: [PATCH 29/34] console error ok, logger logs? --- src/js/tools/metroconfig.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 12a5cfb05..8505b25af 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -195,9 +195,8 @@ export function withSentryResolver(config: MetroConfig, includeWebReplay: boolea // @ts-expect-error test. context.resolveRequest = sentryResolverRequest if (context.resolveRequest === sentryResolverRequest) { - // eslint-disable-next-line no-console - console.error( - `[@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. + logger.error( + `Error: [@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. Please follow one of the following options: - Include your resolverRequest on your metroconfig. - Update your Metro version to 0.68 or higher. From faa94ec78f92ef4b842f7d441cb7d25b1aa910c3 Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 5 Sep 2024 16:59:37 -0300 Subject: [PATCH 30/34] logger doesnt work, should we brek the process? --- src/js/tools/metroconfig.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 8505b25af..b5601a4f0 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -192,10 +192,10 @@ export function withSentryResolver(config: MetroConfig, includeWebReplay: boolea } // Prior 0.68, resolve context.resolveRequest is sentryResolver itself, where on later version it is the default resolver. - // @ts-expect-error test. - context.resolveRequest = sentryResolverRequest +// context.resolveRequest = sentryResolverRequest if (context.resolveRequest === sentryResolverRequest) { - logger.error( + // eslint-disable-next-line no-console + console.error( `Error: [@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. Please follow one of the following options: - Include your resolverRequest on your metroconfig. @@ -203,7 +203,7 @@ Please follow one of the following options: - Set includeWebReplay as true on your metro config. - If you are still facing issues, report the issue at http://www.github.com/getsentry/sentry-react-native/issues`, ); - throw new Error(); + process.exit(-1); } return context.resolveRequest(context, moduleName, platform); From 47d6cd147e8859402b6464b35939fe2d6e5847a2 Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 5 Sep 2024 17:42:35 -0300 Subject: [PATCH 31/34] final tests --- src/js/tools/metroconfig.ts | 10 +++++----- test/tools/metroconfig.test.ts | 22 ++++++---------------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index b5601a4f0..f48861817 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -20,7 +20,7 @@ export interface SentryMetroConfigOptions { annotateReactComponents?: boolean; /** * Adds the Sentry replay package for web. - * @default false (Mobile) true (Web) + * @default true (Mobile) true (Web) */ includeWebReplay?: boolean; } @@ -81,7 +81,7 @@ export function getSentryExpoConfig( newConfig = withSentryBabelTransformer(newConfig); } - if (options.includeWebReplay !== true) { + if (options.includeWebReplay === false) { newConfig = withSentryResolver(newConfig, options.includeWebReplay); } @@ -192,10 +192,9 @@ export function withSentryResolver(config: MetroConfig, includeWebReplay: boolea } // Prior 0.68, resolve context.resolveRequest is sentryResolver itself, where on later version it is the default resolver. -// context.resolveRequest = sentryResolverRequest if (context.resolveRequest === sentryResolverRequest) { // eslint-disable-next-line no-console - console.error( + console.log( `Error: [@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. Please follow one of the following options: - Include your resolverRequest on your metroconfig. @@ -203,7 +202,8 @@ Please follow one of the following options: - Set includeWebReplay as true on your metro config. - If you are still facing issues, report the issue at http://www.github.com/getsentry/sentry-react-native/issues`, ); - process.exit(-1); + // Return required for test. + return process.exit(-1); } return context.resolveRequest(context, moduleName, platform); diff --git a/test/tools/metroconfig.test.ts b/test/tools/metroconfig.test.ts index 5746cc15a..943cf3ca7 100644 --- a/test/tools/metroconfig.test.ts +++ b/test/tools/metroconfig.test.ts @@ -143,6 +143,7 @@ describe('metroconfig', () => { jest.mock('metro/package.json', () => ({ version: metroVersion, })); + }); test('keep Web Replay when platform is web and includeWebReplay is true', () => { @@ -247,27 +248,16 @@ describe('metroconfig', () => { return; } + // @ts-expect-error mock. + const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {}); const modifiedConfig = withSentryResolver({ resolver: {} }, true); const moduleName = 'some/other/module'; - let capturedError: Error | unknown; - try { - resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); - } - catch (error) { - capturedError = error; - } + resolveRequest(modifiedConfig, contextMock, moduleName, 'web'); - expect(capturedError).toBeInstanceOf(Error); - if (capturedError instanceof Error ) { - expect(capturedError.message).toBe(`[@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. -Please follow one of the following options: -- Include your resolverRequest on your metroconfig. -- Update your Metro version to 0.68 or higher. -- Set includeWebReplay as true on your metro config. -- If you are still facing issues, report the issue at http://www.github.com/getsentry/sentry-react-native/issues`); - } + expect(mockExit).toHaveBeenCalledWith(-1); }); + type CustomResolverBeforeMetro067 = ( // @ts-expect-error Can't see type CustomResolutionContext context: CustomResolutionContext, From 97f0c28b2f8bbed9d550c1eb9855338c5f9f9234 Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 5 Sep 2024 17:48:44 -0300 Subject: [PATCH 32/34] yran fix and set default to true --- src/js/tools/metroconfig.ts | 12 ++++++------ test/tools/metroconfig.test.ts | 3 --- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index f48861817..769a512e8 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -20,7 +20,7 @@ export interface SentryMetroConfigOptions { annotateReactComponents?: boolean; /** * Adds the Sentry replay package for web. - * @default true (Mobile) true (Web) + * @default true */ includeWebReplay?: boolean; } @@ -40,7 +40,7 @@ export interface SentryExpoConfigOptions { */ export function withSentryConfig( config: MetroConfig, - { annotateReactComponents = false, includeWebReplay }: SentryMetroConfigOptions = {}, + { annotateReactComponents = false, includeWebReplay = true }: SentryMetroConfigOptions = {}, ): MetroConfig { setSentryMetroDevServerEnvFlag(); @@ -193,15 +193,15 @@ export function withSentryResolver(config: MetroConfig, includeWebReplay: boolea // Prior 0.68, resolve context.resolveRequest is sentryResolver itself, where on later version it is the default resolver. if (context.resolveRequest === sentryResolverRequest) { - // eslint-disable-next-line no-console - console.log( - `Error: [@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. + // eslint-disable-next-line no-console + console.error( + `Error: [@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. Please follow one of the following options: - Include your resolverRequest on your metroconfig. - Update your Metro version to 0.68 or higher. - Set includeWebReplay as true on your metro config. - If you are still facing issues, report the issue at http://www.github.com/getsentry/sentry-react-native/issues`, - ); + ); // Return required for test. return process.exit(-1); } diff --git a/test/tools/metroconfig.test.ts b/test/tools/metroconfig.test.ts index 943cf3ca7..9913d6eec 100644 --- a/test/tools/metroconfig.test.ts +++ b/test/tools/metroconfig.test.ts @@ -143,7 +143,6 @@ describe('metroconfig', () => { jest.mock('metro/package.json', () => ({ version: metroVersion, })); - }); test('keep Web Replay when platform is web and includeWebReplay is true', () => { @@ -257,7 +256,6 @@ describe('metroconfig', () => { expect(mockExit).toHaveBeenCalledWith(-1); }); - type CustomResolverBeforeMetro067 = ( // @ts-expect-error Can't see type CustomResolutionContext context: CustomResolutionContext, @@ -275,7 +273,6 @@ describe('metroconfig', () => { // @ts-expect-error Can't see type Resolution. ): Resolution { if (oldMetro) { - const resolver = metroConfig.resolver?.resolveRequest as CustomResolverBeforeMetro067; // On older Metro the resolveRequest is the creater resolver. context.resolveRequest = resolver; From 03b8acc5e5bd3a349a76fb2dfead181434a7e76a Mon Sep 17 00:00:00 2001 From: Krystof Woldrich <31292499+krystofwoldrich@users.noreply.github.com> Date: Fri, 6 Sep 2024 12:01:42 +0200 Subject: [PATCH 33/34] Apply suggestions from code review --- src/js/tools/metroconfig.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 769a512e8..25b85aaf0 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -51,7 +51,7 @@ export function withSentryConfig( if (annotateReactComponents) { newConfig = withSentryBabelTransformer(newConfig); } - if (includeWebReplay !== true) { + if (options.includeWebReplay === false) { newConfig = withSentryResolver(newConfig, includeWebReplay); } @@ -195,7 +195,7 @@ export function withSentryResolver(config: MetroConfig, includeWebReplay: boolea if (context.resolveRequest === sentryResolverRequest) { // eslint-disable-next-line no-console console.error( - `Error: [@sentry/react-native/metro] Cannot desolve the defaultResolver on Metro older than 0.68. + `Error: [@sentry/react-native/metro] Can not resolve the defaultResolver on Metro older than 0.68. Please follow one of the following options: - Include your resolverRequest on your metroconfig. - Update your Metro version to 0.68 or higher. From 3d5a1c0205ae6a52c8c777a7d6eceb048b2c0981 Mon Sep 17 00:00:00 2001 From: Krystof Woldrich <31292499+krystofwoldrich@users.noreply.github.com> Date: Fri, 6 Sep 2024 12:04:45 +0200 Subject: [PATCH 34/34] Update src/js/tools/metroconfig.ts --- src/js/tools/metroconfig.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/tools/metroconfig.ts b/src/js/tools/metroconfig.ts index 25b85aaf0..4235f38e4 100644 --- a/src/js/tools/metroconfig.ts +++ b/src/js/tools/metroconfig.ts @@ -51,7 +51,7 @@ export function withSentryConfig( if (annotateReactComponents) { newConfig = withSentryBabelTransformer(newConfig); } - if (options.includeWebReplay === false) { + if (includeWebReplay === false) { newConfig = withSentryResolver(newConfig, includeWebReplay); }