Skip to content

Commit 84acbdd

Browse files
authored
fix(init): harden npm project creation flow (#1370)
1 parent d0058e2 commit 84acbdd

4 files changed

Lines changed: 49 additions & 8 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@callstack/repack-init": patch
3+
---
4+
5+
Fix npm-based project creation by using `npm exec ... -- rnc-cli` instead of a nested `npx` invocation, and pass a fully qualified React Native patch version to the React Native CLI.

packages/init/src/tasks/createNewProject.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,53 @@ import type { PackageManager } from '../types/pm.js';
55
import { RepackInitError } from '../utils/error.js';
66
import spinner from '../utils/spinner.js';
77

8+
function getCreateCommand(packageManager: PackageManager) {
9+
if (packageManager.name === 'npm') {
10+
// Use `npm exec` with the package's explicit bin name. Nested `npx`
11+
// invocations can fail when repack-init itself is launched through `npx`.
12+
return {
13+
command: packageManager.runCommand,
14+
args: [
15+
'exec',
16+
'--yes',
17+
'--package',
18+
'@react-native-community/cli@latest',
19+
'--',
20+
'rnc-cli',
21+
],
22+
shell: false,
23+
};
24+
}
25+
26+
return {
27+
command: packageManager.dlxCommand,
28+
args: ['@react-native-community/cli@latest'],
29+
shell: true,
30+
};
31+
}
32+
33+
function getReactNativeVersion() {
34+
const version = versionsJson['react-native'];
35+
36+
return /^\d+\.\d+$/.test(version) ? `${version}.0` : version;
37+
}
38+
839
export default async function createNewProject(
940
cwd: string,
1041
projectName: string,
1142
packageManager: PackageManager,
1243
override: boolean
1344
) {
1445
try {
46+
const createCommand = getCreateCommand(packageManager);
1547
const args = [
16-
'@react-native-community/cli@latest',
48+
...createCommand.args,
1749
'init',
1850
projectName,
1951
'--directory',
2052
path.join(cwd, projectName),
2153
'--version',
22-
versionsJson['react-native'],
54+
getReactNativeVersion(),
2355
'--skip-install',
2456
'--skip-git-init',
2557
];
@@ -32,9 +64,9 @@ export default async function createNewProject(
3264
'Creating new project from the React Native Community Template'
3365
);
3466

35-
return await execa(packageManager.dlxCommand, args, {
67+
return await execa(createCommand.command, args, {
3668
stdio: 'ignore',
37-
shell: true,
69+
shell: createCommand.shell,
3870
});
3971
} catch {
4072
throw new RepackInitError(

packages/init/tsconfig.build.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"compilerOptions": {
4+
"rootDir": "src",
5+
"outDir": "dist"
6+
},
7+
"include": ["src/**/*.ts"]
8+
}

packages/init/tsconfig.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
{
22
"extends": "../../tsconfig.base.json",
3-
"compilerOptions": {
4-
"rootDir": "src",
5-
"outDir": "dist"
6-
},
73
"include": ["src/**/*.ts"]
84
}

0 commit comments

Comments
 (0)