Skip to content

Commit

Permalink
fix: respect scope when resolving package metadata (#5892)
Browse files Browse the repository at this point in the history
This should fix the remaining issue reported in #5411.
In particular, if the user configured a dedicated npm registry for a
specific scope, this setting was previously disregarded by vue-cli.
Thus it was impossible to use vue upgrade if the packages were not also
published to the official npm registry.
  • Loading branch information
bodograumann committed Sep 23, 2020
1 parent 6cac3af commit 5b70fc2
Showing 1 changed file with 35 additions and 13 deletions.
48 changes: 35 additions & 13 deletions packages/@vue/cli/lib/util/ProjectPackageManager.js
Expand Up @@ -85,9 +85,23 @@ function stripVersion (packageName) {
return result[1]
}

// extract the package scope from the full package name
// the result includes the initial @ character
function extractPackageScope (packageName) {
const scopedNameRegExp = /^(@[^\/]+)\/.*$/
const result = packageName.match(scopedNameRegExp)

if (!result) {
return undefined
}

return result[1]
}

class PackageManager {
constructor ({ context, forcePackageManager } = {}) {
this.context = context || process.cwd()
this._registries = {}

if (forcePackageManager) {
this.bin = forcePackageManager
Expand Down Expand Up @@ -146,9 +160,10 @@ class PackageManager {

// Any command that implemented registry-related feature should support
// `-r` / `--registry` option
async getRegistry () {
if (this._registry) {
return this._registry
async getRegistry (scope) {
const cacheKey = scope || ''
if (this._registries[cacheKey]) {
return this._registries[cacheKey]
}

const args = minimist(process.argv, {
Expand All @@ -157,24 +172,30 @@ class PackageManager {
}
})

let registry
if (args.registry) {
this._registry = args.registry
registry = args.registry
} else if (!process.env.VUE_CLI_TEST && await shouldUseTaobao(this.bin)) {
this._registry = registries.taobao
registry = registries.taobao
} else {
try {
this._registry = (await execa(this.bin, ['config', 'get', 'registry'])).stdout
if (scope) {
registry = (await execa(this.bin, ['config', 'get', scope + ':registry'])).stdout
}
if (!registry || registry === 'undefined') {
registry = (await execa(this.bin, ['config', 'get', 'registry'])).stdout
}
} catch (e) {
// Yarn 2 uses `npmRegistryServer` instead of `registry`
this._registry = (await execa(this.bin, ['config', 'get', 'npmRegistryServer'])).stdout
registry = (await execa(this.bin, ['config', 'get', 'npmRegistryServer'])).stdout
}
}

this._registry = stripAnsi(this._registry).trim()
return this._registry
this._registries[cacheKey] = stripAnsi(registry).trim()
return this._registries[cacheKey]
}

async getAuthToken () {
async getAuthToken (scope) {
// get npmrc (https://docs.npmjs.com/configuring-npm/npmrc.html#files)
const possibleRcPaths = [
path.resolve(this.context, '.npmrc'),
Expand All @@ -197,7 +218,7 @@ class PackageManager {
}
}

const registry = await this.getRegistry()
const registry = await this.getRegistry(scope)
const registryWithoutProtocol = registry
.replace(/https?:/, '') // remove leading protocol
.replace(/([^/])$/, '$1/') // ensure ending with slash
Expand Down Expand Up @@ -255,8 +276,9 @@ class PackageManager {

// https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md
async getMetadata (packageName, { full = false } = {}) {
const registry = await this.getRegistry()
const authToken = await this.getAuthToken()
const scope = extractPackageScope(packageName)
const registry = await this.getRegistry(scope)
const authToken = await this.getAuthToken(scope)

const metadataKey = `${this.bin}-${registry}-${packageName}`
let metadata = metadataCache.get(metadataKey)
Expand Down

0 comments on commit 5b70fc2

Please sign in to comment.