Skip to content

Commit fba90f1

Browse files
committed
fix(@angular/create): use appropriate package manager to install dependencies
Previously, NPM was always used to install dependencies even when using `yarn create` or `pnpm create`. Closes angular#23617
1 parent e995bda commit fba90f1

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

packages/angular/create/README.md

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
# `@angular/create`
22

3-
# Create an Angular CLI workspace
3+
## Create an Angular CLI workspace
44

55
Scaffold an Angular CLI workspace without needing to install the Angular CLI globally. All of the [ng new](https://angular.io/cli/new) options and features are supported.
66

7-
# Usage
7+
## Usage
88

9-
NPM
9+
### npm
1010

1111
```
1212
npm init @angular [project-name] -- [...options]
1313
```
1414

15-
Yarn
15+
### yarn
1616

1717
```
1818
yarn create @angular [project-name] [...options]
1919
```
20+
21+
### pnpm
22+
23+
```
24+
pnpm create @angular [project-name] [...options]
25+
```

packages/angular/create/src/index.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,30 @@ import { spawnSync } from 'child_process';
1111
import { join } from 'path';
1212

1313
const binPath = join(require.resolve('@angular/cli/package.json'), '../bin/ng.js');
14+
const [, execPath, ...args] = process.argv;
15+
16+
const hasPackageManagerArg = args.some((a) => a.includes('--package-manager'));
17+
if (!hasPackageManagerArg) {
18+
const isNpm = /[\\/]_npx[/\\]/.test(execPath);
19+
const isPnpm = /[\\/]pnpm[/\\]/.test(execPath);
20+
21+
let packageManager = 'npm';
22+
if (isPnpm) {
23+
packageManager = 'pnpm';
24+
} else if (!isNpm && !isPnpm) {
25+
packageManager = 'yarn';
26+
}
27+
28+
args.push('--package-manager', packageManager);
29+
if (isNpm && args.length) {
30+
// NPM required `--` before flags.
31+
const isFlag = args[0].charAt(0) === '-';
32+
args.splice(isFlag ? 0 : 1, 0, '--');
33+
}
34+
}
1435

1536
// Invoke ng new with any parameters provided.
16-
const { error } = spawnSync(process.execPath, [binPath, 'new', ...process.argv.slice(2)], {
37+
const { error } = spawnSync(process.execPath, [binPath, 'new', ...args], {
1738
stdio: 'inherit',
1839
});
1940

tests/legacy-cli/e2e/tests/misc/create-angular.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { join, resolve } from 'path';
2-
import { expectFileToExist, rimraf } from '../../utils/fs';
2+
import { expectFileToExist, readFile, rimraf } from '../../utils/fs';
33
import { getActivePackageManager } from '../../utils/packages';
44
import { silentNpm, silentYarn } from '../../utils/process';
55

@@ -26,7 +26,12 @@ export default async function () {
2626
throw new Error(`This test is not configured to use ${packageManager}.`);
2727
}
2828

29-
await expectFileToExist(join(projectName, 'angular.json'));
29+
// Check that package manager has been configured based on the package manager used to invoke the create command.
30+
const workspace = JSON.parse(await readFile(join(projectName, 'angular.json')));
31+
if (workspace.cli?.packageManager !== packageManager) {
32+
throw new Error(`Expected 'packageManager' option to be configured to ${packageManager}.`);
33+
}
34+
3035
// Verify styles was create with correct extension.
3136
await expectFileToExist(join(projectName, 'src/styles.scss'));
3237
} finally {

0 commit comments

Comments
 (0)