Skip to content

Commit 272ef5e

Browse files
committed
feat: vue-cli-service build --report/--report-json
1 parent 2b55576 commit 272ef5e

File tree

4 files changed

+97
-27
lines changed

4 files changed

+97
-27
lines changed

packages/@vue/cli-service/lib/commands/build/index.js

+49-24
Original file line numberDiff line numberDiff line change
@@ -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+
1220
module.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(/\.js$/, '-')
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 {

packages/@vue/cli-service/lib/webpack/DashboardPlugin.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const webpack = require('webpack')
99
const { IpcMessenger } = require('@vue/cli-shared-utils')
1010
const { analyzeBundle } = require('./analyzeBundle')
1111

12-
const ID = 'DashboardPlugin'
12+
const ID = 'vue-cli-dashboard-plugin'
1313
const ONE_SECOND = 1000
1414
const FILENAME_QUERY_REGEXP = /\?.*$/
1515

packages/@vue/cli-service/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"vue-loader": "^15.2.0",
6666
"vue-template-compiler": "^2.5.16",
6767
"webpack": "^4.8.2",
68+
"webpack-bundle-analyzer": "^2.13.1",
6869
"webpack-chain": "^4.8.0",
6970
"webpack-dev-server": "^3.1.4",
7071
"webpack-merge": "^4.1.2",

yarn.lock

+46-2
Original file line numberDiff line numberDiff line change
@@ -2071,6 +2071,14 @@ bcrypt-pbkdf@^1.0.0:
20712071
dependencies:
20722072
tweetnacl "^0.14.3"
20732073

2074+
bfj-node4@^5.2.0:
2075+
version "5.3.1"
2076+
resolved "https://registry.yarnpkg.com/bfj-node4/-/bfj-node4-5.3.1.tgz#e23d8b27057f1d0214fc561142ad9db998f26830"
2077+
dependencies:
2078+
bluebird "^3.5.1"
2079+
check-types "^7.3.0"
2080+
tryer "^1.0.0"
2081+
20742082
big.js@^3.1.3:
20752083
version "3.2.0"
20762084
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
@@ -2561,6 +2569,10 @@ [email protected]:
25612569
version "2.24.0"
25622570
resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600"
25632571

2572+
check-types@^7.3.0:
2573+
version "7.4.0"
2574+
resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4"
2575+
25642576
chokidar@^1.6.0, chokidar@^1.7.0:
25652577
version "1.7.0"
25662578
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
@@ -2859,7 +2871,7 @@ [email protected]:
28592871
version "2.11.0"
28602872
resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"
28612873

2862-
[email protected], [email protected], commander@^2.11.0, commander@^2.12.1, commander@^2.12.2, commander@^2.15.1, commander@^2.6.0, commander@^2.9.0, commander@~2.15.0:
2874+
[email protected], [email protected], commander@^2.11.0, commander@^2.12.1, commander@^2.12.2, commander@^2.13.0, commander@^2.15.1, commander@^2.6.0, commander@^2.9.0, commander@~2.15.0:
28632875
version "2.15.1"
28642876
resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
28652877

@@ -4880,6 +4892,10 @@ fileset@^2.0.2:
48804892
glob "^7.0.3"
48814893
minimatch "^3.0.3"
48824894

4895+
filesize@^3.5.11:
4896+
version "3.6.1"
4897+
resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317"
4898+
48834899
fill-range@^2.1.0:
48844900
version "2.2.4"
48854901
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565"
@@ -5578,6 +5594,13 @@ growly@^1.3.0:
55785594
version "1.3.0"
55795595
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
55805596

5597+
gzip-size@^4.1.0:
5598+
version "4.1.0"
5599+
resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-4.1.0.tgz#8ae096257eabe7d69c45be2b67c448124ffb517c"
5600+
dependencies:
5601+
duplexer "^0.1.1"
5602+
pify "^3.0.0"
5603+
55815604
handle-thing@^1.2.5:
55825605
version "1.2.5"
55835606
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4"
@@ -8926,7 +8949,7 @@ [email protected]:
89268949
version "0.0.2"
89278950
resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4"
89288951

8929-
opener@~1.4.0:
8952+
opener@^1.4.3, opener@~1.4.0:
89308953
version "1.4.3"
89318954
resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8"
89328955

@@ -11516,6 +11539,10 @@ trim-right@^1.0.1:
1151611539
version "1.0.1"
1151711540
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
1151811541

11542+
tryer@^1.0.0:
11543+
version "1.0.0"
11544+
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.0.tgz#027b69fa823225e551cace3ef03b11f6ab37c1d7"
11545+
1151911546
ts-jest@^22.4.6:
1152011547
version "22.4.6"
1152111548
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-22.4.6.tgz#a5d7f5e8b809626d1f4143209d301287472ec344"
@@ -12294,6 +12321,23 @@ webidl-conversions@^4.0.2:
1229412321
version "4.0.2"
1229512322
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
1229612323

12324+
webpack-bundle-analyzer@^2.13.1:
12325+
version "2.13.1"
12326+
resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.13.1.tgz#07d2176c6e86c3cdce4c23e56fae2a7b6b4ad526"
12327+
dependencies:
12328+
acorn "^5.3.0"
12329+
bfj-node4 "^5.2.0"
12330+
chalk "^2.3.0"
12331+
commander "^2.13.0"
12332+
ejs "^2.5.7"
12333+
express "^4.16.2"
12334+
filesize "^3.5.11"
12335+
gzip-size "^4.1.0"
12336+
lodash "^4.17.4"
12337+
mkdirp "^0.5.1"
12338+
opener "^1.4.3"
12339+
ws "^4.0.0"
12340+
1229712341
webpack-chain@^4.6.0, webpack-chain@^4.8.0:
1229812342
version "4.8.0"
1229912343
resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-4.8.0.tgz#06fc3dbb9f2707d4c9e899fc6250fbcf2afe6fd1"

0 commit comments

Comments
 (0)