mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-03-01 11:59:10 -06:00
feat!: redesigns vue upgrade, supports code migration (#4090)
This commit is contained in:
26
packages/@vue/cli-plugin-babel/migrator/index.js
Normal file
26
packages/@vue/cli-plugin-babel/migrator/index.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const { chalk } = require('@vue/cli-shared-utils')
|
||||
|
||||
module.exports = (api) => {
|
||||
// TODO: backport this part to v3
|
||||
// if (api.fromVersion('<=3.5.3')) {
|
||||
// // add core-js@2 as dependency
|
||||
// api.extendPackage({
|
||||
// dependencies: {
|
||||
// 'core-js': '^2.6.5'
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
if (api.fromVersion('^3')) {
|
||||
api.extendPackage({
|
||||
dependencies: {
|
||||
'core-js': '^3.1.2'
|
||||
}
|
||||
}, true)
|
||||
|
||||
// TODO: implement a codemod to migrate polyfills
|
||||
api.exitLog(`core-js has been upgraded from v2 to v3.
|
||||
If you have any custom polyfills defined in ${chalk.yellow('babael.config.js')}, please be aware their names may have been changed.
|
||||
For more complete changelog, see https://github.com/zloirock/core-js/blob/master/CHANGELOG.md#300---20190319`)
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ module.exports = (api, {
|
||||
tsLint,
|
||||
lintOn = []
|
||||
}, _, invoking) => {
|
||||
debugger
|
||||
if (typeof lintOn === 'string') {
|
||||
lintOn = lintOn.split(',')
|
||||
}
|
||||
|
||||
@@ -17,3 +17,4 @@
|
||||
|
||||
exports.chalk = require('chalk')
|
||||
exports.execa = require('execa')
|
||||
exports.semver = require('semver')
|
||||
|
||||
@@ -43,6 +43,10 @@ exports.resumeSpinner = () => {
|
||||
spinner.start()
|
||||
}
|
||||
|
||||
exports.failSpinner = (text) => {
|
||||
spinner.fail(text)
|
||||
}
|
||||
|
||||
// silent all logs except errors during tests and keep record
|
||||
if (process.env.VUE_CLI_TEST) {
|
||||
require('./_silence')('spinner', exports)
|
||||
|
||||
@@ -211,7 +211,7 @@ function install ({ id, type, range }, context) {
|
||||
arg = id
|
||||
}
|
||||
|
||||
await installPackage(cwd.get(), getCommand(cwd.get()), null, arg, type === 'devDependencies')
|
||||
await installPackage(cwd.get(), getCommand(cwd.get()), arg, type === 'devDependencies')
|
||||
|
||||
logs.add({
|
||||
message: `Dependency ${id} installed`,
|
||||
@@ -239,7 +239,7 @@ function uninstall ({ id }, context) {
|
||||
|
||||
const dep = findOne(id, context)
|
||||
|
||||
await uninstallPackage(cwd.get(), getCommand(cwd.get()), null, id)
|
||||
await uninstallPackage(cwd.get(), getCommand(cwd.get()), id)
|
||||
|
||||
logs.add({
|
||||
message: `Dependency ${id} uninstalled`,
|
||||
@@ -265,7 +265,7 @@ function update ({ id }, context) {
|
||||
|
||||
const dep = findOne(id, context)
|
||||
const { current, wanted } = await getVersion(dep, context)
|
||||
await updatePackage(cwd.get(), getCommand(cwd.get()), null, id)
|
||||
await updatePackage(cwd.get(), getCommand(cwd.get()), id)
|
||||
|
||||
logs.add({
|
||||
message: `Dependency ${id} updated from ${current} to ${wanted}`,
|
||||
@@ -310,7 +310,7 @@ function updateAll (context) {
|
||||
args: [updatedDeps.length]
|
||||
})
|
||||
|
||||
await updatePackage(cwd.get(), getCommand(cwd.get()), null, updatedDeps.map(
|
||||
await updatePackage(cwd.get(), getCommand(cwd.get()), updatedDeps.map(
|
||||
p => p.id
|
||||
).join(' '))
|
||||
|
||||
|
||||
@@ -334,7 +334,7 @@ function install (id, context) {
|
||||
if (process.env.VUE_CLI_DEBUG && isOfficialPlugin(id)) {
|
||||
mockInstall(id, context)
|
||||
} else {
|
||||
await installPackage(cwd.get(), getCommand(cwd.get()), null, id)
|
||||
await installPackage(cwd.get(), getCommand(cwd.get()), id)
|
||||
}
|
||||
await initPrompts(id, context)
|
||||
installationStep = 'config'
|
||||
@@ -412,7 +412,7 @@ function uninstall (id, context) {
|
||||
if (process.env.VUE_CLI_DEBUG && isOfficialPlugin(id)) {
|
||||
mockUninstall(id, context)
|
||||
} else {
|
||||
await uninstallPackage(cwd.get(), getCommand(cwd.get()), null, id)
|
||||
await uninstallPackage(cwd.get(), getCommand(cwd.get()), id)
|
||||
}
|
||||
currentPluginId = null
|
||||
installationStep = null
|
||||
@@ -520,7 +520,7 @@ function update ({ id, full }, context) {
|
||||
if (localPath) {
|
||||
await updateLocalPackage({ cwd: cwd.get(), id, localPath, full }, context)
|
||||
} else {
|
||||
await updatePackage(cwd.get(), getCommand(cwd.get()), null, id)
|
||||
await updatePackage(cwd.get(), getCommand(cwd.get()), id)
|
||||
}
|
||||
|
||||
logs.add({
|
||||
@@ -583,7 +583,7 @@ async function updateAll (context) {
|
||||
args: [updatedPlugins.length]
|
||||
})
|
||||
|
||||
await updatePackage(cwd.get(), getCommand(cwd.get()), null, updatedPlugins.map(
|
||||
await updatePackage(cwd.get(), getCommand(cwd.get()), updatedPlugins.map(
|
||||
p => p.id
|
||||
).join(' '))
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
const vueCliUpgrade = require('../index')
|
||||
|
||||
vueCliUpgrade()
|
||||
@@ -1,38 +0,0 @@
|
||||
const execa = require('execa')
|
||||
|
||||
function getMaxSatisfying (packageName, range) {
|
||||
let version = JSON.parse(
|
||||
execa.shellSync(`npm view ${packageName}@${range} version --json`).stdout
|
||||
)
|
||||
|
||||
if (typeof version !== 'string') {
|
||||
version = version[0]
|
||||
}
|
||||
|
||||
return version
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const chalk = require('chalk')
|
||||
const Table = require('cli-table')
|
||||
const inquirer = require('inquirer')
|
||||
|
||||
/* eslint-disable node/no-extraneous-require */
|
||||
const {
|
||||
hasYarn,
|
||||
logWithSpinner,
|
||||
stopSpinner
|
||||
} = require('@vue/cli-shared-utils')
|
||||
const { loadOptions } = require('@vue/cli/lib/options')
|
||||
const { installDeps } = require('@vue/cli/lib/util/installDeps')
|
||||
/* eslint-enable node/no-extraneous-require */
|
||||
|
||||
const getPackageJson = require('./get-package-json')
|
||||
const getInstalledVersion = require('./get-installed-version')
|
||||
const getUpgradableVersion = require('./get-upgradable-version')
|
||||
|
||||
const projectPath = process.cwd()
|
||||
|
||||
// - Resolve the version to upgrade to.
|
||||
// - `vue upgrade [patch|minor|major]`: defaults to minor
|
||||
// - If already latest, print message and exit
|
||||
// - Otherwise, confirm via prompt
|
||||
|
||||
function isCorePackage (packageName) {
|
||||
return (
|
||||
packageName === '@vue/cli-service' ||
|
||||
packageName.startsWith('@vue/cli-plugin-')
|
||||
)
|
||||
}
|
||||
|
||||
function shouldUseYarn () {
|
||||
// infer from lockfiles first
|
||||
if (fs.existsSync(path.resolve(projectPath, 'package-lock.json'))) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (fs.existsSync(path.resolve(projectPath, 'yarn.lock')) && hasYarn()) {
|
||||
return true
|
||||
}
|
||||
|
||||
// fallback to packageManager field in ~/.vuerc
|
||||
const { packageManager } = loadOptions()
|
||||
if (packageManager) {
|
||||
return packageManager === 'yarn'
|
||||
}
|
||||
|
||||
return hasYarn()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const table = new Table({
|
||||
head: ['package', 'installed', '', 'upgraded'],
|
||||
colAligns: ['left', 'right', 'right', 'right'],
|
||||
chars: {
|
||||
top: '',
|
||||
'top-mid': '',
|
||||
'top-left': '',
|
||||
'top-right': '',
|
||||
bottom: '',
|
||||
'bottom-mid': '',
|
||||
'bottom-left': '',
|
||||
'bottom-right': '',
|
||||
left: '',
|
||||
'left-mid': '',
|
||||
mid: '',
|
||||
'mid-mid': '',
|
||||
right: '',
|
||||
'right-mid': '',
|
||||
middle: ''
|
||||
}
|
||||
})
|
||||
|
||||
for (const [depType, depMap] of upgradableDepMaps.entries()) {
|
||||
for (const packageName of depMap.keys()) {
|
||||
const installedVersion = getInstalledVersion(packageName)
|
||||
const upgradedVersion = depMap.get(packageName)
|
||||
table.push([packageName, installedVersion, '→', upgradedVersion])
|
||||
|
||||
pkg[depType][packageName] = upgradedVersion
|
||||
}
|
||||
}
|
||||
|
||||
stopSpinner()
|
||||
|
||||
if ([...upgradableDepMaps.values()].every(depMap => depMap.size === 0)) {
|
||||
console.log('Already up-to-date.')
|
||||
return
|
||||
}
|
||||
|
||||
console.log('These packages can be upgraded:\n')
|
||||
console.log(table.toString())
|
||||
console.log(
|
||||
`\nView complete changelog at ${chalk.blue(
|
||||
'https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md'
|
||||
)}\n`
|
||||
)
|
||||
|
||||
const useYarn = shouldUseYarn()
|
||||
const { confirmed } = await inquirer.prompt([
|
||||
{
|
||||
name: 'confirmed',
|
||||
type: 'confirm',
|
||||
message: `Upgrade ${chalk.yellow('package.json')} and run ${chalk.blue(
|
||||
useYarn ? 'yarn install' : 'npm install'
|
||||
)}?`
|
||||
}
|
||||
])
|
||||
|
||||
if (!confirmed) {
|
||||
return
|
||||
}
|
||||
|
||||
fs.writeFileSync(path.resolve(projectPath, 'package.json'), JSON.stringify(pkg, null, 2))
|
||||
console.log()
|
||||
console.log(`${chalk.yellow('package.json')} saved`)
|
||||
if (useYarn) {
|
||||
await installDeps(projectPath, 'yarn')
|
||||
} else {
|
||||
await installDeps(projectPath, 'npm')
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"name": "@vue/cli-upgrade",
|
||||
"version": "4.0.0-alpha.1",
|
||||
"description": "utility to upgrade vue cli service / plugins in vue apps",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/vuejs/vue-cli.git",
|
||||
"directory": "packages/@vue/cli-upgrade"
|
||||
},
|
||||
"keywords": [
|
||||
"vue",
|
||||
"cli",
|
||||
"upgrade",
|
||||
"update"
|
||||
],
|
||||
"author": "Haoqun Jiang <haoqunjiang+npm@gmail.com>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vuejs/vue-cli/issues"
|
||||
},
|
||||
"homepage": "https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-upgrade#readme",
|
||||
"dependencies": {
|
||||
"@vue/cli-shared-utils": "^4.0.0-alpha.1",
|
||||
"chalk": "^2.4.1",
|
||||
"cli-table": "^0.3.1",
|
||||
"execa": "^1.0.0",
|
||||
"inquirer": "^6.3.1"
|
||||
}
|
||||
}
|
||||
55
packages/@vue/cli/__tests__/upgrade.spec.js
Normal file
55
packages/@vue/cli/__tests__/upgrade.spec.js
Normal file
@@ -0,0 +1,55 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const create = require('@vue/cli-test-utils/createTestProject')
|
||||
// const { logs } = require('@vue/cli-shared-utils')
|
||||
|
||||
jest.setTimeout(200000)
|
||||
|
||||
const outsideTestFolder = path.resolve(__dirname, '../../../../../vue-upgrade-tests')
|
||||
|
||||
beforeAll(() => {
|
||||
if (!fs.existsSync(outsideTestFolder)) {
|
||||
fs.mkdirSync(outsideTestFolder)
|
||||
}
|
||||
})
|
||||
|
||||
test('upgrade: plugin-babel v3.5', async () => {
|
||||
process.env.VUE_CLI_TEST_DO_INSTALL_PLUGIN = true
|
||||
const project = await create('plugin-babel-legacy', {
|
||||
plugins: {
|
||||
'@vue/cli-plugin-babel': {
|
||||
version: '3.5.3'
|
||||
}
|
||||
}
|
||||
}, outsideTestFolder)
|
||||
|
||||
const pkg = JSON.parse(await project.read('package.json'))
|
||||
expect(pkg.dependencies).not.toHaveProperty('core-js')
|
||||
|
||||
await project.run(`${require.resolve('../bin/vue')} upgrade @vue/babel`)
|
||||
|
||||
const updatedPkg = JSON.parse(await project.read('package.json'))
|
||||
expect(updatedPkg.dependencies).toHaveProperty('core-js')
|
||||
|
||||
// TODO: run upgrade in the same process so that we can access logs
|
||||
// expect(logs.log.some(([msg]) => msg.match('core-js has been upgraded'))).toBe(true)
|
||||
})
|
||||
|
||||
test('upgrade: plugin-babel with core-js 2', async () => {
|
||||
process.env.VUE_CLI_TEST_DO_INSTALL_PLUGIN = true
|
||||
const project = await create('plugin-babel-v3', {
|
||||
plugins: {
|
||||
'@vue/cli-plugin-babel': {
|
||||
version: '3.8.0'
|
||||
}
|
||||
}
|
||||
}, outsideTestFolder)
|
||||
|
||||
const pkg = JSON.parse(await project.read('package.json'))
|
||||
expect(pkg.dependencies['core-js']).toMatch('^2')
|
||||
|
||||
await project.run(`${require.resolve('../bin/vue')} upgrade @vue/babel --to next`)
|
||||
|
||||
const updatedPkg = JSON.parse(await project.read('package.json'))
|
||||
expect(updatedPkg.dependencies['core-js']).toMatch('^3')
|
||||
})
|
||||
@@ -166,10 +166,12 @@ program
|
||||
})
|
||||
|
||||
program
|
||||
.command('upgrade [semverLevel]')
|
||||
.description('upgrade vue cli service / plugins (default semverLevel: minor)')
|
||||
.action((semverLevel, cmd) => {
|
||||
loadCommand('upgrade', '@vue/cli-upgrade')(semverLevel, cleanArgs(cmd))
|
||||
.command('upgrade [package-name]')
|
||||
.description('(experimental) upgrade vue cli service / plugins')
|
||||
.option('-t, --to <version>', 'upgrade <package-name> to a version that is not latest')
|
||||
.option('-r, --registry <url>', 'Use specified npm registry when installing dependencies')
|
||||
.action((packageName, cmd) => {
|
||||
require('../lib/upgrade')(packageName, cleanArgs(cmd))
|
||||
})
|
||||
|
||||
program
|
||||
|
||||
@@ -112,7 +112,7 @@ module.exports = class Creator extends EventEmitter {
|
||||
let latestMinor = `${semver.major(latest)}.${semver.minor(latest)}.0`
|
||||
|
||||
// if using `next` branch of cli
|
||||
if (semver.gt(current, latest) && semver.prerelease(current)) {
|
||||
if (semver.gte(current, latest) && semver.prerelease(current)) {
|
||||
latestMinor = current
|
||||
}
|
||||
// generate package.json with plugin dependencies
|
||||
@@ -136,6 +136,7 @@ module.exports = class Creator extends EventEmitter {
|
||||
((/^@vue/.test(dep)) ? `^${latestMinor}` : `latest`)
|
||||
)
|
||||
})
|
||||
|
||||
// write package.json
|
||||
await writeFileTree(context, {
|
||||
'package.json': JSON.stringify(pkg, null, 2)
|
||||
@@ -155,11 +156,12 @@ module.exports = class Creator extends EventEmitter {
|
||||
log(`⚙ Installing CLI plugins. This might take a while...`)
|
||||
log()
|
||||
this.emit('creation', { event: 'plugins-install' })
|
||||
if (isTestOrDebug) {
|
||||
|
||||
if (isTestOrDebug && !process.env.VUE_CLI_TEST_DO_INSTALL_PLUGIN) {
|
||||
// in development, avoid installation process
|
||||
await require('./util/setupDevProject')(context)
|
||||
} else {
|
||||
await installDeps(context, packageManager, cliOptions.registry)
|
||||
await installDeps(context, packageManager)
|
||||
}
|
||||
|
||||
// run generator
|
||||
@@ -180,7 +182,7 @@ module.exports = class Creator extends EventEmitter {
|
||||
this.emit('creation', { event: 'deps-install' })
|
||||
log()
|
||||
if (!isTestOrDebug) {
|
||||
await installDeps(context, packageManager, cliOptions.registry)
|
||||
await installDeps(context, packageManager)
|
||||
}
|
||||
|
||||
// run complete cbs if any (injected by generators)
|
||||
|
||||
@@ -173,8 +173,9 @@ class GeneratorAPI {
|
||||
* files are written to disk.
|
||||
*
|
||||
* @param {object | () => object} fields - Fields to merge.
|
||||
* @param {boolean} forceNewVersion - Ignore version conflicts when updating dependency version
|
||||
*/
|
||||
extendPackage (fields) {
|
||||
extendPackage (fields, forceNewVersion) {
|
||||
const pkg = this.generator.pkg
|
||||
const toMerge = isFunction(fields) ? fields(pkg) : fields
|
||||
for (const key in toMerge) {
|
||||
@@ -186,7 +187,8 @@ class GeneratorAPI {
|
||||
this.id,
|
||||
existing || {},
|
||||
value,
|
||||
this.generator.depSources
|
||||
this.generator.depSources,
|
||||
forceNewVersion
|
||||
)
|
||||
} else if (!(key in pkg)) {
|
||||
pkg[key] = value
|
||||
|
||||
29
packages/@vue/cli/lib/Migrator.js
Normal file
29
packages/@vue/cli/lib/Migrator.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const Generator = require('./Generator')
|
||||
const MigratorAPI = require('./MigratorAPI')
|
||||
|
||||
const inferRootOptions = require('./util/inferRootOptions')
|
||||
|
||||
module.exports = class Migrator extends Generator {
|
||||
constructor (context, {
|
||||
plugin,
|
||||
|
||||
pkg = {},
|
||||
completeCbs = [],
|
||||
files = {},
|
||||
invoking = false
|
||||
} = {}) {
|
||||
super(context, {
|
||||
pkg,
|
||||
plugins: [],
|
||||
completeCbs,
|
||||
files,
|
||||
invoking
|
||||
})
|
||||
this.plugins = [plugin]
|
||||
|
||||
const rootOptions = inferRootOptions(pkg)
|
||||
// apply migrators from plugins
|
||||
const api = new MigratorAPI(plugin.id, plugin.installed, this, plugin.options, rootOptions)
|
||||
plugin.apply(api, plugin.options, rootOptions, invoking)
|
||||
}
|
||||
}
|
||||
23
packages/@vue/cli/lib/MigratorAPI.js
Normal file
23
packages/@vue/cli/lib/MigratorAPI.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const semver = require('semver')
|
||||
const GeneratorAPI = require('./GeneratorAPI')
|
||||
|
||||
class MigratorAPI extends GeneratorAPI {
|
||||
/**
|
||||
* @param {string} id - Id of the owner plugin
|
||||
* @param {Migrator} migrator - The invoking Migrator instance
|
||||
* @param {object} options - options passed to this plugin
|
||||
* @param {object} rootOptions - root options (the entire preset)
|
||||
*/
|
||||
constructor (id, installedVersion, migrator, options, rootOptions) {
|
||||
super(id, migrator, options, rootOptions)
|
||||
|
||||
this.installedVersion = installedVersion
|
||||
this.migrator = this.generator
|
||||
}
|
||||
|
||||
fromVersion (range) {
|
||||
return semver.satisfies(this.installedVersion, range)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MigratorAPI
|
||||
@@ -28,7 +28,7 @@ async function add (pluginName, options = {}, context = process.cwd()) {
|
||||
log()
|
||||
|
||||
const packageManager = loadOptions().packageManager || (hasProjectYarn(context) ? 'yarn' : hasProjectPnpm(context) ? 'pnpm' : 'npm')
|
||||
await installPackage(context, packageManager, options.registry, packageName)
|
||||
await installPackage(context, packageManager, packageName)
|
||||
|
||||
log(`${chalk.green('✔')} Successfully installed plugin: ${chalk.cyan(packageName)}`)
|
||||
log()
|
||||
|
||||
@@ -2,13 +2,7 @@ const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const execa = require('execa')
|
||||
const chalk = require('chalk')
|
||||
const globby = require('globby')
|
||||
const inquirer = require('inquirer')
|
||||
const { isBinaryFileSync } = require('isbinaryfile')
|
||||
const Generator = require('./Generator')
|
||||
const { loadOptions } = require('./options')
|
||||
const { installDeps } = require('./util/installDeps')
|
||||
const normalizeFilePaths = require('./util/normalizeFilePaths')
|
||||
const {
|
||||
log,
|
||||
error,
|
||||
@@ -21,23 +15,10 @@ const {
|
||||
loadModule
|
||||
} = require('@vue/cli-shared-utils')
|
||||
|
||||
async function readFiles (context) {
|
||||
const files = await globby(['**'], {
|
||||
cwd: context,
|
||||
onlyFiles: true,
|
||||
gitignore: true,
|
||||
ignore: ['**/node_modules/**', '**/.git/**'],
|
||||
dot: true
|
||||
})
|
||||
const res = {}
|
||||
for (const file of files) {
|
||||
const name = path.resolve(context, file)
|
||||
res[file] = isBinaryFileSync(name)
|
||||
? fs.readFileSync(name)
|
||||
: fs.readFileSync(name, 'utf-8')
|
||||
}
|
||||
return normalizeFilePaths(res)
|
||||
}
|
||||
const Generator = require('./Generator')
|
||||
const { loadOptions } = require('./options')
|
||||
const { installDeps } = require('./util/installDeps')
|
||||
const readFiles = require('./util/readFiles')
|
||||
|
||||
function getPkg (context) {
|
||||
const pkgPath = path.resolve(context, 'package.json')
|
||||
@@ -146,7 +127,7 @@ async function runGenerator (context, plugin, pkg = getPkg(context)) {
|
||||
log()
|
||||
const packageManager =
|
||||
loadOptions().packageManager || (hasProjectYarn(context) ? 'yarn' : hasProjectPnpm(context) ? 'pnpm' : 'npm')
|
||||
await installDeps(context, packageManager, plugin.options && plugin.options.registry)
|
||||
await installDeps(context, packageManager)
|
||||
}
|
||||
|
||||
if (createCompleteCbs.length) {
|
||||
|
||||
271
packages/@vue/cli/lib/upgrade.js
Normal file
271
packages/@vue/cli/lib/upgrade.js
Normal file
@@ -0,0 +1,271 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const chalk = require('chalk')
|
||||
const execa = require('execa')
|
||||
const {
|
||||
log,
|
||||
error,
|
||||
done,
|
||||
|
||||
logWithSpinner,
|
||||
stopSpinner,
|
||||
|
||||
isPlugin,
|
||||
resolvePluginId,
|
||||
loadModule,
|
||||
|
||||
hasProjectGit
|
||||
} = require('@vue/cli-shared-utils')
|
||||
|
||||
const Migrator = require('./Migrator')
|
||||
|
||||
const { getCommand, getVersion } = require('./util/packageManager')
|
||||
const { installDeps, updatePackage } = require('./util/installDeps')
|
||||
const { linkPackage } = require('./util/linkBin')
|
||||
|
||||
const getPackageJson = require('./util/getPackageJson')
|
||||
const getInstalledVersion = require('./util/getInstalledVersion')
|
||||
const tryGetNewerRange = require('./util/tryGetNewerRange')
|
||||
const readFiles = require('./util/readFiles')
|
||||
|
||||
const isTestOrDebug = process.env.VUE_CLI_TEST || process.env.VUE_CLI_DEBUG
|
||||
|
||||
async function runMigrator (packageName, options, context) {
|
||||
const pluginMigrator = loadModule(`${packageName}/migrator`, context)
|
||||
if (!pluginMigrator) { return }
|
||||
|
||||
const plugin = {
|
||||
id: packageName,
|
||||
apply: pluginMigrator,
|
||||
installed: options.installed
|
||||
}
|
||||
|
||||
const pkg = getPackageJson(context)
|
||||
const createCompleteCbs = []
|
||||
const migrator = new Migrator(context, {
|
||||
plugin: plugin,
|
||||
|
||||
pkg,
|
||||
files: await readFiles(context),
|
||||
completeCbs: createCompleteCbs,
|
||||
invoking: true
|
||||
})
|
||||
|
||||
log(`🚀 Running migrator of ${packageName}`)
|
||||
await migrator.generate({
|
||||
extractConfigFiles: true,
|
||||
checkExisting: true
|
||||
})
|
||||
|
||||
const newDeps = migrator.pkg.dependencies
|
||||
const newDevDeps = migrator.pkg.devDependencies
|
||||
const depsChanged =
|
||||
JSON.stringify(newDeps) !== JSON.stringify(pkg.dependencies) ||
|
||||
JSON.stringify(newDevDeps) !== JSON.stringify(pkg.devDependencies)
|
||||
|
||||
if (!isTestOrDebug && depsChanged) {
|
||||
log(`📦 Installing additional dependencies...`)
|
||||
log()
|
||||
const packageManager = getCommand(context)
|
||||
await installDeps(context, packageManager)
|
||||
}
|
||||
|
||||
if (createCompleteCbs.length) {
|
||||
logWithSpinner('⚓', `Running completion hooks...`)
|
||||
for (const cb of createCompleteCbs) {
|
||||
await cb()
|
||||
}
|
||||
stopSpinner()
|
||||
log()
|
||||
}
|
||||
|
||||
log(`${chalk.green('✔')} Successfully invoked migrator for plugin: ${chalk.cyan(plugin.id)}`)
|
||||
if (!process.env.VUE_CLI_TEST && hasProjectGit(context)) {
|
||||
const { stdout } = await execa('git', [
|
||||
'ls-files',
|
||||
'--exclude-standard',
|
||||
'--modified',
|
||||
'--others'
|
||||
], {
|
||||
cwd: context
|
||||
})
|
||||
if (stdout.trim()) {
|
||||
log(` The following files have been updated / added:\n`)
|
||||
log(
|
||||
chalk.red(
|
||||
stdout
|
||||
.split(/\r?\n/g)
|
||||
.map(line => ` ${line}`)
|
||||
.join('\n')
|
||||
)
|
||||
)
|
||||
log()
|
||||
log(
|
||||
` You should review these changes with ${chalk.cyan(
|
||||
`git diff`
|
||||
)} and commit them.`
|
||||
)
|
||||
log()
|
||||
}
|
||||
}
|
||||
|
||||
migrator.printExitLogs()
|
||||
}
|
||||
|
||||
async function upgradeSinglePackage (pluginId, options, context) {
|
||||
const packageName = resolvePluginId(pluginId)
|
||||
const pkg = getPackageJson(context)
|
||||
|
||||
let depEntry, required
|
||||
for (const depType of ['dependencies', 'devDependencies', 'optionalDependencies']) {
|
||||
if (pkg[depType] && pkg[depType][packageName]) {
|
||||
depEntry = depType
|
||||
required = pkg[depType][packageName]
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!required) {
|
||||
throw new Error(`Can't find ${chalk.yellow(packageName)} in ${chalk.yellow('package.json')}`)
|
||||
}
|
||||
const installed = getInstalledVersion(packageName)
|
||||
|
||||
let targetVersion = options.to || 'latest'
|
||||
|
||||
// if the targetVersion is not an exact version
|
||||
if (!/\d+\.\d+\.\d+/.test(targetVersion)) {
|
||||
if (targetVersion === 'latest') {
|
||||
logWithSpinner(`Getting latest version of ${packageName}`)
|
||||
} else {
|
||||
logWithSpinner(`Getting max satisfying version of ${packageName}@${options.to}`)
|
||||
}
|
||||
|
||||
targetVersion = await getVersion(packageName, targetVersion, context)
|
||||
stopSpinner()
|
||||
}
|
||||
|
||||
if (targetVersion === installed) {
|
||||
log(`Already installed ${packageName}@${targetVersion}`)
|
||||
|
||||
const newRange = tryGetNewerRange(`^${targetVersion}`, required)
|
||||
if (newRange !== required) {
|
||||
pkg[depEntry][packageName] = newRange
|
||||
fs.writeFileSync(path.resolve(context, 'package.json'), JSON.stringify(pkg, null, 2))
|
||||
log(`${chalk.green('✔')} Updated version range in ${chalk.yellow('package.json')}`)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
log(`Upgrading ${packageName} from ${installed} to ${targetVersion}`)
|
||||
|
||||
if (isTestOrDebug) {
|
||||
// link packages in current repo for test
|
||||
await linkPackage(path.resolve(__dirname, `../../../${packageName}`), path.join(context, 'node_modules', packageName))
|
||||
} else {
|
||||
await updatePackage(context, getCommand(context), `${packageName}@^${targetVersion}`)
|
||||
}
|
||||
|
||||
await runMigrator(packageName, { installed }, context)
|
||||
}
|
||||
|
||||
async function getUpgradable (context) {
|
||||
// get current deps
|
||||
// filter @vue/cli-service, @vue/cli-plugin-* & vue-cli-plugin-*
|
||||
const pkg = getPackageJson(context)
|
||||
const upgradable = []
|
||||
|
||||
for (const depType of ['dependencies', 'devDependencies', 'optionalDependencies']) {
|
||||
for (const [name, range] of Object.entries(pkg[depType] || {})) {
|
||||
if (name !== '@vue/cli-service' && !isPlugin(name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
const installed = await getInstalledVersion(name)
|
||||
const wanted = await getVersion(name, range, context)
|
||||
const latest = await getVersion(name, 'latest', context)
|
||||
|
||||
if (installed !== latest) {
|
||||
upgradable.push({ name, installed, wanted, latest })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return upgradable
|
||||
}
|
||||
|
||||
async function checkForUpdates (context) {
|
||||
logWithSpinner('Gathering pacakage information...')
|
||||
const upgradable = await getUpgradable(context)
|
||||
stopSpinner()
|
||||
|
||||
if (!upgradable.length) {
|
||||
done('Seems all plugins are up to date. Good work!')
|
||||
return
|
||||
}
|
||||
|
||||
// format the output
|
||||
// adapted from @angular/cli
|
||||
const names = upgradable.map(dep => dep.name)
|
||||
let namePad = Math.max(...names.map(x => x.length)) + 2
|
||||
if (!Number.isFinite(namePad)) {
|
||||
namePad = 30
|
||||
}
|
||||
const pads = [namePad, 12, 12, 12, 0]
|
||||
console.log(
|
||||
' ' +
|
||||
['Name', 'Installed', 'Wanted', 'Latest', 'Command to upgrade'].map(
|
||||
(x, i) => chalk.underline(x.padEnd(pads[i]))
|
||||
).join('')
|
||||
)
|
||||
for (const p of upgradable) {
|
||||
const fields = [p.name, p.installed, p.wanted, p.latest, `vue upgrade ${p.name}`]
|
||||
console.log(' ' + fields.map((x, i) => x.padEnd(pads[i])).join(''))
|
||||
}
|
||||
|
||||
console.log(`Run ${chalk.yellow('vue upgrade --all')} to upgrade all the above plugins`)
|
||||
|
||||
return upgradable
|
||||
}
|
||||
|
||||
async function upgradeAll (context) {
|
||||
// TODO: should confirm for major version upgrades
|
||||
// for patch & minor versions, upgrade directly
|
||||
// for major versions, prompt before upgrading
|
||||
const upgradable = await getUpgradable(context)
|
||||
|
||||
if (!upgradable.length) {
|
||||
done('Seems all plugins are up to date. Good work!')
|
||||
return
|
||||
}
|
||||
|
||||
for (const p of upgradable) {
|
||||
await upgradeSinglePackage(p.name, { to: p.latest }, context)
|
||||
}
|
||||
|
||||
done('All plugins are up to date!')
|
||||
}
|
||||
|
||||
async function upgrade (packageName, options, context = process.cwd()) {
|
||||
if (!packageName) {
|
||||
if (options.to) {
|
||||
error(`Must specify a package name to upgrade to ${options.to}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (options.all) {
|
||||
return upgradeAll(context)
|
||||
}
|
||||
|
||||
return checkForUpdates(context)
|
||||
}
|
||||
|
||||
return upgradeSinglePackage(packageName, options, context)
|
||||
}
|
||||
|
||||
module.exports = (...args) => {
|
||||
return upgrade(...args).catch(err => {
|
||||
error(err)
|
||||
if (!process.env.VUE_CLI_TEST) {
|
||||
process.exit(1)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
const path = require('path')
|
||||
const getPackageJson = require('./get-package-json')
|
||||
const getPackageJson = require('./getPackageJson')
|
||||
|
||||
module.exports = function getInstalledVersion (packageName) {
|
||||
// for first level deps, read package.json directly is way faster than `npm list`
|
||||
@@ -1,9 +1,10 @@
|
||||
const { request } = require('@vue/cli-shared-utils')
|
||||
const { getRegistry } = require('./packageManager')
|
||||
|
||||
module.exports = async function getPackageVersion (id, range = '') {
|
||||
const registry = (await require('./shouldUseTaobao')())
|
||||
? `https://registry.npm.taobao.org`
|
||||
: `https://registry.npmjs.org`
|
||||
module.exports = async function getPackageVersion (id, range = '', registry) {
|
||||
if (!registry) {
|
||||
registry = await getRegistry()
|
||||
}
|
||||
|
||||
let result
|
||||
try {
|
||||
|
||||
@@ -3,7 +3,7 @@ const chalk = require('chalk')
|
||||
const execa = require('execa')
|
||||
const readline = require('readline')
|
||||
const registries = require('./registries')
|
||||
const shouldUseTaobao = require('./shouldUseTaobao')
|
||||
const { getRegistry } = require('./packageManager')
|
||||
|
||||
const debug = require('debug')('vue-cli:install')
|
||||
|
||||
@@ -91,14 +91,8 @@ function renderProgressBar (curr, total) {
|
||||
process.stderr.write(`[${complete}${incomplete}]${bar}`)
|
||||
}
|
||||
|
||||
async function addRegistryToArgs (command, args, cliRegistry) {
|
||||
const altRegistry = (
|
||||
cliRegistry || (
|
||||
(await shouldUseTaobao(command))
|
||||
? registries.taobao
|
||||
: null
|
||||
)
|
||||
)
|
||||
async function addRegistryToArgs (command, args) {
|
||||
const altRegistry = await getRegistry({ packageManager: command })
|
||||
|
||||
if (altRegistry) {
|
||||
args.push(`--registry=${altRegistry}`)
|
||||
@@ -194,12 +188,12 @@ function executeCommand (command, args, targetDir) {
|
||||
})
|
||||
}
|
||||
|
||||
exports.installDeps = async function installDeps (targetDir, command, cliRegistry) {
|
||||
exports.installDeps = async function installDeps (targetDir, command) {
|
||||
checkPackageManagerIsSupported(command)
|
||||
|
||||
const args = packageManagerConfig[command].installDeps
|
||||
|
||||
await addRegistryToArgs(command, args, cliRegistry)
|
||||
await addRegistryToArgs(command, args)
|
||||
|
||||
debug(`command: `, command)
|
||||
debug(`args: `, args)
|
||||
@@ -207,14 +201,14 @@ exports.installDeps = async function installDeps (targetDir, command, cliRegistr
|
||||
await executeCommand(command, args, targetDir)
|
||||
}
|
||||
|
||||
exports.installPackage = async function (targetDir, command, cliRegistry, packageName, dev = true) {
|
||||
exports.installPackage = async function (targetDir, command, packageName, dev = true) {
|
||||
checkPackageManagerIsSupported(command)
|
||||
|
||||
const args = packageManagerConfig[command].installPackage
|
||||
|
||||
if (dev) args.push('-D')
|
||||
|
||||
await addRegistryToArgs(command, args, cliRegistry)
|
||||
await addRegistryToArgs(command, args)
|
||||
|
||||
args.push(packageName)
|
||||
|
||||
@@ -224,12 +218,12 @@ exports.installPackage = async function (targetDir, command, cliRegistry, packag
|
||||
await executeCommand(command, args, targetDir)
|
||||
}
|
||||
|
||||
exports.uninstallPackage = async function (targetDir, command, cliRegistry, packageName) {
|
||||
exports.uninstallPackage = async function (targetDir, command, packageName) {
|
||||
checkPackageManagerIsSupported(command)
|
||||
|
||||
const args = packageManagerConfig[command].uninstallPackage
|
||||
|
||||
await addRegistryToArgs(command, args, cliRegistry)
|
||||
await addRegistryToArgs(command, args)
|
||||
|
||||
args.push(packageName)
|
||||
|
||||
@@ -239,12 +233,12 @@ exports.uninstallPackage = async function (targetDir, command, cliRegistry, pack
|
||||
await executeCommand(command, args, targetDir)
|
||||
}
|
||||
|
||||
exports.updatePackage = async function (targetDir, command, cliRegistry, packageName) {
|
||||
exports.updatePackage = async function (targetDir, command, packageName) {
|
||||
checkPackageManagerIsSupported(command)
|
||||
|
||||
const args = packageManagerConfig[command].updatePackage
|
||||
|
||||
await addRegistryToArgs(command, args, cliRegistry)
|
||||
await addRegistryToArgs(command, args)
|
||||
|
||||
packageName.split(' ').forEach(name => args.push(name))
|
||||
|
||||
|
||||
@@ -19,3 +19,12 @@ exports.linkBin = async (src, dest) => {
|
||||
await fs.chmod(dest, '755')
|
||||
}
|
||||
}
|
||||
|
||||
exports.linkPackage = async (src, dest) => {
|
||||
if (!process.env.VUE_CLI_TEST && !process.env.VUE_CLI_DEBUG) {
|
||||
throw new Error(`linkPackage should only be used during tests or debugging.`)
|
||||
}
|
||||
|
||||
await fs.remove(dest)
|
||||
await fs.symlink(src, dest, 'dir')
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
const semver = require('semver')
|
||||
const { warn } = require('@vue/cli-shared-utils')
|
||||
|
||||
module.exports = function resolveDeps (generatorId, to, from, sources) {
|
||||
const tryGetNewerRange = require('./tryGetNewerRange')
|
||||
|
||||
const extractSemver = r => r.replace(/^.+#semver:/, '')
|
||||
const injectSemver = (r, v) => semver.validRange(r) ? v : r.replace(/#semver:.+$/, `#semver:${v}`)
|
||||
|
||||
module.exports = function resolveDeps (generatorId, to, from, sources, forceNewVersion) {
|
||||
const res = Object.assign({}, to)
|
||||
for (const name in from) {
|
||||
const r1 = to[name]
|
||||
@@ -37,7 +42,14 @@ module.exports = function resolveDeps (generatorId, to, from, sources) {
|
||||
sources[name] = generatorId
|
||||
}
|
||||
// warn incompatible version requirements
|
||||
if (!semver.validRange(r1semver) || !semver.validRange(r2semver) || !semver.intersects(r1semver, r2semver)) {
|
||||
if (
|
||||
!forceNewVersion &&
|
||||
(
|
||||
!semver.validRange(r1semver) ||
|
||||
!semver.validRange(r2semver) ||
|
||||
!semver.intersects(r1semver, r2semver)
|
||||
)
|
||||
) {
|
||||
warn(
|
||||
`conflicting versions for project dependency "${name}":\n\n` +
|
||||
`- ${r1} injected by generator "${sourceGeneratorId}"\n` +
|
||||
@@ -49,16 +61,3 @@ module.exports = function resolveDeps (generatorId, to, from, sources) {
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
const leadRE = /^(~|\^|>=?)/
|
||||
const rangeToVersion = r => r.replace(leadRE, '').replace(/x/g, '0')
|
||||
const extractSemver = r => r.replace(/^.+#semver:/, '')
|
||||
const injectSemver = (r, v) => semver.validRange(r) ? v : r.replace(/#semver:.+$/, `#semver:${v}`)
|
||||
|
||||
function tryGetNewerRange (r1, r2) {
|
||||
const v1 = rangeToVersion(r1)
|
||||
const v2 = rangeToVersion(r2)
|
||||
if (semver.valid(v1) && semver.valid(v2)) {
|
||||
return semver.gt(v1, v2) ? r1 : r2
|
||||
}
|
||||
}
|
||||
|
||||
102
packages/@vue/cli/lib/util/packageManager.js
Normal file
102
packages/@vue/cli/lib/util/packageManager.js
Normal file
@@ -0,0 +1,102 @@
|
||||
const execa = require('execa')
|
||||
const minimist = require('minimist')
|
||||
const semver = require('semver')
|
||||
const LRU = require('lru-cache')
|
||||
|
||||
const {
|
||||
hasYarn,
|
||||
hasProjectYarn,
|
||||
hasPnpm3OrLater,
|
||||
hasProjectPnpm
|
||||
} = require('@vue/cli-shared-utils')
|
||||
|
||||
const { loadOptions } = require('../options')
|
||||
const registries = require('./registries')
|
||||
const shouldUseTaobao = require('./shouldUseTaobao')
|
||||
|
||||
function getCommand (cwd) {
|
||||
if (!cwd) {
|
||||
return loadOptions().packageManager || (hasYarn() ? 'yarn' : hasPnpm3OrLater() ? 'pnpm' : 'npm')
|
||||
}
|
||||
return hasProjectYarn(cwd) ? 'yarn' : hasProjectPnpm(cwd) ? 'pnpm' : 'npm'
|
||||
}
|
||||
|
||||
// Any command that implemented registry-related feature should support
|
||||
// `-r` / `--registry` option
|
||||
async function getRegistry ({ cwd, packageManager } = {}) {
|
||||
const args = minimist(process.argv, {
|
||||
alias: {
|
||||
r: 'registry'
|
||||
}
|
||||
})
|
||||
|
||||
if (args.registry) {
|
||||
return args.registry
|
||||
}
|
||||
|
||||
if (await shouldUseTaobao()) {
|
||||
return registries.taobao
|
||||
}
|
||||
|
||||
if (!packageManager) {
|
||||
packageManager = getCommand(cwd)
|
||||
}
|
||||
const { stdout } = await execa(packageManager, ['config', 'get', 'registry'])
|
||||
return stdout
|
||||
}
|
||||
|
||||
const metadataCache = new LRU({
|
||||
max: 200,
|
||||
maxAge: 1000 * 60 * 30 // 30 min.
|
||||
})
|
||||
|
||||
async function getMetadata (packageName, { field = '', packageManager, cwd } = {}) {
|
||||
if (!packageManager) {
|
||||
packageManager = getCommand(cwd)
|
||||
}
|
||||
const registry = await getRegistry({ cwd, packageManager })
|
||||
|
||||
const metadataKey = `${packageManager}-${registry}-${packageName}`
|
||||
let metadata = metadataCache.get(metadataKey)
|
||||
|
||||
if (metadata) {
|
||||
return metadata
|
||||
}
|
||||
|
||||
const { stdout } = await execa(
|
||||
packageManager,
|
||||
[
|
||||
'info',
|
||||
packageName,
|
||||
field,
|
||||
'--json',
|
||||
'--registry',
|
||||
registry
|
||||
]
|
||||
)
|
||||
|
||||
metadata = JSON.parse(stdout)
|
||||
if (packageManager === 'yarn') {
|
||||
// `yarn info` outputs messages in the form of `{"type": "inspect", data: {}}`
|
||||
metadata = metadata.data
|
||||
}
|
||||
|
||||
metadataCache.set(metadataKey, metadata)
|
||||
return metadata
|
||||
}
|
||||
|
||||
async function getVersion (packageName, versionRange, cwd) {
|
||||
const metadata = await getMetadata(packageName, { cwd })
|
||||
if (Object.keys(metadata['dist-tags']).includes(versionRange)) {
|
||||
return metadata['dist-tags'][versionRange]
|
||||
}
|
||||
const versions = Array.isArray(metadata.versions) ? metadata.versions : Object.keys(metadata.versions)
|
||||
return semver.maxSatisfying(versions, versionRange)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getCommand,
|
||||
getRegistry,
|
||||
getMetadata,
|
||||
getVersion
|
||||
}
|
||||
24
packages/@vue/cli/lib/util/readFiles.js
Normal file
24
packages/@vue/cli/lib/util/readFiles.js
Normal file
@@ -0,0 +1,24 @@
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
|
||||
const globby = require('globby')
|
||||
const { isBinaryFileSync } = require('isbinaryfile')
|
||||
const normalizeFilePaths = require('./normalizeFilePaths')
|
||||
|
||||
module.exports = async function readFiles (context) {
|
||||
const files = await globby(['**'], {
|
||||
cwd: context,
|
||||
onlyFiles: true,
|
||||
gitignore: true,
|
||||
ignore: ['**/node_modules/**', '**/.git/**'],
|
||||
dot: true
|
||||
})
|
||||
const res = {}
|
||||
for (const file of files) {
|
||||
const name = path.resolve(context, file)
|
||||
res[file] = isBinaryFileSync(name)
|
||||
? fs.readFileSync(name)
|
||||
: fs.readFileSync(name, 'utf-8')
|
||||
}
|
||||
return normalizeFilePaths(res)
|
||||
}
|
||||
12
packages/@vue/cli/lib/util/tryGetNewerRange.js
Normal file
12
packages/@vue/cli/lib/util/tryGetNewerRange.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const semver = require('semver')
|
||||
|
||||
const leadRE = /^(~|\^|>=?)/
|
||||
const rangeToVersion = r => r.replace(leadRE, '').replace(/x/g, '0')
|
||||
|
||||
module.exports = function tryGetNewerRange (r1, r2) {
|
||||
const v1 = rangeToVersion(r1)
|
||||
const v2 = rangeToVersion(r2)
|
||||
if (semver.valid(v1) && semver.valid(v2)) {
|
||||
return semver.gt(v1, v2) ? r1 : r2
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,7 @@
|
||||
"js-yaml": "^3.13.1",
|
||||
"jscodeshift": "^0.6.4",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"lru-cache": "^5.1.1",
|
||||
"minimist": "^1.2.0",
|
||||
"recast": "^0.18.1",
|
||||
"request": "^2.87.0",
|
||||
|
||||
Reference in New Issue
Block a user