Skip to content

Commit 0b4d1f3

Browse files
feat(metro-plugin): Support Metro 0.83 (#5035)
* feat(metro-plugin): Support Metro 0.83 * fix sourceMapString named export * fix lint * fix lint 2 * fix lint 3
1 parent d43b056 commit 0b4d1f3

File tree

8 files changed

+344
-25
lines changed

8 files changed

+344
-25
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
> make sure you follow our [migration guide](https://docs.sentry.io/platforms/react-native/migration/) first.
77
<!-- prettier-ignore-end -->
88
9+
## Unreleased
10+
11+
### Features
12+
13+
- Support Metro 0.83 ([#5035](https://github.com/getsentry/sentry-react-native/pull/5035))
14+
915
## 6.19.0
1016

1117
### Fixes

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
"jest-environment-jsdom": "^29.6.2",
105105
"jest-extended": "^4.0.2",
106106
"madge": "^6.1.0",
107-
"metro": "0.81.0",
107+
"metro": "0.83.1",
108108
"prettier": "^2.0.5",
109109
"react": "18.3.1",
110110
"react-native": "0.77.1",

packages/core/src/js/tools/sentryMetroSerializer.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
import * as crypto from 'crypto';
22
// eslint-disable-next-line import/no-extraneous-dependencies
33
import type { MixedOutput, Module, ReadOnlyGraph } from 'metro';
4-
// eslint-disable-next-line import/no-extraneous-dependencies
5-
import * as countLines from 'metro/src/lib/countLines';
4+
import type * as countLinesType from 'metro/private/lib/countLines';
65

76
import type { Bundle, MetroSerializer, MetroSerializerOutput, SerializedBundle, VirtualJSOutput } from './utils';
87
import { createDebugIdSnippet, createSet, determineDebugIdFromBundleSource, stringToUUID } from './utils';
98
import { createDefaultMetroSerializer } from './vendor/metro/utils';
109

10+
let countLines: typeof countLinesType;
11+
try {
12+
countLines = require('metro/private/lib/countLines');
13+
} catch (e) {
14+
countLines = require('metro/src/lib/countLines');
15+
}
16+
1117
type SourceMap = Record<string, unknown>;
1218

1319
const DEBUG_ID_PLACE_HOLDER = '__debug_id_place_holder__';

packages/core/src/js/tools/utils.ts

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import * as crypto from 'crypto';
22
// eslint-disable-next-line import/no-extraneous-dependencies
33
import type { Module, ReadOnlyGraph, SerializerOptions } from 'metro';
4-
// eslint-disable-next-line import/no-extraneous-dependencies
5-
import type CountingSet from 'metro/src/lib/CountingSet';
4+
import type CountingSet from 'metro/src/lib/CountingSet'; // types are in src but exports are in private
65

76
// Variant of MixedOutput
87
// https://github.com/facebook/metro/blob/9b85f83c9cc837d8cd897aa7723be7da5b296067/packages/metro/src/DeltaBundler/types.flow.js#L21
@@ -84,16 +83,44 @@ export function determineDebugIdFromBundleSource(code: string): string | undefin
8483
* https://github.com/facebook/metro/blob/fc29a1177f883144674cf85a813b58567f69d545/packages/metro/src/lib/CountingSet.js
8584
*/
8685
function resolveSetCreator(): () => CountingSet<string> {
86+
const CountingSetFromPrivate = safeRequireCountingSetFromPrivate();
87+
if (CountingSetFromPrivate) {
88+
return () => new CountingSetFromPrivate.default();
89+
}
90+
91+
const CountingSetFromSrc = safeRequireCountingSetFromSrc();
92+
if (CountingSetFromSrc) {
93+
return () => new CountingSetFromSrc.default();
94+
}
95+
96+
return () => new Set() as unknown as CountingSet<string>;
97+
}
98+
99+
/**
100+
* CountingSet was added in Metro 0.72.0 before that NodeJS Set was used.
101+
*
102+
* https://github.com/facebook/metro/blob/fc29a1177f883144674cf85a813b58567f69d545/packages/metro/src/lib/CountingSet.js
103+
*/
104+
function safeRequireCountingSetFromSrc(): { default: new <T>() => CountingSet<T> } | undefined {
105+
try {
106+
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-extraneous-dependencies
107+
return require('metro/src/lib/CountingSet');
108+
} catch (e) {
109+
return undefined;
110+
}
111+
}
112+
113+
/**
114+
* CountingSet was moved to private in Metro 0.83.0. (all src exports were moved to private)
115+
*
116+
* https://github.com/facebook/metro/commit/ae6f42372ed361611b5672705f22081c2022cf28
117+
*/
118+
function safeRequireCountingSetFromPrivate(): { default: new <T>() => CountingSet<T> } | undefined {
87119
try {
88120
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-extraneous-dependencies
89-
const { default: MetroSet } = require('metro/src/lib/CountingSet');
90-
return () => new MetroSet();
121+
return require('metro/private/lib/CountingSet');
91122
} catch (e) {
92-
if (e instanceof Error && 'code' in e && e.code === 'MODULE_NOT_FOUND') {
93-
return () => new Set() as unknown as CountingSet<string>;
94-
} else {
95-
throw e;
96-
}
123+
return undefined;
97124
}
98125
}
99126

packages/core/src/js/tools/vendor/metro/metro.d.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2525
// SOFTWARE.
2626

27-
declare module 'metro/src/DeltaBundler/Serializers/baseJSBundle' {
27+
// All exports were moved from src to private in Metro 0.83.0.
28+
// https://github.com/facebook/metro/commit/ae6f42372ed361611b5672705f22081c2022cf28
29+
30+
declare module 'metro/private/DeltaBundler/Serializers/baseJSBundle' {
2831
// https://github.com/facebook/metro/blob/9b85f83c9cc837d8cd897aa7723be7da5b296067/packages/metro/src/DeltaBundler/Serializers/baseJSBundle.js#L25
2932
const baseJSBundle: (
3033
entryPoint: string,
@@ -39,7 +42,7 @@ declare module 'metro/src/DeltaBundler/Serializers/baseJSBundle' {
3942
export = baseJSBundle;
4043
}
4144

42-
declare module 'metro/src/lib/bundleToString' {
45+
declare module 'metro/private/lib/bundleToString' {
4346
// https://github.com/facebook/metro/blob/9b85f83c9cc837d8cd897aa7723be7da5b296067/packages/metro/src/lib/bundleToString.js#L22
4447
const baseJSBundle: (bundle: { modules: [number, string][]; post: string; pre: string }) => {
4548
code: string;
@@ -49,13 +52,13 @@ declare module 'metro/src/lib/bundleToString' {
4952
export = baseJSBundle;
5053
}
5154

52-
declare module 'metro/src/lib/countLines' {
55+
declare module 'metro/private/lib/countLines' {
5356
// https://github.com/facebook/metro/blob/9b85f83c9cc837d8cd897aa7723be7da5b296067/packages/metro/src/lib/countLines.js#L16
5457
const countLines: (code: string) => number;
5558
export = countLines;
5659
}
5760

58-
declare module 'metro/src/DeltaBundler/Serializers/sourceMapString' {
61+
declare module 'metro/private/DeltaBundler/Serializers/sourceMapString' {
5962
import type { MixedOutput, Module } from 'metro';
6063

6164
// https://github.com/facebook/metro/blob/9b85f83c9cc837d8cd897aa7723be7da5b296067/packages/metro/src/DeltaBundler/Serializers/sourceMapString.js#L19

packages/core/src/js/tools/vendor/metro/utils.ts

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,37 @@
2626

2727
// eslint-disable-next-line import/no-extraneous-dependencies
2828
import type { MixedOutput, Module, ReadOnlyGraph } from 'metro';
29-
// eslint-disable-next-line import/no-extraneous-dependencies
30-
import * as baseJSBundle from 'metro/src/DeltaBundler/Serializers/baseJSBundle';
31-
// eslint-disable-next-line import/no-extraneous-dependencies
32-
import * as sourceMapString from 'metro/src/DeltaBundler/Serializers/sourceMapString';
33-
// eslint-disable-next-line import/no-extraneous-dependencies
34-
import * as bundleToString from 'metro/src/lib/bundleToString';
29+
import type * as baseJSBundleType from 'metro/private/DeltaBundler/Serializers/baseJSBundle';
30+
import type * as sourceMapStringType from 'metro/private/DeltaBundler/Serializers/sourceMapString';
31+
import type * as bundleToStringType from 'metro/private/lib/bundleToString';
32+
33+
let baseJSBundle: typeof baseJSBundleType;
34+
try {
35+
baseJSBundle = require('metro/private/DeltaBundler/Serializers/baseJSBundle');
36+
} catch (e) {
37+
baseJSBundle = require('metro/src/DeltaBundler/Serializers/baseJSBundle');
38+
}
39+
40+
let sourceMapString: typeof sourceMapStringType;
41+
try {
42+
// eslint-disable-next-line @typescript-eslint/no-var-requires
43+
const sourceMapStringModule = require('metro/private/DeltaBundler/Serializers/sourceMapString');
44+
sourceMapString = (sourceMapStringModule as { sourceMapString: typeof sourceMapStringType }).sourceMapString;
45+
} catch (e) {
46+
sourceMapString = require('metro/src/DeltaBundler/Serializers/sourceMapString');
47+
if ('sourceMapString' in sourceMapString) {
48+
// Changed to named export in https://github.com/facebook/metro/commit/34148e61200a508923315fbe387b26d1da27bf4b
49+
// Metro 0.81.0 and 0.80.10 patch
50+
sourceMapString = (sourceMapString as { sourceMapString: typeof sourceMapStringType }).sourceMapString;
51+
}
52+
}
53+
54+
let bundleToString: typeof bundleToStringType;
55+
try {
56+
bundleToString = require('metro/private/lib/bundleToString');
57+
} catch (e) {
58+
bundleToString = require('metro/src/lib/bundleToString');
59+
}
3560

3661
import type { MetroSerializer } from '../../utils';
3762

packages/core/test/tools/sentryMetroSerializer.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import * as fs from 'fs';
22
import type { MixedOutput, Module } from 'metro';
3-
import CountingSet from 'metro/src/lib/CountingSet';
4-
import * as countLines from 'metro/src/lib/countLines';
3+
// eslint-disable-next-line import/no-unresolved
4+
import CountingSet from 'metro/private/lib/CountingSet';
5+
// eslint-disable-next-line import/no-unresolved
6+
import * as countLines from 'metro/private/lib/countLines';
57
import { minify } from 'uglify-js';
68

79
import { createSentryMetroSerializer } from '../../src/js/tools/sentryMetroSerializer';

0 commit comments

Comments
 (0)