Skip to content

Commit db2bd3e

Browse files
authoredJan 15, 2024
feat: allow overriding commands from react-native.config.js (#2229)
* feat: allow overriding commands * chore: remove duplicates * chore: update snaphosts * docs: add note about overriding config
1 parent aef1894 commit db2bd3e

File tree

4 files changed

+91
-3
lines changed

4 files changed

+91
-3
lines changed
 

‎docs/plugins.md

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ At the startup, React Native CLI reads configuration from all dependencies liste
2727

2828
At the end, an array of commands concatenated from all plugins is passed on to the CLI to be loaded after built-in commands.
2929

30+
Also, you can provide your own configuration by creating a `react-native.config.js` file in the root of the project, which overrides the configuration from plugins.
31+
3032
> See [`healthChecks`](./healthChecks.md) for information on how plugins can provide additional health checks for `npx react-native doctor`.
3133
3234
## Command interface

‎packages/cli-config/src/__tests__/__snapshots__/index-test.ts.snap

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`command specified in root config should overwrite command in "react-native-foo" and "react-native-bar" packages 1`] = `
4+
Object {
5+
"func": [Function],
6+
"name": "foo-command",
7+
"options": Array [
8+
Object {
9+
"description": "Custom option",
10+
"name": "--option",
11+
},
12+
],
13+
}
14+
`;
15+
316
exports[`should apply build types from dependency config 1`] = `
417
Object {
518
"name": "react-native-test",
@@ -35,11 +48,17 @@ exports[`should load commands from "react-native-foo" and "react-native-bar" pac
3548
Array [
3649
Object {
3750
"func": [Function],
38-
"name": "foo-command",
51+
"name": "bar-command",
3952
},
4053
Object {
4154
"func": [Function],
42-
"name": "bar-command",
55+
"name": "foo-command",
56+
"options": Array [
57+
Object {
58+
"description": "Custom option",
59+
"name": "--option",
60+
},
61+
],
4362
},
4463
]
4564
`;

‎packages/cli-config/src/__tests__/index-test.ts

+53
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,59 @@ test('should read a config of a dependency and use it to load other settings', (
128128
).toMatchSnapshot();
129129
});
130130

131+
test('command specified in root config should overwrite command in "react-native-foo" and "react-native-bar" packages', () => {
132+
DIR = getTempDirectory('config_test_packages');
133+
writeFiles(DIR, {
134+
'node_modules/react-native-foo/package.json': '{}',
135+
'node_modules/react-native-foo/react-native.config.js': `module.exports = {
136+
commands: [
137+
{
138+
name: 'foo-command',
139+
func: () => console.log('foo')
140+
}
141+
]
142+
}`,
143+
'node_modules/react-native-bar/package.json': '{}',
144+
'node_modules/react-native-bar/react-native.config.js': `module.exports = {
145+
commands: [
146+
{
147+
name: 'bar-command',
148+
func: () => console.log('bar')
149+
}
150+
]
151+
}`,
152+
'package.json': `{
153+
"dependencies": {
154+
"react-native-foo": "0.0.1",
155+
"react-native-bar": "0.0.1"
156+
}
157+
}`,
158+
'react-native.config.js': `module.exports = {
159+
reactNativePath: '.',
160+
commands: [
161+
{
162+
name: 'foo-command',
163+
func: () => {
164+
console.log('overridden foo command');
165+
},
166+
options: [
167+
{
168+
name: '--option',
169+
description: 'Custom option',
170+
},
171+
],
172+
},
173+
],
174+
};`,
175+
});
176+
const {commands} = loadConfig(DIR);
177+
const commandsNames = commands.map(({name}) => name);
178+
const commandIndex = commandsNames.indexOf('foo-command');
179+
180+
expect(commands[commandIndex].options).not.toBeNull();
181+
expect(commands[commandIndex]).toMatchSnapshot();
182+
});
183+
131184
test('should merge project configuration with default values', () => {
132185
DIR = getTempDirectory('config_test_merge');
133186
writeFiles(DIR, {

‎packages/cli-config/src/loadConfig.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
DependencyConfig,
66
UserConfig,
77
Config,
8+
Command,
89
} from '@react-native-community/cli-types';
910
import {
1011
findProjectRoot,
@@ -72,6 +73,16 @@ function getReactNativeVersion(reactNativePath: string) {
7273
return 'unknown';
7374
}
7475

76+
const removeDuplicateCommands = <T extends boolean>(commands: Command<T>[]) => {
77+
const uniqueCommandsMap = new Map();
78+
79+
commands.forEach((command) => {
80+
uniqueCommandsMap.set(command.name, command);
81+
});
82+
83+
return Array.from(uniqueCommandsMap.values());
84+
};
85+
7586
/**
7687
* Loads CLI configuration
7788
*/
@@ -143,7 +154,10 @@ function loadConfig(projectRoot: string = findProjectRoot()): Config {
143154
);
144155
},
145156
}),
146-
commands: [...acc.commands, ...config.commands],
157+
commands: removeDuplicateCommands([
158+
...config.commands,
159+
...acc.commands,
160+
]),
147161
platforms: {
148162
...acc.platforms,
149163
...config.platforms,

0 commit comments

Comments
 (0)
Please sign in to comment.