fix(@angular/cli): temporarily limit npm to version 6

This change will display an error message if using npm 7 (or versions earlier than 6). This is a temporarily change while npm 7 usability concerns are addressed.
This commit is contained in:
Charles Lyding 2021-02-04 15:38:19 -05:00 committed by Keen Yee Liau
parent ab5078d660
commit 331f628139
6 changed files with 78 additions and 3 deletions

View File

@ -88,7 +88,7 @@ function loadPackageJson(p: string) {
case 'engines':
pkg['engines'] = {
'node': '>= 10.13.0',
'npm': '>= 6.11.0',
'npm': '^6.11.0',
'yarn': '>= 1.13.0',
};
break;

View File

@ -15,7 +15,7 @@ import { Arguments } from '../models/interface';
import { RunSchematicOptions, SchematicCommand } from '../models/schematic-command';
import { colors } from '../utilities/color';
import { installPackage, installTempPackage } from '../utilities/install-package';
import { getPackageManager } from '../utilities/package-manager';
import { ensureCompatibleNpm, getPackageManager } from '../utilities/package-manager';
import {
NgAddSaveDepedency,
PackageManifest,
@ -39,6 +39,8 @@ export class AddCommand extends SchematicCommand<AddCommandSchema> {
}
async run(options: AddCommandSchema & Arguments) {
ensureCompatibleNpm();
if (!options.collection) {
this.logger.fatal(
`The "ng add" command requires a name argument to be specified eg. ` +

View File

@ -7,6 +7,7 @@
*/
import { Arguments } from '../models/interface';
import { SchematicCommand } from '../models/schematic-command';
import { ensureCompatibleNpm } from '../utilities/package-manager';
import { Schema as NewCommandSchema } from './new';
@ -21,6 +22,8 @@ export class NewCommand extends SchematicCommand<NewCommandSchema> {
}
public async run(options: NewCommandSchema & Arguments) {
ensureCompatibleNpm();
// Register the version of the CLI in the registry.
const packageJson = require('../package.json');
const version = packageJson.version;

View File

@ -18,7 +18,7 @@ import { SchematicEngineHost } from '../models/schematic-engine-host';
import { colors } from '../utilities/color';
import { runTempPackageBin } from '../utilities/install-package';
import { writeErrorToLogFile } from '../utilities/log-file';
import { getPackageManager } from '../utilities/package-manager';
import { ensureCompatibleNpm, getPackageManager } from '../utilities/package-manager';
import {
PackageIdentifier,
PackageManifest,
@ -267,6 +267,8 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
// tslint:disable-next-line:no-big-function
async run(options: UpdateCommandSchema & Arguments) {
ensureCompatibleNpm();
// Check if the current installed CLI version is older than the latest version.
if (!disableVersionCheck && await this.checkCLILatestVersion(options.verbose, options.next)) {
this.logger.warn(

View File

@ -54,3 +54,26 @@ export async function getPackageManager(root: string): Promise<PackageManager> {
// Potentially with a prompt to choose and optionally set as the default.
return packageManager || PackageManager.Npm;
}
/**
* Checks if the npm version is version 6.x. If not, display a message and exit.
*/
export function ensureCompatibleNpm() {
try {
const version = execSync('npm --version', {encoding: 'utf8', stdio: 'pipe'}).trim();
const major = Number(version.match(/^(\d+)\./)?.[1]);
if (major === 6) {
return;
}
// tslint:disable-next-line: no-console
console.error(
`npm version ${version} detected.\n` +
'The Angular CLI currently requires npm version 6.\n\n' +
'Please install a compatible version to proceed (`npm install --global npm@6`).\n',
);
process.exit(3);
} catch {
// npm is not installed
}
}

View File

@ -0,0 +1,45 @@
import { getActivePackageManager } from '../../utils/packages';
import { ng, npm } from '../../utils/process';
import { expectToFail } from '../../utils/utils';
const errorText = 'The Angular CLI currently requires npm version 6.';
export default async function() {
// Only relevant with npm as a package manager
if (getActivePackageManager() !== 'npm') {
return;
}
const currentDirectory = process.cwd();
try {
// Install version 7.x
await npm('install', '--global', 'npm@7');
// Ensure `ng add` exits and shows npm error
const { message: stderrAdd } = await expectToFail(() => ng('add'));
if (!stderrAdd.includes(errorText)) {
throw new Error('ng add expected to show npm version error.');
}
// Ensure `ng update` exits and shows npm error
const { message: stderrUpdate } = await expectToFail(() => ng('update'));
if (!stderrUpdate.includes(errorText)) {
throw new Error('ng update expected to show npm version error.');
}
// Ensure `ng new` exits and shows npm error
// Must be outside the project for `ng new`
process.chdir('..');
const { message: stderrNew } = await expectToFail(() => ng('new'));
if (!stderrNew.includes(errorText)) {
throw new Error('ng new expected to show npm version error.');
}
} finally {
// Change directory back
process.chdir(currentDirectory);
// Reset version back to 6.x
await npm('install', '--global', 'npm@6');
}
}