Skip to content

Commit e18f8cc

Browse files
author
Benjamin Reid
authored
React Query Option (#128)
* Remove custom TypeScript setup for community template * Remove need to run react navigation configure script * Remove need to copy react navigations java file changes * No need to delete .flowconfig * Fix typo * Add example env * Delete the ts(x) files rather than JS * Only run pretty over the app folder * Switch to using npx pod install to install pods * Add in types for styled components * Main bulk of work to switch to react query option * Remove space * Fix tsconfig * Fix bundled types * React query example * Configure console for React native * Notes around react-query * Fix tests * Alter note around running the app * Install react-native-make * Spelling fix
1 parent ead5625 commit e18f8cc

File tree

21 files changed

+265
-229
lines changed

21 files changed

+265
-229
lines changed

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ npx romulus-cli init
4848
Create a new React Native project using their CLI tool.
4949

5050
```
51-
react-native init MyApp && cd MyApp
51+
npx react-native init MyApp --template react-native-template-typescript
52+
cd MyApp
5253
```
5354

5455
Once this is complete, simply run the main generator command. This will rework
@@ -63,11 +64,14 @@ romulus init
6364

6465
- A sensible `README` providing consistent instructions between projects
6566
- TypeScript support
66-
- Router using `react-navigation`
67-
- Redux setup
67+
- Router using `react-navigation` (v5)
68+
- Redux setup (optional)
6869
- Store is persisted using `redux-persist`
6970
- Helpful state changes logged in the debugger using `redux-logger`
7071
- Actions are prevented from being dispatched before the cache is restored
72+
- `react-query` setup (optional)
73+
- Makes it easy to get setup with `react-query`
74+
- Replaces Saga and Redux architecture
7175
- UI niceities
7276
- CSS-in-JS support for `styled-components`
7377
- Start to a styleguide to list your components
@@ -81,7 +85,7 @@ romulus init
8185
- Optional support for different locales using `react-native-i18n`
8286
- Environment variables available in JavaScript, Objective C and Java using
8387
`react-native-config`
84-
- Sagas (to handle async tasks like HTTP requests) using `redux-saga`
88+
- Sagas (to handle async tasks like HTTP requests) using `redux-saga` (optional, not available with `react-query`)
8589
- Initial setup for deep linking
8690
- Requests are set up to be handled with `axios` with clear logging in the
8791
debugger provided

docs/commands.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ const initialState: State = {
119119

120120
const reducer = (
121121
state = initialState,
122-
action: SettingsActions | ReducerAction
122+
action: SettingsActions,
123123
): State => {
124124
switch (action.type) {
125125
case SETTINGS_EXAMPLE:

generators/base/index.js

Lines changed: 99 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,23 @@ module.exports = class extends Generator {
1313

1414
prompting() {
1515
return this.prompt([
16+
{
17+
type: "list",
18+
name: "httpLayer",
19+
message: "Which HTTP layer do you want to use?",
20+
choices: ["react-query", "redux-saga"],
21+
default: "react-query",
22+
},
1623
{
1724
type: "confirm",
1825
name: "i18nSupport",
1926
message: "Do you want i18n support?",
2027
default: true,
2128
},
22-
]).then(answers => {
29+
]).then((answers) => {
2330
this.i18nSupport = answers.i18nSupport;
31+
this.usingReactQuery = answers.httpLayer === "react-query";
32+
this.usingReduxSaga = answers.httpLayer === "redux-saga";
2433
});
2534
}
2635

@@ -29,7 +38,7 @@ module.exports = class extends Generator {
2938
this.fs.copyTpl(
3039
this.templatePath("index.js"),
3140
this.destinationPath("index.js"),
32-
{ name: this.name }
41+
{ name: this.name, usingReactQuery: this.usingReactQuery }
3342
);
3443

3544
// copy Prettier config
@@ -38,38 +47,39 @@ module.exports = class extends Generator {
3847
this.destinationPath(".prettierrc.js")
3948
);
4049

41-
// copy Prettier config
50+
// copy ESLint config
4251
this.fs.copyTpl(
4352
this.templatePath(".eslintrc.js"),
4453
this.destinationPath(".eslintrc.js")
4554
);
4655

56+
this.fs.copyTpl(
57+
this.templatePath("jest.config.js"),
58+
this.destinationPath("jest.config.js")
59+
);
60+
4761
// copy TypeSCript config
4862
this.fs.copyTpl(
4963
this.templatePath("tsconfig.json"),
5064
this.destinationPath("tsconfig.json"),
5165
{ name: this.name }
5266
);
5367

54-
this.fs.copyTpl(
55-
this.templatePath("jest.config.js"),
56-
this.destinationPath("jest.config.js")
57-
);
58-
59-
// remove App.js generated by RN
60-
this.fs.delete("App.js");
61-
62-
// remove Flow configuration
63-
this.fs.delete(".flowconfig");
68+
// remove default App generated by RN
69+
this.fs.delete("App.tsx");
6470

6571
// remove default test
66-
this.fs.delete("__tests__/App-test.js");
72+
this.fs.delete("__tests__/App-test.tsx");
6773

6874
// copy root app file that the entry points use
6975
this.fs.copyTpl(
7076
this.templatePath("App/index.tsx"),
7177
this.destinationPath("App/index.tsx"),
72-
{ name: this.name }
78+
{
79+
name: this.name,
80+
usingReduxSaga: this.usingReduxSaga,
81+
usingReactQuery: this.usingReactQuery,
82+
}
7383
);
7484

7585
// copy router
@@ -86,6 +96,7 @@ module.exports = class extends Generator {
8696
{
8797
name: this.name,
8898
i18nSupport: this.i18nSupport,
99+
usingReactQuery: this.usingReactQuery,
89100
}
90101
);
91102

@@ -96,40 +107,54 @@ module.exports = class extends Generator {
96107
{ name: this.name }
97108
);
98109

99-
// copy store
100-
this.fs.copyTpl(
101-
this.templatePath("App/Store/index.ts"),
102-
this.destinationPath("App/Store/index.ts"),
103-
{ name: this.name }
104-
);
110+
if (this.usingReduxSaga) {
111+
this.fs.copyTpl(
112+
this.templatePath("@types/react-redux.d.ts"),
113+
this.destinationPath("@types/react-redux.d.ts"),
114+
{ name: this.name }
115+
);
105116

106-
// copy store middleware
107-
this.fs.copyTpl(
108-
this.templatePath("App/Store/Middleware"),
109-
this.destinationPath("App/Store/Middleware"),
110-
{ name: this.name }
111-
);
117+
this.fs.copyTpl(
118+
this.templatePath("@types/redux-action-buffer.d.ts"),
119+
this.destinationPath("@types/redux-action-buffer.d.ts"),
120+
{ name: this.name }
121+
);
112122

113-
// copy reducers
114-
this.fs.copyTpl(
115-
this.templatePath("App/Reducers"),
116-
this.destinationPath("App/Reducers"),
117-
{ name: this.name, reducers: ["App"] }
118-
);
123+
// copy store
124+
this.fs.copyTpl(
125+
this.templatePath("App/Store/index.ts"),
126+
this.destinationPath("App/Store/index.ts"),
127+
{ name: this.name }
128+
);
119129

120-
// copy actions
121-
this.fs.copyTpl(
122-
this.templatePath("App/Actions"),
123-
this.destinationPath("App/Actions"),
124-
{ name: this.name }
125-
);
130+
// copy store middleware
131+
this.fs.copyTpl(
132+
this.templatePath("App/Store/Middleware"),
133+
this.destinationPath("App/Store/Middleware"),
134+
{ name: this.name }
135+
);
126136

127-
// copy sagas
128-
this.fs.copyTpl(
129-
this.templatePath("App/Sagas"),
130-
this.destinationPath("App/Sagas"),
131-
{ name: this.name }
132-
);
137+
// copy reducers
138+
this.fs.copyTpl(
139+
this.templatePath("App/Reducers"),
140+
this.destinationPath("App/Reducers"),
141+
{ name: this.name, reducers: ["App"] }
142+
);
143+
144+
// copy actions
145+
this.fs.copyTpl(
146+
this.templatePath("App/Actions"),
147+
this.destinationPath("App/Actions"),
148+
{ name: this.name }
149+
);
150+
151+
// copy sagas
152+
this.fs.copyTpl(
153+
this.templatePath("App/Sagas"),
154+
this.destinationPath("App/Sagas"),
155+
{ name: this.name }
156+
);
157+
}
133158

134159
// copy services
135160
this.fs.copyTpl(
@@ -178,6 +203,15 @@ module.exports = class extends Generator {
178203
api_url: "http://localhost:3000",
179204
storage_prefix: "development",
180205
});
206+
this.fs.copyTpl(
207+
this.templatePath(".env"),
208+
this.destinationPath(".env.example"),
209+
{
210+
env: "development",
211+
api_url: "http://localhost:3000",
212+
storage_prefix: "development",
213+
}
214+
);
181215
this.fs.copyTpl(
182216
this.templatePath(".env"),
183217
this.destinationPath(".env.staging"),
@@ -212,13 +246,6 @@ module.exports = class extends Generator {
212246
this.destinationPath("__mocks__")
213247
);
214248

215-
// copy TypeScript types
216-
this.fs.copyTpl(
217-
this.templatePath("@types"),
218-
this.destinationPath("@types"),
219-
{ name: this.name }
220-
);
221-
222249
this.fs.copyTpl(
223250
this.templatePath("README.md"),
224251
this.destinationPath("README.md"),
@@ -232,23 +259,15 @@ module.exports = class extends Generator {
232259
{ name: this.name }
233260
);
234261

235-
// copy android files
236-
this.fs.copyTpl(
237-
this.templatePath("android/MainActivity.java"),
238-
this.destinationPath(
239-
`android/app/src/main/java/com/${this.name.toLowerCase()}/MainActivity.java`
240-
),
241-
{ name: this.name, nameLower: this.name.toLowerCase() }
242-
);
243-
244262
// merge the two package json files
245263
const currentPackage = readPkg.sync();
246264

247265
writePkg.sync(
248266
deepExtend(currentPackage, {
249267
private: true,
250268
scripts: {
251-
pretty: "prettier --config .prettierrc.js --write '**/*.{ts,tsx,js}'",
269+
pretty:
270+
"prettier --config .prettierrc.js --write 'App/**/*.{ts,tsx,js}'",
252271
lint: "eslint --fix './App/**/*.{ts,tsx,js}'",
253272
bump: "./bin/bump-ios.sh",
254273
test: "jest --verbose",
@@ -274,42 +293,41 @@ module.exports = class extends Generator {
274293
const reactNavigation = [
275294
"@react-navigation/native",
276295
"@react-navigation/stack",
277-
"react-native-gesture-handler",
278296
"react-native-reanimated",
297+
"react-native-gesture-handler",
279298
"react-native-screens",
280299
"react-native-safe-area-context",
281300
"@react-native-community/masked-view",
282301
];
283302

284-
this.yarnInstall([
285-
"@react-native-community/async-storage",
286-
"axios",
287-
"https://github.com/luggit/react-native-config#master",
288-
...(this.i18nSupport ? ["react-native-i18n"] : []),
303+
const reduxSagaModules = [
289304
"react-redux",
290305
"redux",
291306
"redux-action-buffer",
292307
"redux-logger",
293308
"redux-persist",
294309
"redux-saga",
310+
];
311+
312+
const reactQueryModules = ["react-query"];
313+
314+
const types = ["@types/styled-components"];
315+
316+
this.yarnInstall([
317+
"@react-native-community/async-storage",
318+
"axios",
319+
"react-native-config",
295320
"styled-components",
296321
...reactNavigation,
322+
...(this.i18nSupport ? ["react-native-i18n"] : []),
323+
...(this.usingReduxSaga ? reduxSagaModules : []),
324+
...(this.usingReactQuery ? reactQueryModules : []),
297325
]);
298326

299-
const typeScript = [
300-
"typescript",
301-
"@types/jest",
302-
"@types/react",
303-
"@types/react-native",
304-
"@types/react-test-renderer",
305-
"@types/styled-components",
306-
"@types/react-redux",
307-
"@types/redux-logger",
308-
"@types/node",
309-
];
310-
311327
this.yarnInstall(
312328
[
329+
...types,
330+
"@bam.tech/react-native-make",
313331
"@testing-library/react-native",
314332
"eslint",
315333
"babel-eslint",
@@ -324,7 +342,6 @@ module.exports = class extends Generator {
324342
"eslint-plugin-tsc",
325343
"jest",
326344
"jest-styled-components",
327-
...typeScript,
328345
],
329346
{
330347
dev: true,
@@ -334,9 +351,7 @@ module.exports = class extends Generator {
334351

335352
end() {
336353
this.log("Installing Pods...");
337-
this.spawnCommandSync("pod", ["install"], {
338-
cwd: this.destinationPath("ios"),
339-
});
354+
this.spawnCommandSync("npx", ["pod-install"]);
340355

341356
this.log("Running Prettier...");
342357
this.spawnCommandSync("yarn", ["run", "pretty"]);
@@ -359,15 +374,6 @@ module.exports = class extends Generator {
359374
}
360375
);
361376

362-
this.log("Configuring React Navigation");
363-
this.spawnCommandSync(
364-
"python",
365-
[`${this.templatePath("bin")}/react-navigation.py`],
366-
{
367-
cwd: this.destinationPath(),
368-
}
369-
);
370-
371377
this.log("Creating iOS Schemes");
372378
this.spawnCommandSync(
373379
"python",

generators/base/templates/@types/index.d.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)