@@ -9,6 +9,14 @@ const buildModes = {
99 'wc-async' : 'web component (async)'
1010}
1111
12+ const modifyConfig = ( config , fn ) => {
13+ if ( Array . isArray ( config ) ) {
14+ config . forEach ( c => fn ( c ) )
15+ } else {
16+ fn ( config )
17+ }
18+ }
19+
1220module . exports = ( api , options ) => {
1321 api . registerCommand ( 'build' , {
1422 description : 'build for production' ,
@@ -19,6 +27,8 @@ module.exports = (api, options) => {
1927 '--target' : `app | lib | wc | wc-async (default: ${ defaults . target } )` ,
2028 '--name' : `name for lib or web-component mode (default: "name" in package.json or entry filename)` ,
2129 '--no-clean' : `do not remove the dist directory before building the project` ,
30+ '--report' : `generate report.html to help analyze bundle content` ,
31+ '--report-json' : 'generate report.json to help analyze bundle content' ,
2232 '--watch' : `watch for changes`
2333 }
2434 } , async ( args ) => {
@@ -43,8 +53,8 @@ module.exports = (api, options) => {
4353 modern : true ,
4454 clean : false
4555 } ) , api , options )
46- } else {
4756 delete process . env . VUE_CLI_MODERN_BUILD
57+ } else {
4858 return build ( args , api , options )
4959 }
5060 } )
@@ -83,6 +93,7 @@ async function build (args, api, options) {
8393 }
8494
8595 const targetDir = api . resolve ( args . dest || options . outputDir )
96+ const isLegacyBuild = args . target === 'app' && options . modernMode && ! args . modern
8697
8798 // resolve raw webpack config
8899 process . env . VUE_CLI_BUILD_TARGET = args . target
@@ -101,14 +112,9 @@ async function build (args, api, options) {
101112 // apply inline dest path after user configureWebpack hooks
102113 // so it takes higher priority
103114 if ( args . dest ) {
104- const applyDest = config => {
115+ modifyConfig ( webpackConfig , config => {
105116 config . output . path = targetDir
106- }
107- if ( Array . isArray ( webpackConfig ) ) {
108- webpackConfig . forEach ( applyDest )
109- } else {
110- applyDest ( webpackConfig )
111- }
117+ } )
112118 }
113119
114120 // grab the actual output path and check for common mis-configuration
@@ -118,40 +124,59 @@ async function build (args, api, options) {
118124 : webpackConfig
119125 ) . output . path
120126
121- if ( args . watch ) {
122- webpackConfig . watch = true
123- }
124-
125127 if ( ! args . dest && actualTargetDir !== api . resolve ( options . outputDir ) ) {
126128 // user directly modifies output.path in configureWebpack or chainWebpack.
127129 // this is not supported because there's no way for us to give copy
128130 // plugin the correct value this way.
129- console . error ( chalk . red (
131+ throw new Error (
130132 `\n\nConfiguration Error: ` +
131133 `Avoid modifying webpack output.path directly. ` +
132134 `Use the "outputDir" option instead.\n`
133- ) )
134- process . exit ( 1 )
135+ )
135136 }
136137
137138 if ( actualTargetDir === api . service . context ) {
138- console . error ( chalk . red (
139+ throw new Error (
139140 `\n\nConfiguration Error: ` +
140141 `Do not set output directory to project root.\n`
141- ) )
142- process . exit ( 1 )
142+ )
143143 }
144144
145- if ( args . clean ) {
146- await fs . remove ( targetDir )
145+ if ( args . watch ) {
146+ modifyConfig ( webpackConfig , config => {
147+ config . watch = true
148+ } )
147149 }
148150
149151 // Expose advanced stats
150152 if ( args . dashboard ) {
151153 const DashboardPlugin = require ( '../../webpack/DashboardPlugin' )
152- ; ( webpackConfig . plugins = webpackConfig . plugins || [ ] ) . push ( new DashboardPlugin ( {
153- type : 'build'
154- } ) )
154+ modifyConfig ( webpackConfig , config => {
155+ config . plugins . push ( new DashboardPlugin ( {
156+ type : 'build'
157+ } ) )
158+ } )
159+ }
160+
161+ if ( args . report || args [ 'report-json' ] ) {
162+ const { BundleAnalyzerPlugin } = require ( 'webpack-bundle-analyzer' )
163+ modifyConfig ( webpackConfig , config => {
164+ const bundleName = args . target !== 'app'
165+ ? config . output . filename . replace ( / \. j s $ / , '-' )
166+ : isLegacyBuild ? 'legacy-' : ''
167+ config . plugins . push ( new BundleAnalyzerPlugin ( {
168+ logLevel : 'warn' ,
169+ openAnalyzer : false ,
170+ analyzerMode : args . report ? 'static' : 'disabled' ,
171+ reportFilename : `${ bundleName } report.html` ,
172+ statsFilename : `${ bundleName } report.json` ,
173+ generateStatsFile : ! ! args [ 'report-json' ]
174+ } ) )
175+ } )
176+ }
177+
178+ if ( args . clean ) {
179+ await fs . remove ( targetDir )
155180 }
156181
157182 return new Promise ( ( resolve , reject ) => {
@@ -171,7 +196,7 @@ async function build (args, api, options) {
171196 targetDir
172197 )
173198 log ( formatStats ( stats , targetDirShort , api ) )
174- if ( args . target === 'app' && ! ( options . modernMode && ! args . modern ) ) {
199+ if ( args . target === 'app' && ! isLegacyBuild ) {
175200 if ( ! args . watch ) {
176201 done ( `Build complete. The ${ chalk . cyan ( targetDirShort ) } directory is ready to be deployed.\n` )
177202 } else {
0 commit comments