Skip to content

Commit

Permalink
fix: run migrator in a separator process, fix require cache issues du…
Browse files Browse the repository at this point in the history
…ring upgrade (#5360)

* fix: run migrator in a separator process, fix require cache issues during upgrade

* fix: fix cwd

* test: fix test mocks

* fix: early return
  • Loading branch information
haoqunjiang authored Apr 7, 2020
1 parent 4659869 commit 9855c52
Showing 1 changed file with 31 additions and 21 deletions.
52 changes: 31 additions & 21 deletions packages/@vue/cli/lib/Upgrader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const fs = require('fs')
const path = require('path')
const {
chalk,
execa,
semver,

log,
Expand All @@ -12,19 +13,17 @@ const {
isPlugin,
resolvePluginId,

loadModule
loadModule,
resolveModule
} = require('@vue/cli-shared-utils')

const tryGetNewerRange = require('./util/tryGetNewerRange')
const getPkg = require('./util/getPkg')
const PackageManager = require('./util/ProjectPackageManager')

const { runMigrator } = require('./migrate')

function clearRequireCache () {
Object.keys(require.cache).forEach(key => delete require.cache[key])
}

module.exports = class Upgrader {
constructor (context = process.cwd()) {
this.context = context
Expand Down Expand Up @@ -108,28 +107,39 @@ module.exports = class Upgrader {

log(`Upgrading ${packageName} from ${installed} to ${targetVersion}`)
await this.pm.upgrade(`${packageName}@~${targetVersion}`)
// as the dependencies have now changed, the require cache must be invalidated
// otherwise it may affect the behavior of the migrator
clearRequireCache()

// The cached `pkg` field won't automatically update after running `this.pm.upgrade`.
// Also, `npm install pkg@~version` won't replace the original `"pkg": "^version"` field.
// So we have to manually update `this.pkg` and write to the file system in `runMigrator`
this.pkg[depEntry][packageName] = `~${targetVersion}`
const noop = () => {}

const pluginMigrator =
loadModule(`${packageName}/migrator`, this.context) || noop

await runMigrator(
this.context,
{
id: packageName,
apply: pluginMigrator,
baseVersion: installed
},
this.pkg
)

const resolvedPluginMigrator =
resolveModule(`${packageName}/migrator`, this.context)

if (resolvedPluginMigrator) {
// for unit tests, need to run migrator in the same process for mocks to work
// TODO: fix the tests and remove this special case
if (process.env.VUE_CLI_TEST) {
clearRequireCache()
await require('./migrate').runMigrator(
this.context,
{
id: packageName,
apply: loadModule(`${packageName}/migrator`, this.context),
baseVersion: installed
},
this.pkg
)
return
}

const cliBin = path.resolve(__dirname, '../bin/vue.js')
// Run migrator in a separate process to avoid all kinds of require cache issues
await execa('node', [cliBin, 'migrate', packageName, '--from', installed], {
cwd: this.context,
stdio: 'inherit'
})
}
}

async getUpgradable (includeNext) {
Expand Down

0 comments on commit 9855c52

Please sign in to comment.