@@ -9,6 +9,14 @@ const buildModes = {
9
9
'wc-async' : 'web component (async)'
10
10
}
11
11
12
+ const modifyConfig = ( config , fn ) => {
13
+ if ( Array . isArray ( config ) ) {
14
+ config . forEach ( c => fn ( c ) )
15
+ } else {
16
+ fn ( config )
17
+ }
18
+ }
19
+
12
20
module . exports = ( api , options ) => {
13
21
api . registerCommand ( 'build' , {
14
22
description : 'build for production' ,
@@ -19,6 +27,8 @@ module.exports = (api, options) => {
19
27
'--target' : `app | lib | wc | wc-async (default: ${ defaults . target } )` ,
20
28
'--name' : `name for lib or web-component mode (default: "name" in package.json or entry filename)` ,
21
29
'--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' ,
22
32
'--watch' : `watch for changes`
23
33
}
24
34
} , async ( args ) => {
@@ -43,8 +53,8 @@ module.exports = (api, options) => {
43
53
modern : true ,
44
54
clean : false
45
55
} ) , api , options )
46
- } else {
47
56
delete process . env . VUE_CLI_MODERN_BUILD
57
+ } else {
48
58
return build ( args , api , options )
49
59
}
50
60
} )
@@ -83,6 +93,7 @@ async function build (args, api, options) {
83
93
}
84
94
85
95
const targetDir = api . resolve ( args . dest || options . outputDir )
96
+ const isLegacyBuild = args . target === 'app' && options . modernMode && ! args . modern
86
97
87
98
// resolve raw webpack config
88
99
process . env . VUE_CLI_BUILD_TARGET = args . target
@@ -101,14 +112,9 @@ async function build (args, api, options) {
101
112
// apply inline dest path after user configureWebpack hooks
102
113
// so it takes higher priority
103
114
if ( args . dest ) {
104
- const applyDest = config => {
115
+ modifyConfig ( webpackConfig , config => {
105
116
config . output . path = targetDir
106
- }
107
- if ( Array . isArray ( webpackConfig ) ) {
108
- webpackConfig . forEach ( applyDest )
109
- } else {
110
- applyDest ( webpackConfig )
111
- }
117
+ } )
112
118
}
113
119
114
120
// grab the actual output path and check for common mis-configuration
@@ -118,40 +124,59 @@ async function build (args, api, options) {
118
124
: webpackConfig
119
125
) . output . path
120
126
121
- if ( args . watch ) {
122
- webpackConfig . watch = true
123
- }
124
-
125
127
if ( ! args . dest && actualTargetDir !== api . resolve ( options . outputDir ) ) {
126
128
// user directly modifies output.path in configureWebpack or chainWebpack.
127
129
// this is not supported because there's no way for us to give copy
128
130
// plugin the correct value this way.
129
- console . error ( chalk . red (
131
+ throw new Error (
130
132
`\n\nConfiguration Error: ` +
131
133
`Avoid modifying webpack output.path directly. ` +
132
134
`Use the "outputDir" option instead.\n`
133
- ) )
134
- process . exit ( 1 )
135
+ )
135
136
}
136
137
137
138
if ( actualTargetDir === api . service . context ) {
138
- console . error ( chalk . red (
139
+ throw new Error (
139
140
`\n\nConfiguration Error: ` +
140
141
`Do not set output directory to project root.\n`
141
- ) )
142
- process . exit ( 1 )
142
+ )
143
143
}
144
144
145
- if ( args . clean ) {
146
- await fs . remove ( targetDir )
145
+ if ( args . watch ) {
146
+ modifyConfig ( webpackConfig , config => {
147
+ config . watch = true
148
+ } )
147
149
}
148
150
149
151
// Expose advanced stats
150
152
if ( args . dashboard ) {
151
153
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 )
155
180
}
156
181
157
182
return new Promise ( ( resolve , reject ) => {
@@ -171,7 +196,7 @@ async function build (args, api, options) {
171
196
targetDir
172
197
)
173
198
log ( formatStats ( stats , targetDirShort , api ) )
174
- if ( args . target === 'app' && ! ( options . modernMode && ! args . modern ) ) {
199
+ if ( args . target === 'app' && ! isLegacyBuild ) {
175
200
if ( ! args . watch ) {
176
201
done ( `Build complete. The ${ chalk . cyan ( targetDirShort ) } directory is ready to be deployed.\n` )
177
202
} else {
0 commit comments