From 9641d6d254bd708c66a670b51639d316567c6a4c Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Thu, 27 Aug 2020 16:29:01 +0800 Subject: [PATCH] fix: fix support for Node.js v8 and deprecate it (#5827) Fixes #5800 --- packages/@vue/cli/bin/vue.js | 15 +++++--- packages/@vue/cli/lib/Creator.js | 35 +++++++++++------ .../cli/lib/util/ProjectPackageManager.js | 38 +++++++++++++++++++ 3 files changed, 70 insertions(+), 18 deletions(-) diff --git a/packages/@vue/cli/bin/vue.js b/packages/@vue/cli/bin/vue.js index c30d66a1e5..c65a809c49 100755 --- a/packages/@vue/cli/bin/vue.js +++ b/packages/@vue/cli/bin/vue.js @@ -19,12 +19,15 @@ function checkNodeVersion (wanted, id) { checkNodeVersion(requiredVersion, '@vue/cli') -if (semver.satisfies(process.version, '9.x')) { - console.log(chalk.red( - `You are using Node ${process.version}.\n` + - `Node.js 9.x has already reached end-of-life and will not be supported in future major releases.\n` + - `It's strongly recommended to use an active LTS version instead.` - )) +const EOL_NODE_MAJORS = ['8.x', '9.x', '11.x', '13.x'] +for (const major of EOL_NODE_MAJORS) { + if (semver.satisfies(process.version, major)) { + console.log(chalk.red( + `You are using Node ${process.version}.\n` + + `Node.js ${major} has already reached end-of-life and will not be supported in future major releases.\n` + + `It's strongly recommended to use an active LTS version instead.` + )) + } } const fs = require('fs') diff --git a/packages/@vue/cli/lib/Creator.js b/packages/@vue/cli/lib/Creator.js index 4dd321b778..ff947b912b 100644 --- a/packages/@vue/cli/lib/Creator.js +++ b/packages/@vue/cli/lib/Creator.js @@ -28,6 +28,7 @@ const { const { chalk, execa, + semver, log, warn, @@ -132,9 +133,10 @@ module.exports = class Creator extends EventEmitter { (hasYarn() ? 'yarn' : null) || (hasPnpm3OrLater() ? 'pnpm' : 'npm') ) - const pm = new PackageManager({ context, forcePackageManager: packageManager }) await clearConsole() + const pm = new PackageManager({ context, forcePackageManager: packageManager }) + log(`✨ Creating project in ${chalk.yellow(context)}.`) this.emit('creation', { event: 'creating' }) @@ -173,6 +175,26 @@ module.exports = class Creator extends EventEmitter { 'package.json': JSON.stringify(pkg, null, 2) }) + // generate a .npmrc file for pnpm, to persist the `shamefully-flatten` flag + if (packageManager === 'pnpm') { + const pnpmConfig = hasPnpmVersionOrLater('4.0.0') + ? 'shamefully-hoist=true\n' + : 'shamefully-flatten=true\n' + + await writeFileTree(context, { + '.npmrc': pnpmConfig + }) + } + + if (packageManager === 'yarn' && semver.satisfies(process.version, '8.x')) { + // Vue CLI 4.x should support Node 8.x, + // but some dependenices already bumped `engines` field to Node 10 + // and Yarn treats `engines` field too strictly + await writeFileTree(context, { + '.yarnrc': '# Hotfix for Node 8.x\n--install.ignore-engines true\n' + }) + } + // intilaize git repository before installing deps // so that vue-cli-service can setup git hooks. const shouldInitGit = this.shouldInitGit(cliOptions) @@ -235,17 +257,6 @@ module.exports = class Creator extends EventEmitter { }) } - // generate a .npmrc file for pnpm, to persist the `shamefully-flatten` flag - if (packageManager === 'pnpm') { - const pnpmConfig = hasPnpmVersionOrLater('4.0.0') - ? 'shamefully-hoist=true\n' - : 'shamefully-flatten=true\n' - - await writeFileTree(context, { - '.npmrc': pnpmConfig - }) - } - // commit initial state let gitCommitFailed = false let gpgSign = false diff --git a/packages/@vue/cli/lib/util/ProjectPackageManager.js b/packages/@vue/cli/lib/util/ProjectPackageManager.js index 15256a7c4b..2ab3877bf5 100644 --- a/packages/@vue/cli/lib/util/ProjectPackageManager.js +++ b/packages/@vue/cli/lib/util/ProjectPackageManager.js @@ -106,6 +106,22 @@ class PackageManager { this.bin = loadOptions().packageManager || (hasYarn() ? 'yarn' : hasPnpm3OrLater() ? 'pnpm' : 'npm') } + if (this.bin === 'npm') { + // npm doesn't support package aliases until v6.9 + const MIN_SUPPORTED_NPM_VERSION = '6.9.0' + const npmVersion = stripAnsi(execa.sync('npm', ['--version']).stdout) + + if (semver.lt(npmVersion, MIN_SUPPORTED_NPM_VERSION)) { + warn( + 'You are using an outdated version of NPM.\n' + + 'there may be unexpected errors during installation.\n' + + 'Please upgrade your NPM version.' + ) + + this.needsNpmInstallFix = true + } + } + if (!SUPPORTED_PACKAGE_MANAGERS.includes(this.bin)) { log() warn( @@ -313,6 +329,28 @@ class PackageManager { } } + if (this.needsNpmInstallFix) { + // if npm 5, split into several `npm add` calls + // see https://github.com/vuejs/vue-cli/issues/5800#issuecomment-675199729 + const pkg = resolvePkg(this.context) + if (pkg.dependencies) { + const deps = Object.entries(pkg.dependencies).map(([dep, range]) => `${dep}@${range}`) + await this.runCommand('install', deps) + } + + if (pkg.devDependencies) { + const devDeps = Object.entries(pkg.devDependencies).map(([dep, range]) => `${dep}@${range}`) + await this.runCommand('install', [...devDeps, '--save-dev']) + } + + if (pkg.optionalDependencies) { + const devDeps = Object.entries(pkg.devDependencies).map(([dep, range]) => `${dep}@${range}`) + await this.runCommand('install', [...devDeps, '--save-optional']) + } + + return + } + return await this.runCommand('install') }