From 788e4217681e0d0b49d936d95d60d5026ac41b69 Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Fri, 31 Mar 2023 15:59:54 +0100 Subject: [PATCH] fix: Fix merge of CLI Metro config overrides, add soft fallback to RN defaults --- packages/cli-plugin-metro/package.json | 1 + .../src/tools/loadMetroConfig.ts | 47 ++++++++++++++----- .../@react-native/metro-config/index.d.ts | 5 ++ yarn.lock | 28 +++++++++++ 4 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 packages/cli-plugin-metro/types/@react-native/metro-config/index.d.ts diff --git a/packages/cli-plugin-metro/package.json b/packages/cli-plugin-metro/package.json index d351f65dd..6bebf8d87 100644 --- a/packages/cli-plugin-metro/package.json +++ b/packages/cli-plugin-metro/package.json @@ -9,6 +9,7 @@ "dependencies": { "@react-native-community/cli-server-api": "^11.0.1", "@react-native-community/cli-tools": "^11.0.1", + "@react-native/metro-config": "^0.72.1", "chalk": "^4.1.2", "execa": "^5.0.0", "metro": "0.76.0", diff --git a/packages/cli-plugin-metro/src/tools/loadMetroConfig.ts b/packages/cli-plugin-metro/src/tools/loadMetroConfig.ts index 34c66c8a8..344f989b0 100644 --- a/packages/cli-plugin-metro/src/tools/loadMetroConfig.ts +++ b/packages/cli-plugin-metro/src/tools/loadMetroConfig.ts @@ -1,5 +1,13 @@ +import fs from 'fs'; import path from 'path'; -import {ConfigT, InputConfigT, loadConfig, resolveConfig} from 'metro-config'; +import { + ConfigT, + InputConfigT, + loadConfig, + mergeConfig, + resolveConfig, +} from 'metro-config'; +import {getDefaultConfig} from '@react-native/metro-config'; import {CLIError, logger} from '@react-native-community/cli-tools'; import type {Config} from '@react-native-community/cli-types'; import {reactNativePlatformResolver} from './metroPlatformResolver'; @@ -67,8 +75,8 @@ export interface ConfigOptionsT { /** * Load Metro config. * - * Allows the CLI to override certain defaults in the base `metro.config.js` - * based on dynamic user options in `ctx`. + * Allows the CLI to override select values in `metro.config.js` based on + * dynamic user options in `ctx`. */ export default async function loadMetroConfig( ctx: ConfigLoadingContext, @@ -89,17 +97,32 @@ export default async function loadMetroConfig( // @ts-ignore resolveConfig return value is mistyped logger.debug(`Reading Metro config from ${projectConfig.filepath}`); - try { - require.resolve('@react-native/metro-config', { - paths: [ctx.root], - }); - } catch (e) { + if ( + !/['"']@react-native\/metro-config['"']/.test( + fs + // @ts-ignore resolveConfig return value is mistyped + .readFileSync(projectConfig.filepath, 'utf8'), + ) + ) { logger.warn( - "From React Native 0.72, your 'metro.config.js' file should " + - "extend '@react-native/metro-config', however it's not present in your " + - "project's devDependencies. Please install '@react-native/metro-config'.", + 'From React Native 0.72, your metro.config.js file should extend' + + "'@react-native/metro-config'. Please see the React Native 0.72 " + + 'changelog, or copy the template at:\n' + + 'https://github.com/facebook/react-native/blob/main/packages/react-native/template/metro.config.js', ); + logger.warn('Falling back to internal defaults.'); + + const loadedConfig = await loadConfig( + {cwd: ctx.root, ...options}, + // Provide @react-native/metro-config defaults on top of Metro defaults + getDefaultConfig(ctx.root), + ); + + return mergeConfig(loadedConfig, overrideConfig); } - return loadConfig({cwd: ctx.root, ...options}, overrideConfig); + return mergeConfig( + await loadConfig({cwd: ctx.root, ...options}), + overrideConfig, + ); } diff --git a/packages/cli-plugin-metro/types/@react-native/metro-config/index.d.ts b/packages/cli-plugin-metro/types/@react-native/metro-config/index.d.ts new file mode 100644 index 000000000..eaf8bba35 --- /dev/null +++ b/packages/cli-plugin-metro/types/@react-native/metro-config/index.d.ts @@ -0,0 +1,5 @@ +declare module '@react-native/metro-config' { + import type {ConfigT} from 'metro-config'; + + export function getDefaultConfig(projectRoot: string): ConfigT; +} diff --git a/yarn.lock b/yarn.lock index 7b05eee33..5c96ad8d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2673,6 +2673,21 @@ resolved "https://registry.yarnpkg.com/@react-native-community/eslint-plugin/-/eslint-plugin-1.1.0.tgz#e42b1bef12d2415411519fd528e64b593b1363dc" integrity sha512-W/J0fNYVO01tioHjvYWQ9m6RgndVtbElzYozBq1ZPrHO/iCzlqoySHl4gO/fpCl9QEFjvJfjPgtPMTMlsoq5DQ== +"@react-native/js-polyfills@^0.72.1": + version "0.72.1" + resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.72.1.tgz#905343ef0c51256f128256330fccbdb35b922291" + integrity sha512-cRPZh2rBswFnGt5X5EUEPs0r+pAsXxYsifv/fgy9ZLQokuT52bPH+9xjDR+7TafRua5CttGW83wP4TntRcWNDA== + +"@react-native/metro-config@^0.72.1": + version "0.72.1" + resolved "https://registry.yarnpkg.com/@react-native/metro-config/-/metro-config-0.72.1.tgz#57f212700db2d160e8beff6163558310c2c82220" + integrity sha512-BxGfuMK/cXwJxChE4/T6nE4qOdwGLM9iUFFKpcyh9Nks0702qTTvwpjkFbJvlkpe4yulAZh8CKLJrRDVzGGbfQ== + dependencies: + "@react-native/js-polyfills" "^0.72.1" + metro-config "0.76.0" + metro-react-native-babel-transformer "0.76.0" + metro-runtime "0.76.0" + "@sinonjs/commons@^1.7.0": version "1.7.1" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.1.tgz#da5fd19a5f71177a53778073978873964f49acf1" @@ -8916,6 +8931,19 @@ metro-react-native-babel-preset@0.76.0: babel-plugin-transform-flow-enums "^0.0.2" react-refresh "^0.4.0" +metro-react-native-babel-transformer@0.76.0: + version "0.76.0" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.76.0.tgz#8c8872f0d3a0ec9dad2480df53c92c10eac92c79" + integrity sha512-mLyUiGq2qPoEwV3oncD82HOtM4wAl8YmXtGY17D4iqH6/5pE32lRnDDYt0WnJYACZDs3RB3MhTjGCM7rJNwn/A== + dependencies: + "@babel/core" "^7.20.0" + babel-preset-fbjs "^3.4.0" + hermes-parser "0.8.0" + metro-babel-transformer "0.76.0" + metro-react-native-babel-preset "0.76.0" + metro-source-map "0.76.0" + nullthrows "^1.1.1" + metro-resolver@0.76.0: version "0.76.0" resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.76.0.tgz#3fa778adbab30859023a89e7a1241f4eb68171f2"