upgrade 命令
源码目录: packages/@vue/cli-upgrade 。
作用: 升级 @vue/cli-service 和 vue-cli 插件。
vue upgrade
命令的入口在 packages/@vue/cli/bin/vue.js
中:
program
.command('upgrade [semverLevel]')
.description('upgrade vue cli service / plugins (default semverLevel: minor)')
.action((semverLevel, cmd) => {
loadCommand('upgrade', '@vue/cli-upgrade')(semverLevel, cleanArgs(cmd))
})
代码比较少,需要注意的就是 semverLevel
,它用于指定安装 @vue/cli-service || @vue/cli-plugin-*
的版本号形式,可选择值有三个,默认值为 minor:
- patch: 升级到最新补丁版号
- minor: 升级到最新次版本号
- major: 升级到最新主版本号
先看下 @vue/cli-upgrade/index.js
代码,即 upgrade
命令执行的函数:
module.exports = async function vueCliUpgrade (semverLevel = 'minor'){
// get current deps
// filter @vue/cli-service & @vue/cli-plugin-*
const pkg = getPackageJson(projectPath)
const upgradableDepMaps = new Map([
['dependencies', new Map()],
['devDependencies', new Map()],
['optionalDependencies', new Map()]
])
logWithSpinner('Gathering update information...')
for (const depType of upgradableDepMaps.keys()) {
for (const [packageName, currRange] of Object.entries(pkg[depType] || {})) {
if (!isCorePackage(packageName)) {
continue
}
const upgradable = getUpgradableVersion(
packageName,
currRange,
semverLevel
)
if (upgradable !== currRange) {
upgradableDepMaps.get(depType).set(packageName, upgradable)
}
}
}
// some code ...
}
首先获取了项目的 package.json
,然后获取其中的 dependencies,devDependencies,optionalDependencies。获取了这些依赖后利用 isCorePackage
过滤掉不是 @vue/cli-service
和 @vue/cli-plugin-*
的依赖,再分别获取过滤后的依赖需要更新到的版本号,获取版本号使用了 getUpgradableVersion
方法:
module.exports = function getUpgradableVersion (
packageName,
currRange,
semverLevel
) {
let newRange
if (semverLevel === 'patch') { // 安装最近的小版本依赖包, 补丁号
const currMaxVersion = getMaxSatisfying(packageName, currRange)
newRange = `~${currMaxVersion}`
const newMaxVersion = getMaxSatisfying(packageName, newRange)
newRange = `~${newMaxVersion}`
} else if (semverLevel === 'minor') { // 安装最近大版本依赖包,次版本号
const currMaxVersion = getMaxSatisfying(packageName, currRange)
newRange = `^${currMaxVersion}`
const newMaxVersion = getMaxSatisfying(packageName, newRange)
newRange = `^${newMaxVersion}`
} else if (semverLevel === 'major') { // 主版本号
newRange = `^${getMaxSatisfying(packageName, 'latest')}`
} else {
throw new Error('Release type must be one of patch | minor | major!')
}
return newRange
}
通过 getMaxSatisfying
方法执行 npm view
命令获取依赖的版本号,然后根据 semverLevel 确定版本号的形式并返回。如果返回的版本号与当前 package.json
里面依赖的不一致,则将需要升级的信息存在 table 中,以便后续利用 cli-table
输出到控制台上,除此之外还将该依赖名称和需要升级的版本号存在 Map 结构中。
在此之后会遍历 upgradableDepMaps
,判断依赖是否有更新信息,如果有则输出信息并询问是否需要安装依赖,否则直接退出。