Skip to content

Commit 71b029e

Browse files
committed
refactor: use create-expo-app to generate expo example
1 parent b5a8513 commit 71b029e

File tree

9 files changed

+163
-11813
lines changed

9 files changed

+163
-11813
lines changed

packages/create-react-native-library/src/index.ts

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import ora from 'ora';
99
import validateNpmPackage from 'validate-npm-package-name';
1010
import githubUsername from 'github-username';
1111
import prompts, { PromptObject } from './utils/prompts';
12-
import generateRNApp from './utils/generateRNApp';
12+
import generateExampleApp from './utils/generateExampleApp';
1313

1414
const FALLBACK_BOB_VERSION = '0.18.3';
1515

@@ -384,6 +384,7 @@ async function create(argv: yargs.Arguments<any>) {
384384
url: authorUrl,
385385
},
386386
repo: repoUrl,
387+
example,
387388
};
388389

389390
const copyDir = async (source: string, dest: string) => {
@@ -419,13 +420,12 @@ async function create(argv: yargs.Arguments<any>) {
419420

420421
const spinner = ora('Generating example app').start();
421422

422-
if (example === 'native') {
423-
await generateRNApp({
424-
dest: folder,
425-
projectName: options.project.name,
426-
isNewArch: options.project.turbomodule,
427-
});
428-
}
423+
await generateExampleApp({
424+
type: example,
425+
dest: folder,
426+
projectName: options.project.name,
427+
isNewArch: options.project.turbomodule,
428+
});
429429

430430
spinner.succeed(
431431
`Project created successfully at ${kleur.yellow(argv.name)}!\n`
@@ -487,20 +487,18 @@ async function create(argv: yargs.Arguments<any>) {
487487
}
488488
}
489489

490-
if (example === 'native') {
491-
// Set `react` and `react-native` versions of root `package.json` from example `package.json`
492-
const examplePackageJson = fs.readJSONSync(
493-
path.join(folder, 'example', 'package.json')
494-
);
495-
const rootPackageJson = fs.readJSONSync(path.join(folder, 'package.json'));
496-
rootPackageJson.devDependencies.react =
497-
examplePackageJson.dependencies.react;
498-
rootPackageJson.devDependencies['react-native'] =
499-
examplePackageJson.dependencies['react-native'];
500-
fs.writeJSONSync(path.join(folder, 'package.json'), rootPackageJson, {
501-
spaces: 2,
502-
});
503-
}
490+
// Set `react` and `react-native` versions of root `package.json` from example `package.json`
491+
const examplePackageJson = fs.readJSONSync(
492+
path.join(folder, 'example', 'package.json')
493+
);
494+
const rootPackageJson = fs.readJSONSync(path.join(folder, 'package.json'));
495+
rootPackageJson.devDependencies.react = examplePackageJson.dependencies.react;
496+
rootPackageJson.devDependencies['react-native'] =
497+
examplePackageJson.dependencies['react-native'];
498+
499+
fs.writeJSONSync(path.join(folder, 'package.json'), rootPackageJson, {
500+
spaces: 2,
501+
});
504502

505503
try {
506504
spawn.sync('git', ['init'], { cwd: folder });
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import fs from 'fs-extra';
2+
import spawn from 'cross-spawn';
3+
import path from 'path';
4+
5+
const FILES_TO_DELETE = [
6+
'__tests__',
7+
'.buckconfig',
8+
'.eslintrc.js',
9+
'.flowconfig',
10+
'.git',
11+
'.gitignore',
12+
'.prettierrc.js',
13+
'App.js',
14+
'index.js',
15+
];
16+
17+
const PACKAGES_TO_REMOVE = [
18+
'@react-native-community/eslint-config',
19+
'babel-jest',
20+
'eslint',
21+
'jest',
22+
'react-test-renderer',
23+
];
24+
25+
const PACKAGES_TO_ADD = {
26+
'babel-plugin-module-resolver': '^4.1.0',
27+
};
28+
29+
const PACKAGES_TO_ADD_NEW_ARCH = {
30+
'patch-package': '^6.4.7',
31+
'postinstall-postinstall': '^2.1.0',
32+
};
33+
34+
export default async function generateExampleApp({
35+
type,
36+
dest,
37+
projectName,
38+
isNewArch,
39+
}: {
40+
type: 'expo' | 'native';
41+
dest: string;
42+
projectName: string;
43+
isNewArch: boolean;
44+
}) {
45+
const directory = path.join(dest, 'example');
46+
const args =
47+
type === 'native'
48+
? // `npx react-native init <projectName> --directory example --skip-install`
49+
[
50+
'react-native',
51+
'init',
52+
`${projectName}Example`,
53+
'--directory',
54+
directory,
55+
'--skip-install',
56+
]
57+
: // `npx create-expo-app example --no-install`
58+
['create-expo-app', directory, '--no-install'];
59+
60+
const child = spawn('npx', ['--yes', ...args], {
61+
cwd: dest,
62+
});
63+
64+
await new Promise((resolve, reject) => {
65+
child.once('error', reject);
66+
child.once('close', resolve);
67+
});
68+
69+
// Remove unnecessary files and folders
70+
for (const file of FILES_TO_DELETE) {
71+
await fs.remove(path.join(directory, file));
72+
}
73+
74+
// Patch the example app's package.json
75+
const pkg = JSON.parse(
76+
await fs.readFile(path.join(directory, 'package.json'), 'utf8')
77+
);
78+
79+
// Remove Jest config for now
80+
delete pkg.jest;
81+
82+
const { scripts, devDependencies } = pkg;
83+
84+
delete scripts.test;
85+
delete scripts.lint;
86+
87+
if (type === 'native') {
88+
scripts.pods = 'pod-install --quiet';
89+
}
90+
91+
PACKAGES_TO_REMOVE.forEach((pkg) => {
92+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
93+
delete devDependencies[pkg];
94+
});
95+
96+
Object.assign(devDependencies, PACKAGES_TO_ADD);
97+
98+
// Temporary until autolinking is fixed on iOS
99+
// https://github.com/facebook/react-native/commit/a5622165c198ac6e7ffff5883d4f269a2c974f2e
100+
if (isNewArch) {
101+
scripts.postinstall = 'patch-package';
102+
103+
Object.assign(devDependencies, PACKAGES_TO_ADD_NEW_ARCH);
104+
}
105+
106+
await fs.writeFile(
107+
path.join(directory, 'package.json'),
108+
JSON.stringify(pkg, null, 2)
109+
);
110+
111+
// If the library is on new architecture, enable new arch for iOS and Android
112+
if (isNewArch) {
113+
// Android
114+
// Change newArchEnabled=false to newArchEnabled=true in example/android/gradle.properties
115+
const gradleProperties = await fs.readFile(
116+
path.join(directory, 'android', 'gradle.properties'),
117+
'utf8'
118+
);
119+
120+
await fs.writeFile(
121+
path.join(directory, 'android', 'gradle.properties'),
122+
gradleProperties.replace('newArchEnabled=false', 'newArchEnabled=true')
123+
);
124+
125+
// iOS
126+
// Add ENV['RCT_NEW_ARCH_ENABLED'] = 1 on top of example/ios/Podfile
127+
const podfile = await fs.readFile(
128+
path.join(directory, 'ios', 'Podfile'),
129+
'utf8'
130+
);
131+
132+
await fs.writeFile(
133+
path.join(directory, 'ios', 'Podfile'),
134+
"ENV['RCT_NEW_ARCH_ENABLED'] = '1'\n" + podfile
135+
);
136+
}
137+
}

packages/create-react-native-library/src/utils/generateRNApp.ts

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

packages/create-react-native-library/templates/common/$package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@
3333
"prepare": "bob build",
3434
"release": "release-it",
3535
"example": "yarn --cwd example",
36-
"bootstrap": "yarn example && yarn && yarn example pods"
36+
<% if (example == 'native') { -%>
37+
"bootstrap": "yarn example && yarn install && yarn example pods"
38+
<% } else { -%>
39+
"bootstrap": "yarn example && yarn install"
40+
<% } -%>
3741
},
3842
"keywords": [
3943
"react-native",

packages/create-react-native-library/templates/expo-library/example/$package.json

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './src/App';

packages/create-react-native-library/templates/expo-library/example/app.json

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

0 commit comments

Comments
 (0)