@@ -2,6 +2,7 @@ const { URL } = require('url')
22const https = require ( 'https' )
33const chalk = require ( 'chalk' )
44const execa = require ( 'execa' )
5+ const readline = require ( 'readline' )
56const inquirer = require ( 'inquirer' )
67const { loadOptions, saveOptions } = require ( '../options' )
78const { pauseSpinner, resumeSpinner } = require ( '@vue/cli-shared-utils' )
@@ -74,6 +75,26 @@ const shouldUseTaobao = async (command) => {
7475 return save ( useTaobaoRegistry )
7576}
7677
78+ const toStartOfLine = stream => {
79+ if ( ! chalk . supportsColor ) {
80+ stream . write ( '\r' )
81+ return
82+ }
83+ readline . cursorTo ( stream , 0 )
84+ }
85+
86+ const renderProgressBar = ( curr , total ) => {
87+ const ratio = Math . min ( Math . max ( curr / total , 0 ) , 1 )
88+ const bar = ` ${ curr } /${ total } `
89+ const availableSpace = Math . max ( 0 , process . stderr . columns - bar . length - 3 )
90+ const width = Math . min ( total , availableSpace )
91+ const completeLength = Math . round ( width * ratio )
92+ const complete = `#` . repeat ( completeLength )
93+ const incomplete = `-` . repeat ( width - completeLength )
94+ toStartOfLine ( process . stderr )
95+ process . stderr . write ( `[${ complete } ${ incomplete } ]${ bar } ` )
96+ }
97+
7798module . exports = async function installDeps ( targetDir , command , cliRegistry ) {
7899 const args = [ ]
79100 if ( command === 'npm' ) {
@@ -105,9 +126,28 @@ module.exports = async function installDeps (targetDir, command, cliRegistry) {
105126 await new Promise ( ( resolve , reject ) => {
106127 const child = execa ( command , args , {
107128 cwd : targetDir ,
108- stdio : 'inherit'
129+ stdio : [ 'inherit' , 'inherit' , command === 'yarn' ? 'pipe' : 'inherit' ]
109130 } )
110131
132+ // filter out unwanted yarn output
133+ if ( command === 'yarn' ) {
134+ child . stderr . on ( 'data' , buf => {
135+ const str = buf . toString ( )
136+ if ( / w a r n i n g / . test ( str ) ) {
137+ return
138+ }
139+ // progress bar
140+ const progressBarMatch = str . match ( / \[ .* \] ( \d + ) \/ ( \d + ) / )
141+ if ( progressBarMatch ) {
142+ // since yarn is in a child process, it's unable to get the width of
143+ // the terminal. reimplement the progress bar ourselves!
144+ renderProgressBar ( progressBarMatch [ 1 ] , progressBarMatch [ 2 ] )
145+ return
146+ }
147+ process . stderr . write ( buf )
148+ } )
149+ }
150+
111151 child . on ( 'close' , code => {
112152 if ( code !== 0 ) {
113153 reject ( `command failed: ${ command } ${ args . join ( ' ' ) } ` )
0 commit comments