Skip to content

Commit 065ac45

Browse files
clydinalan-agius4
authored andcommitted
fix(@angular/cli): remove npm 7 incompatibility notification
npm 7.5.6 contains several fixes that allow it to work successfully with the Angular CLI. The minimum npm engine value is now set to support npm versions greater than 7.5.6 (npm 6 support remains unchanged). A warning will be shown to users with npm 7 versions less than 7.5.6 when used with the new, add, or update commands.
1 parent 7ef73c8 commit 065ac45

File tree

3 files changed

+44
-36
lines changed

3 files changed

+44
-36
lines changed

lib/packages.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ function loadPackageJson(p: string) {
8888
case 'engines':
8989
pkg['engines'] = {
9090
'node': '>= 12.13.0',
91-
'npm': '^6.11.0',
91+
'npm': '^6.11.0 || ^7.5.6',
9292
'yarn': '>= 1.13.0',
9393
};
9494
break;

packages/angular/cli/utilities/package-manager.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import { execSync } from 'child_process';
99
import { existsSync } from 'fs';
1010
import { join } from 'path';
11+
import { satisfies, valid } from 'semver';
1112
import { PackageManager } from '../lib/config/schema';
1213
import { getConfiguredPackageManager } from './config';
1314

@@ -56,29 +57,27 @@ export async function getPackageManager(root: string): Promise<PackageManager> {
5657
}
5758

5859
/**
59-
* Checks if the npm version is version 6.x. If not, display a message and exit.
60+
* Checks if the npm version is a supported 7.x version. If not, display a warning.
6061
*/
6162
export async function ensureCompatibleNpm(root: string): Promise<void> {
6263
if ((await getPackageManager(root)) !== PackageManager.Npm) {
6364
return;
6465
}
6566

6667
try {
67-
const version = execSync('npm --version', {encoding: 'utf8', stdio: 'pipe'}).trim();
68-
const major = Number(version.match(/^(\d+)\./)?.[1]);
69-
if (major <= 6) {
68+
const versionText = execSync('npm --version', {encoding: 'utf8', stdio: 'pipe'}).trim();
69+
const version = valid(versionText);
70+
if (!version) {
7071
return;
7172
}
7273

73-
// tslint:disable-next-line: no-console
74-
console.error(
75-
`npm version ${version} detected. The Angular CLI temporarily requires npm version 6 while upstream issues are addressed.\n\n` +
76-
'Please install a compatible version to proceed (`npm install --global npm@6`).\n' +
77-
'For additional information and alternative workarounds, please see ' +
78-
'https://github.com/angular/angular-cli/issues/19957#issuecomment-775407654',
79-
);
80-
81-
process.exit(3);
74+
if (satisfies(version, '>=7 <7.5.6')) {
75+
// tslint:disable-next-line: no-console
76+
console.warn(
77+
`npm version ${version} detected.` +
78+
' When using npm 7 with the Angular CLI, npm version 7.5.6 or higher is recommended.',
79+
);
80+
}
8281
} catch {
8382
// npm is not installed
8483
}

tests/legacy-cli/e2e/tests/misc/npm-7.ts

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { getActivePackageManager } from '../../utils/packages';
33
import { ng, npm } from '../../utils/process';
44
import { expectToFail } from '../../utils/utils';
55

6-
const errorText = 'The Angular CLI temporarily requires npm version 6';
6+
const warningText = 'npm version 7.5.6 or higher is recommended';
77

88
export default async function() {
99
// Only relevant with npm as a package manager
@@ -18,53 +18,62 @@ export default async function() {
1818

1919
const currentDirectory = process.cwd();
2020
try {
21-
// Install version 7.x
22-
await npm('install', '--global', 'npm@7');
21+
// Install version >=7.5.6
22+
await npm('install', '--global', 'npm@>=7.5.6');
2323

24-
// Ensure `ng add` exits and shows npm error
24+
// Ensure `ng update` does not show npm warning
25+
const { stderr: stderrUpdate1 } = await ng('update');
26+
if (stderrUpdate1.includes(warningText)) {
27+
throw new Error('ng update expected to not show npm version warning.');
28+
}
29+
30+
// Install version <7.5.6
31+
await npm('install', '--global', 'npm@7.4.0');
32+
33+
// Ensure `ng add` shows npm warning
2534
const { message: stderrAdd } = await expectToFail(() => ng('add'));
26-
if (!stderrAdd.includes(errorText)) {
27-
throw new Error('ng add expected to show npm version error.');
35+
if (!stderrAdd.includes(warningText)) {
36+
throw new Error('ng add expected to show npm version warning.');
2837
}
2938

30-
// Ensure `ng update` exits and shows npm error
31-
const { message: stderrUpdate } = await expectToFail(() => ng('update'));
32-
if (!stderrUpdate.includes(errorText)) {
33-
throw new Error('ng update expected to show npm version error.');
39+
// Ensure `ng update` shows npm warning
40+
const { stderr: stderrUpdate2 } = await ng('update');
41+
if (!stderrUpdate2.includes(warningText)) {
42+
throw new Error('ng update expected to show npm version warning.');
3443
}
3544

3645
// Ensure `ng build` executes successfully
3746
const { stderr: stderrBuild } = await ng('build');
38-
if (stderrBuild.includes(errorText)) {
39-
throw new Error('ng build expected to not show npm version error.');
47+
if (stderrBuild.includes(warningText)) {
48+
throw new Error('ng build expected to not show npm version warning.');
4049
}
4150

42-
// Ensure `ng new` exits and shows npm error
51+
// Ensure `ng new` shows npm warning
4352
// Must be outside the project for `ng new`
4453
process.chdir('..');
4554
const { message: stderrNew } = await expectToFail(() => ng('new'));
46-
if (!stderrNew.includes(errorText)) {
47-
throw new Error('ng new expected to show npm version error.');
55+
if (!stderrNew.includes(warningText)) {
56+
throw new Error('ng new expected to show npm version warning.');
4857
}
4958

50-
// Ensure `ng new --package-manager=npm` exits and shows npm error
59+
// Ensure `ng new --package-manager=npm` shows npm warning
5160
const { message: stderrNewNpm } = await expectToFail(() => ng('new', '--package-manager=npm'));
52-
if (!stderrNewNpm.includes(errorText)) {
53-
throw new Error('ng new expected to show npm version error.');
61+
if (!stderrNewNpm.includes(warningText)) {
62+
throw new Error('ng new expected to show npm version warning.');
5463
}
5564

5665
// Ensure `ng new --skip-install` executes successfully
5766
const { stderr: stderrNewSkipInstall } = await ng('new', 'npm-seven-skip', '--skip-install');
58-
if (stderrNewSkipInstall.includes(errorText)) {
59-
throw new Error('ng new --skip-install expected to not show npm version error.');
67+
if (stderrNewSkipInstall.includes(warningText)) {
68+
throw new Error('ng new --skip-install expected to not show npm version warning.');
6069
}
6170

6271
// Ensure `ng new --package-manager=yarn` executes successfully
6372
// Need an additional npmrc file since yarn does not use the NPM registry environment variable
6473
await writeFile('.npmrc', 'registry=http://localhost:4873')
6574
const { stderr: stderrNewYarn } = await ng('new', 'npm-seven-yarn', '--package-manager=yarn');
66-
if (stderrNewYarn.includes(errorText)) {
67-
throw new Error('ng new --package-manager=yarn expected to not show npm version error.');
75+
if (stderrNewYarn.includes(warningText)) {
76+
throw new Error('ng new --package-manager=yarn expected to not show npm version warning.');
6877
}
6978
} finally {
7079
// Cleanup extra test projects

0 commit comments

Comments
 (0)