Skip to content

Commit ad0da2d

Browse files
authored
fix: fix pnpm compatibility issues during scaffolding (#3790)
as a follow up of #1531 1. separate project pnpm check and global pnpm check 2. rename `hasPnpm` to `hasPnpm3OrLater` 3. add `--shamefully-flatten` flag for `pnpm install` 4. generate `.npmrc` when using pnpm as package manager, to persist the install flag
2 parents cc66247 + 92c69e1 commit ad0da2d

File tree

9 files changed

+60
-22
lines changed

9 files changed

+60
-22
lines changed

packages/@vue/cli-service/lib/commands/serve.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const {
22
info,
33
hasProjectYarn,
4-
hasPnpm,
4+
hasProjectPnpm,
55
openBrowser,
66
IpcMessenger
77
} = require('@vue/cli-shared-utils')
@@ -235,7 +235,7 @@ module.exports = (api, options) => {
235235
isFirstCompile = false
236236

237237
if (!isProduction) {
238-
const buildCommand = hasProjectYarn(api.getCwd()) ? `yarn build` : hasPnpm() ? `pnpm run build` : `npm run build`
238+
const buildCommand = hasProjectYarn(api.getCwd()) ? `yarn build` : hasProjectPnpm(api.getCwd()) ? `pnpm run build` : `npm run build`
239239
console.log(` Note that the development build is not optimized.`)
240240
console.log(` To create a production build, run ${chalk.cyan(buildCommand)}.`)
241241
} else {

packages/@vue/cli-shared-utils/lib/env.js

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const _gitProjects = new LRU({
1414
max: 10,
1515
maxAge: 1000
1616
})
17-
let _hasPnpm
1817

1918
// env detection
2019
exports.hasYarn = () => {
@@ -79,25 +78,51 @@ exports.hasProjectGit = (cwd) => {
7978
return result
8079
}
8180

82-
exports.hasPnpm = () => {
81+
let _hasPnpm
82+
let _hasPnpm3orLater
83+
const _pnpmProjects = new LRU({
84+
max: 10,
85+
maxAge: 1000
86+
})
87+
88+
exports.hasPnpm3OrLater = () => {
8389
if (process.env.VUE_CLI_TEST) {
8490
return true
8591
}
86-
if (_hasPnpm != null) {
87-
return _hasPnpm
92+
if (_hasPnpm3orLater != null) {
93+
return _hasPnpm3orLater
8894
}
8995
try {
9096
const pnpmVersion = execSync('pnpm --version').toString()
9197
// there's a critical bug in pnpm 2
9298
// https://github.com/pnpm/pnpm/issues/1678#issuecomment-469981972
9399
// so we only support pnpm >= 3.0.0
94-
_hasPnpm = semver.gte(pnpmVersion, '3.0.0')
95-
return _hasPnpm
100+
_hasPnpm = true
101+
_hasPnpm3orLater = semver.gte(pnpmVersion, '3.0.0')
102+
return _hasPnpm3orLater
96103
} catch (e) {
97-
return (_hasPnpm = false)
104+
return (_hasPnpm3orLater = false)
98105
}
99106
}
100107

108+
exports.hasProjectPnpm = (cwd) => {
109+
if (_pnpmProjects.has(cwd)) {
110+
return checkPnpm(_pnpmProjects.get(cwd))
111+
}
112+
113+
const lockFile = path.join(cwd, 'pnpm-lock.yaml')
114+
const result = fs.existsSync(lockFile)
115+
_pnpmProjects.set(cwd, result)
116+
return checkPnpm(result)
117+
}
118+
119+
function checkPnpm (result) {
120+
if (result && !exports.hasPnpm3OrLater()) {
121+
throw new Error(`The project seems to require pnpm${_hasPnpm ? ' >= 3' : ''} but it's not installed.`)
122+
}
123+
return result
124+
}
125+
101126
// OS
102127
exports.isWindows = process.platform === 'win32'
103128
exports.isMacintosh = process.platform === 'darwin'
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
const {
22
hasYarn,
33
hasProjectYarn,
4-
hasPnpm
4+
hasPnpm3OrLater,
5+
hasProjectPnpm
56
} = require('@vue/cli-shared-utils')
67
const { loadOptions } = require('@vue/cli/lib/options')
78

89
exports.getCommand = function (cwd = undefined) {
910
if (!cwd) {
10-
return loadOptions().packageManager || (hasYarn() ? 'yarn' : hasPnpm() ? 'pnpm' : 'npm')
11+
return loadOptions().packageManager || (hasYarn() ? 'yarn' : hasPnpm3OrLater() ? 'pnpm' : 'npm')
1112
}
12-
return hasProjectYarn(cwd) ? 'yarn' : hasPnpm() ? 'pnpm' : 'npm'
13+
return hasProjectYarn(cwd) ? 'yarn' : hasProjectPnpm() ? 'pnpm' : 'npm'
1314
}

packages/@vue/cli-ui/src/components/file-diff/FileDiffView.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ import GIT_COMMIT from '@/graphql/git/gitCommit.gql'
133133
134134
const defaultCollapsed = [
135135
'yarn.lock',
136+
'pnpm-lock.yaml',
136137
'package-lock.json'
137138
]
138139

packages/@vue/cli/lib/Creator.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const {
3333
hasGit,
3434
hasProjectGit,
3535
hasYarn,
36-
hasPnpm,
36+
hasPnpm3OrLater,
3737
logWithSpinner,
3838
stopSpinner,
3939
exit,
@@ -99,7 +99,7 @@ module.exports = class Creator extends EventEmitter {
9999
cliOptions.packageManager ||
100100
loadOptions().packageManager ||
101101
(hasYarn() ? 'yarn' : null) ||
102-
(hasPnpm() ? 'pnpm' : 'npm')
102+
(hasPnpm3OrLater() ? 'pnpm' : 'npm')
103103
)
104104

105105
await clearConsole()
@@ -192,6 +192,13 @@ module.exports = class Creator extends EventEmitter {
192192
'README.md': generateReadme(generator.pkg, packageManager)
193193
})
194194

195+
// generate a .npmrc file for pnpm, to persist the `shamefully-flatten` flag
196+
if (packageManager === 'pnpm') {
197+
await writeFileTree(context, {
198+
'.npmrc': 'shamefully-flatten=true\n'
199+
})
200+
}
201+
195202
// commit initial state
196203
let gitCommitFailed = false
197204
if (shouldInitGit) {
@@ -412,7 +419,7 @@ module.exports = class Creator extends EventEmitter {
412419

413420
// ask for packageManager once
414421
const savedOptions = loadOptions()
415-
if (!savedOptions.packageManager && (hasYarn() || hasPnpm())) {
422+
if (!savedOptions.packageManager && (hasYarn() || hasPnpm3OrLater())) {
416423
const packageManagerChoices = []
417424

418425
if (hasYarn()) {
@@ -423,7 +430,7 @@ module.exports = class Creator extends EventEmitter {
423430
})
424431
}
425432

426-
if (hasPnpm()) {
433+
if (hasPnpm3OrLater()) {
427434
packageManagerChoices.push({
428435
name: 'Use PNPM',
429436
value: 'pnpm',

packages/@vue/cli/lib/add.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const {
66
log,
77
error,
88
hasProjectYarn,
9-
hasPnpm,
9+
hasProjectPnpm,
1010
resolvePluginId,
1111
resolveModule,
1212
loadModule
@@ -27,7 +27,7 @@ async function add (pluginName, options = {}, context = process.cwd()) {
2727
log(`📦 Installing ${chalk.cyan(packageName)}...`)
2828
log()
2929

30-
const packageManager = loadOptions().packageManager || (hasProjectYarn(context) ? 'yarn' : hasPnpm() ? 'pnpm' : 'npm')
30+
const packageManager = loadOptions().packageManager || (hasProjectYarn(context) ? 'yarn' : hasProjectPnpm() ? 'pnpm' : 'npm')
3131
await installPackage(context, packageManager, options.registry, packageName)
3232

3333
log(`${chalk.green('✔')} Successfully installed plugin: ${chalk.cyan(packageName)}`)

packages/@vue/cli/lib/invoke.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const {
1414
error,
1515
hasProjectYarn,
1616
hasProjectGit,
17-
hasPnpm,
17+
hasProjectPnpm,
1818
logWithSpinner,
1919
stopSpinner,
2020
resolvePluginId,
@@ -145,7 +145,7 @@ async function runGenerator (context, plugin, pkg = getPkg(context)) {
145145
log(`📦 Installing additional dependencies...`)
146146
log()
147147
const packageManager =
148-
loadOptions().packageManager || (hasProjectYarn(context) ? 'yarn' : hasPnpm() ? 'pnpm' : 'npm')
148+
loadOptions().packageManager || (hasProjectYarn(context) ? 'yarn' : hasProjectPnpm() ? 'pnpm' : 'npm')
149149
await installDeps(context, packageManager, plugin.options && plugin.options.registry)
150150
}
151151

packages/@vue/cli/lib/util/installDeps.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ exports.installDeps = async function installDeps (targetDir, command, cliRegistr
182182
// do nothing
183183
}
184184

185+
if (command === 'pnpm') {
186+
args.push('--shamefully-flatten')
187+
}
188+
185189
await addRegistryToArgs(command, args, cliRegistry)
186190

187191
debug(`command: `, command)

packages/@vue/cli/lib/util/loadCommand.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ module.exports = function loadCommand (commandName, moduleName) {
1111
} catch (err2) {
1212
if (isNotFoundError(err2)) {
1313
const chalk = require('chalk')
14-
const { hasYarn, hasPnpm } = require('@vue/cli-shared-utils')
14+
const { hasYarn, hasPnpm3OrLater } = require('@vue/cli-shared-utils')
1515
let installCommand = `npm install -g`
1616
if (hasYarn()) {
1717
installCommand = `yarn global add`
18-
} else if (hasPnpm()) {
18+
} else if (hasPnpm3OrLater()) {
1919
installCommand = `pnpm install -g`
2020
}
2121
console.log()

0 commit comments

Comments
 (0)