Skip to content

Commit c53e49b

Browse files
committed
[RFC] feat: Update cli-plugin-metro to use defaults in app metro.config.js from RN 0.72
1 parent 28fe385 commit c53e49b

File tree

3 files changed

+74
-38
lines changed

3 files changed

+74
-38
lines changed

packages/cli-plugin-metro/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export type {MetroConfig} from 'metro-config';
22
export {
33
Config,
44
ConfigLoadingContext,
5-
getDefaultConfig,
5+
getDefaultConfigPre72 as getDefaultConfig,
66
default as loadMetroConfig,
77
} from './tools/loadMetroConfig';
88
export {

packages/cli-plugin-metro/src/tools/__tests__/loadMetroConfig-test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import {getDefaultConfig} from '../loadMetroConfig';
1+
import {getDefaultConfigPre72} from '../loadMetroConfig';
22

33
jest.mock('fs');
44
jest.mock('path');
55

6-
describe('getDefaultConfig', () => {
6+
describe('getDefaultConfigPre72', () => {
77
it('should preserve transformer.allowOptionalDependencies=true when overriding other transformer options', async () => {
8-
const config = getDefaultConfig({
8+
const config = getDefaultConfigPre72({
99
root: '/',
1010
reactNativePath: '',
1111
// @ts-ignore

packages/cli-plugin-metro/src/tools/loadMetroConfig.ts

Lines changed: 70 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
/**
2-
* Configuration file of Metro.
3-
*/
41
import path from 'path';
5-
import {ConfigT, InputConfigT, loadConfig} from 'metro-config';
2+
import {ConfigT, InputConfigT, loadConfig, mergeConfig} from 'metro-config';
63
import type {Config} from '@react-native-community/cli-types';
74
import {reactNativePlatformResolver} from './metroPlatformResolver';
85

6+
/**
7+
* @deprecated (React Native 0.72.0) Please use
8+
* https://github.com/facebook/react-native/tree/main/package/metro-config/index.js
9+
*/
910
const INTERNAL_CALLSITES_REGEX = new RegExp(
1011
[
1112
'/Libraries/Renderer/implementations/.+\\.js$',
@@ -35,14 +36,60 @@ export type ConfigLoadingContext = Pick<
3536

3637
/**
3738
* Default configuration
39+
*
40+
* @deprecated (React Native 0.72.0) Please use
41+
* https://github.com/facebook/react-native/tree/main/package/metro-config/index.js
3842
*/
39-
export const getDefaultConfig = (ctx: ConfigLoadingContext): InputConfigT => {
43+
export const getDefaultConfigPre72 = (
44+
ctx: ConfigLoadingContext,
45+
): InputConfigT => {
46+
const defaultConfig = {
47+
resolver: {
48+
resolverMainFields: ['react-native', 'browser', 'main'],
49+
unstable_conditionNames: ['import', 'require', 'react-native'],
50+
},
51+
serializer: {
52+
getPolyfills: () =>
53+
require(path.join(ctx.reactNativePath, 'rn-get-polyfills'))(),
54+
},
55+
server: {
56+
port: Number(process.env.RCT_METRO_PORT) || 8081,
57+
},
58+
symbolicator: {
59+
customizeFrame: (frame: {file?: string}) => {
60+
const collapse = Boolean(
61+
frame.file && INTERNAL_CALLSITES_REGEX.test(frame.file),
62+
);
63+
return {collapse};
64+
},
65+
},
66+
transformer: {
67+
allowOptionalDependencies: true,
68+
babelTransformerPath: require.resolve(
69+
'metro-react-native-babel-transformer',
70+
),
71+
assetRegistryPath: 'react-native/Libraries/Image/AssetRegistry',
72+
asyncRequireModulePath: require.resolve(
73+
'metro-runtime/src/modules/asyncRequire',
74+
),
75+
},
76+
watchFolders: [],
77+
};
78+
79+
return mergeConfig(defaultConfig, getOverrideConfig(ctx));
80+
};
81+
82+
/**
83+
* Get the config options to override based on RN CLI inputs.
84+
*/
85+
function getOverrideConfig(ctx: ConfigLoadingContext): InputConfigT {
4086
const outOfTreePlatforms = Object.keys(ctx.platforms).filter(
4187
(platform) => ctx.platforms[platform].npmPackageName,
4288
);
4389

4490
return {
4591
resolver: {
92+
platforms: [...Object.keys(ctx.platforms), 'native'],
4693
resolveRequest:
4794
outOfTreePlatforms.length === 0
4895
? undefined
@@ -55,9 +102,6 @@ export const getDefaultConfig = (ctx: ConfigLoadingContext): InputConfigT => {
55102
{},
56103
),
57104
),
58-
resolverMainFields: ['react-native', 'browser', 'main'],
59-
platforms: [...Object.keys(ctx.platforms), 'native'],
60-
unstable_conditionNames: ['import', 'require', 'react-native'],
61105
},
62106
serializer: {
63107
// We can include multiple copies of InitializeCore here because metro will
@@ -76,30 +120,8 @@ export const getDefaultConfig = (ctx: ConfigLoadingContext): InputConfigT => {
76120
getPolyfills: () =>
77121
require(path.join(ctx.reactNativePath, 'rn-get-polyfills'))(),
78122
},
79-
server: {
80-
port: Number(process.env.RCT_METRO_PORT) || 8081,
81-
},
82-
symbolicator: {
83-
customizeFrame: (frame) => {
84-
const collapse = Boolean(
85-
frame.file && INTERNAL_CALLSITES_REGEX.test(frame.file),
86-
);
87-
return {collapse};
88-
},
89-
},
90-
transformer: {
91-
allowOptionalDependencies: true,
92-
babelTransformerPath: require.resolve(
93-
'metro-react-native-babel-transformer',
94-
),
95-
assetRegistryPath: 'react-native/Libraries/Image/AssetRegistry',
96-
asyncRequireModulePath: require.resolve(
97-
'metro-runtime/src/modules/asyncRequire',
98-
),
99-
},
100-
watchFolders: [],
101123
};
102-
};
124+
}
103125

104126
export interface ConfigOptionsT {
105127
maxWorkers?: number;
@@ -113,15 +135,29 @@ export interface ConfigOptionsT {
113135
}
114136

115137
/**
116-
* Loads Metro Config and applies `options` on top of the resolved config.
138+
* Load Metro config.
117139
*
118-
* This allows the CLI to always overwrite the file settings.
140+
* Allows the CLI to override certain defaults in the base `metro.config.js`
141+
* based on dynamic user options in `ctx`.
119142
*/
120143
export default function loadMetroConfig(
121144
ctx: ConfigLoadingContext,
122145
options?: ConfigOptionsT,
123146
): Promise<ConfigT> {
124-
const defaultConfig = {...getDefaultConfig(ctx)};
147+
const reactNativeVersion = require(ctx.reactNativePath + '/package.json')
148+
?.version;
149+
150+
if (
151+
reactNativeVersion &&
152+
parseInt(reactNativeVersion.split('.')[0], 10) >= 72
153+
) {
154+
// React Native 0.72 and later: Load Metro config which inherits
155+
// @react-native/metro-config, and apply sparse additional config
156+
return loadConfig({cwd: ctx.root}, getOverrideConfig(ctx));
157+
}
158+
159+
// Pre React Native 0.72: Load Metro config and apply all legacy defaults
160+
const defaultConfig = {...getDefaultConfigPre72(ctx)};
125161
if (options && options.reporter) {
126162
defaultConfig.reporter = options.reporter;
127163
}

0 commit comments

Comments
 (0)