@@ -85,9 +85,23 @@ function stripVersion (packageName) {
8585 return result [ 1 ]
8686}
8787
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+
88101class PackageManager {
89102 constructor ( { context, forcePackageManager } = { } ) {
90103 this . context = context || process . cwd ( )
104+ this . _registries = { }
91105
92106 if ( forcePackageManager ) {
93107 this . bin = forcePackageManager
@@ -146,9 +160,10 @@ class PackageManager {
146160
147161 // Any command that implemented registry-related feature should support
148162 // `-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 ]
152167 }
153168
154169 const args = minimist ( process . argv , {
@@ -157,24 +172,30 @@ class PackageManager {
157172 }
158173 } )
159174
175+ let registry
160176 if ( args . registry ) {
161- this . _registry = args . registry
177+ registry = args . registry
162178 } else if ( ! process . env . VUE_CLI_TEST && await shouldUseTaobao ( this . bin ) ) {
163- this . _registry = registries . taobao
179+ registry = registries . taobao
164180 } else {
165181 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+ }
167188 } catch ( e ) {
168189 // 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
170191 }
171192 }
172193
173- this . _registry = stripAnsi ( this . _registry ) . trim ( )
174- return this . _registry
194+ this . _registries [ cacheKey ] = stripAnsi ( registry ) . trim ( )
195+ return this . _registries [ cacheKey ]
175196 }
176197
177- async getAuthToken ( ) {
198+ async getAuthToken ( scope ) {
178199 // get npmrc (https://docs.npmjs.com/configuring-npm/npmrc.html#files)
179200 const possibleRcPaths = [
180201 path . resolve ( this . context , '.npmrc' ) ,
@@ -197,7 +218,7 @@ class PackageManager {
197218 }
198219 }
199220
200- const registry = await this . getRegistry ( )
221+ const registry = await this . getRegistry ( scope )
201222 const registryWithoutProtocol = registry
202223 . replace ( / h t t p s ? : / , '' ) // remove leading protocol
203224 . replace ( / ( [ ^ / ] ) $ / , '$1/' ) // ensure ending with slash
@@ -255,8 +276,9 @@ class PackageManager {
255276
256277 // https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md
257278 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 )
260282
261283 const metadataKey = `${ this . bin } -${ registry } -${ packageName } `
262284 let metadata = metadataCache . get ( metadataKey )
0 commit comments