@@ -85,9 +85,23 @@ function stripVersion (packageName) {
85
85
return result [ 1 ]
86
86
}
87
87
88
+ // extract the package scope from the full package name
89
+ // the result includes the initial @ character
90
+ function extractPackageScope ( packageName ) {
91
+ const scopedNameRegExp = / ^ ( @ [ ^ \/ ] + ) \/ .* $ /
92
+ const result = packageName . match ( scopedNameRegExp )
93
+
94
+ if ( ! result ) {
95
+ return undefined
96
+ }
97
+
98
+ return result [ 1 ]
99
+ }
100
+
88
101
class PackageManager {
89
102
constructor ( { context, forcePackageManager } = { } ) {
90
103
this . context = context || process . cwd ( )
104
+ this . _registries = { }
91
105
92
106
if ( forcePackageManager ) {
93
107
this . bin = forcePackageManager
@@ -146,9 +160,10 @@ class PackageManager {
146
160
147
161
// Any command that implemented registry-related feature should support
148
162
// `-r` / `--registry` option
149
- async getRegistry ( ) {
150
- if ( this . _registry ) {
151
- return this . _registry
163
+ async getRegistry ( scope ) {
164
+ const cacheKey = scope || ''
165
+ if ( this . _registries [ cacheKey ] ) {
166
+ return this . _registries [ cacheKey ]
152
167
}
153
168
154
169
const args = minimist ( process . argv , {
@@ -157,24 +172,30 @@ class PackageManager {
157
172
}
158
173
} )
159
174
175
+ let registry
160
176
if ( args . registry ) {
161
- this . _registry = args . registry
177
+ registry = args . registry
162
178
} else if ( ! process . env . VUE_CLI_TEST && await shouldUseTaobao ( this . bin ) ) {
163
- this . _registry = registries . taobao
179
+ registry = registries . taobao
164
180
} else {
165
181
try {
166
- this . _registry = ( await execa ( this . bin , [ 'config' , 'get' , 'registry' ] ) ) . stdout
182
+ if ( scope ) {
183
+ registry = ( await execa ( this . bin , [ 'config' , 'get' , scope + ':registry' ] ) ) . stdout
184
+ }
185
+ if ( ! registry || registry === 'undefined' ) {
186
+ registry = ( await execa ( this . bin , [ 'config' , 'get' , 'registry' ] ) ) . stdout
187
+ }
167
188
} catch ( e ) {
168
189
// Yarn 2 uses `npmRegistryServer` instead of `registry`
169
- this . _registry = ( await execa ( this . bin , [ 'config' , 'get' , 'npmRegistryServer' ] ) ) . stdout
190
+ registry = ( await execa ( this . bin , [ 'config' , 'get' , 'npmRegistryServer' ] ) ) . stdout
170
191
}
171
192
}
172
193
173
- this . _registry = stripAnsi ( this . _registry ) . trim ( )
174
- return this . _registry
194
+ this . _registries [ cacheKey ] = stripAnsi ( registry ) . trim ( )
195
+ return this . _registries [ cacheKey ]
175
196
}
176
197
177
- async getAuthToken ( ) {
198
+ async getAuthToken ( scope ) {
178
199
// get npmrc (https://docs.npmjs.com/configuring-npm/npmrc.html#files)
179
200
const possibleRcPaths = [
180
201
path . resolve ( this . context , '.npmrc' ) ,
@@ -197,7 +218,7 @@ class PackageManager {
197
218
}
198
219
}
199
220
200
- const registry = await this . getRegistry ( )
221
+ const registry = await this . getRegistry ( scope )
201
222
const registryWithoutProtocol = registry
202
223
. replace ( / h t t p s ? : / , '' ) // remove leading protocol
203
224
. replace ( / ( [ ^ / ] ) $ / , '$1/' ) // ensure ending with slash
@@ -255,8 +276,9 @@ class PackageManager {
255
276
256
277
// https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md
257
278
async getMetadata ( packageName , { full = false } = { } ) {
258
- const registry = await this . getRegistry ( )
259
- const authToken = await this . getAuthToken ( )
279
+ const scope = extractPackageScope ( packageName )
280
+ const registry = await this . getRegistry ( scope )
281
+ const authToken = await this . getAuthToken ( scope )
260
282
261
283
const metadataKey = `${ this . bin } -${ registry } -${ packageName } `
262
284
let metadata = metadataCache . get ( metadataKey )
0 commit comments