Skip to content

Commit a99067f

Browse files
robhoganfacebook-github-bot
authored andcommitted
mergeConfig: Fix handling of partial config first argument
Summary: Typically the `metro-config` `mergeConfig` API is called with a fully populated config as its first argument (often `getDefaultValues(__dirname)`), but it has in fact always supported merging a partial config (`InputConfigT`) into another. This has a couple of bugs, however: 1. When the base config lacks a top-level `resolver` or `tranformer` config, the call fails hard on accessing a prop of `undefined`. 2. When neither config contains one of `cacheStores`, `transformer.babelTransformerPath`, `resolver.dependencyExtractor` or `resolver.hasteImplModulePath`, `mergeConfig` will cause that property to be set with a value of `undefined`, which could cause issues if that is subsequently spread over a config where they are populated. ``` - **[Fix]** Fix `mergeConfig` handling of 2+ partial configs ``` Reviewed By: motiz88 Differential Revision: D83475279 fbshipit-source-id: 7e181d0ab0526cd090b321dd2822c4339b430c6f
1 parent 463d17b commit a99067f

File tree

2 files changed

+56
-28
lines changed

2 files changed

+56
-28
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict-local
8+
* @format
9+
* @oncall react_native
10+
*/
11+
12+
import {mergeConfig} from '../loadConfig';
13+
14+
describe('mergeConfig', () => {
15+
test('can merge empty configs', () => {
16+
expect(mergeConfig({}, {})).toStrictEqual({
17+
resolver: {},
18+
serializer: {},
19+
server: {},
20+
symbolicator: {},
21+
transformer: {},
22+
watcher: {
23+
healthCheck: {},
24+
unstable_autoSaveCache: {},
25+
watchman: {},
26+
},
27+
});
28+
});
29+
});

packages/metro-config/src/loadConfig.js

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -110,54 +110,53 @@ function mergeConfigObjects<T: InputConfigT>(
110110
return {
111111
...base,
112112
...overrides,
113-
114-
cacheStores:
115-
overrides.cacheStores != null
116-
? typeof overrides.cacheStores === 'function'
117-
? overrides.cacheStores(MetroCache)
118-
: overrides.cacheStores
119-
: base.cacheStores,
113+
...(overrides.cacheStores != null
114+
? {
115+
cacheStores:
116+
typeof overrides.cacheStores === 'function'
117+
? overrides.cacheStores(MetroCache)
118+
: overrides.cacheStores,
119+
}
120+
: null),
120121

121122
resolver: {
122123
...base.resolver,
124+
...overrides.resolver,
123125
// $FlowFixMe[exponential-spread]
124-
...(overrides.resolver || {}),
125-
dependencyExtractor:
126-
overrides.resolver && overrides.resolver.dependencyExtractor != null
127-
? resolve(overrides.resolver.dependencyExtractor)
128-
: // $FlowFixMe[incompatible-use]
129-
base.resolver.dependencyExtractor,
130-
hasteImplModulePath:
131-
overrides.resolver && overrides.resolver.hasteImplModulePath != null
132-
? resolve(overrides.resolver.hasteImplModulePath)
133-
: // $FlowFixMe[incompatible-use]
134-
base.resolver.hasteImplModulePath,
126+
...(overrides.resolver?.dependencyExtractor != null
127+
? {dependencyExtractor: resolve(overrides.resolver.dependencyExtractor)}
128+
: null),
129+
...(overrides.resolver?.hasteImplModulePath != null
130+
? {hasteImplModulePath: resolve(overrides.resolver.hasteImplModulePath)}
131+
: null),
135132
},
136133
serializer: {
137134
...base.serializer,
138135
// $FlowFixMe[exponential-spread]
139-
...(overrides.serializer || {}),
136+
...overrides.serializer,
140137
},
141138
transformer: {
142139
...base.transformer,
143140
// $FlowFixMe[exponential-spread]
144-
...(overrides.transformer || {}),
145-
babelTransformerPath:
146-
overrides.transformer &&
147-
overrides.transformer.babelTransformerPath != null
148-
? resolve(overrides.transformer.babelTransformerPath)
149-
: // $FlowFixMe[incompatible-use]
150-
base.transformer.babelTransformerPath,
141+
...overrides.transformer,
142+
// $FlowFixMe[exponential-spread]
143+
...(overrides.transformer?.babelTransformerPath != null
144+
? {
145+
babelTransformerPath: resolve(
146+
overrides.transformer.babelTransformerPath,
147+
),
148+
}
149+
: null),
151150
},
152151
server: {
153152
...base.server,
154153
// $FlowFixMe[exponential-spread]
155-
...(overrides.server || {}),
154+
...overrides.server,
156155
},
157156
symbolicator: {
158157
...base.symbolicator,
159158
// $FlowFixMe[exponential-spread]
160-
...(overrides.symbolicator || {}),
159+
...overrides.symbolicator,
161160
},
162161
watcher: {
163162
...base.watcher,

0 commit comments

Comments
 (0)