Skip to content

Commit 61510e7

Browse files
committed
feat(build/serve): improve CLI output, closes #105
1 parent dc9940b commit 61510e7

File tree

5 files changed

+62
-67
lines changed

5 files changed

+62
-67
lines changed

__tests__/build.helper.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,11 @@ const runTests = useTS =>
1414
const projectPath = p =>
1515
path.join(process.cwd(), '__tests__/projects/' + projectName, p)
1616

17-
const { stdout } = await project.run(
17+
await project.run(
1818
`vue-cli-service electron:build --x64 ${
1919
isWin ? '--win zip' : ''
2020
} --linux zip`
2121
)
22-
// Ensure built completes
23-
expect(stdout.indexOf('Build complete!')).not.toBe(-1)
2422
// Ensure /dist is not modified
2523
expect(project.has('dist')).toBe(false)
2624
// Ensure build successfully outputted files

__tests__/commands.spec.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const mockYargsCommand = jest.fn(() => ({ parse: mockYargsParse }))
1616
jest.mock('yargs', () => ({ command: mockYargsCommand }))
1717
jest.mock('@vue/cli-service/lib/commands/build')
1818
jest.mock('fs-extra')
19+
jest.mock('@vue/cli-service/lib/commands/build/formatStats')
1920
jest.mock('../lib/removeJunk.js', () => jest.fn(() => 'removeJunk'))
2021
jest.mock('electron-builder')
2122
const mockInstallAppDeps = jest.fn()
@@ -72,7 +73,8 @@ const runCommand = async (command, options = {}, args = {}, rawArgs = []) => {
7273
chainWebpack: jest.fn(),
7374
service: {
7475
// Mock api.service.run('build/serve')
75-
run: serviceRun
76+
run: serviceRun,
77+
context: process.cwd()
7678
}
7779
}
7880
// Run the plugin, saving it's registered commands

__tests__/serve.helper.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ portfinder.basePort = 9515
99
const serve = (project, notifyUpdate) =>
1010
new Promise((resolve, reject) => {
1111
// --debug to prevent Electron from being launched
12-
const child = project.run('vue-cli-service electron:serve --debug')
12+
const child = project.run('vue-cli-service electron:serve --headless')
1313
let log = ''
1414
child.stdout.on('data', async data => {
1515
data = data.toString()
@@ -18,7 +18,7 @@ const serve = (project, notifyUpdate) =>
1818
if (
1919
data.match(
2020
// Dev server is finished and index.js is created
21-
/Not launching electron as debug argument was passed\. You must launch electron though your debugger\./
21+
/\$WEBPACK_DEV_SERVER_URL=/
2222
)
2323
) {
2424
resolve({

index.js

Lines changed: 55 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@ const webpack = require('webpack')
33
const Config = require('webpack-chain')
44
const merge = require('lodash.merge')
55
const fs = require('fs-extra')
6+
const path = require('path')
7+
const {
8+
log,
9+
done,
10+
info,
11+
logWithSpinner,
12+
stopSpinner,
13+
warn,
14+
error
15+
} = require('@vue/cli-shared-utils')
16+
const formatStats = require('@vue/cli-service/lib/commands/build/formatStats')
617
const { chainWebpack, getExternals } = require('./lib/webpackConfig')
718

819
module.exports = (api, options) => {
@@ -92,7 +103,7 @@ module.exports = (api, options) => {
92103
}
93104
// Set the base url so that the app protocol is used
94105
options.baseUrl = './'
95-
console.log('Bundling render process:')
106+
info('Bundling render process:')
96107
// Build the render process with the custom args
97108
await api.service.run('build', vueArgs)
98109
// Copy package.json to output dir
@@ -123,37 +134,26 @@ module.exports = (api, options) => {
123134
mainProcessChain,
124135
usesTypescript
125136
})
126-
console.log('Bundling main process:\n')
137+
logWithSpinner('Bundling main process...')
127138
bundle.run((err, stats) => {
139+
stopSpinner(false)
128140
if (err) {
129-
console.error(err.stack || err)
130-
if (err.details) {
131-
console.error(err.details)
132-
}
133141
return reject(err)
134142
}
135-
136-
const info = stats.toJson()
137-
138143
if (stats.hasErrors()) {
139-
return reject(info.errors)
144+
// eslint-disable-next-line prefer-promise-reject-errors
145+
return reject(`Build failed with errors.`)
140146
}
141-
142-
if (stats.hasWarnings()) {
143-
console.warn(info.warnings)
144-
}
145-
146-
console.log(
147-
stats.toString({
148-
chunks: false,
149-
colors: true
150-
})
147+
const targetDirShort = path.relative(
148+
api.service.context,
149+
`${outputDir}/bundled`
151150
)
151+
log(formatStats(stats, targetDirShort, api))
152152

153153
buildApp()
154154
})
155155
} else {
156-
console.log(
156+
info(
157157
'Not bundling main process as bundleMainProcess was set to false in plugin options'
158158
)
159159
// Copy main process file instead of bundling it
@@ -165,7 +165,7 @@ module.exports = (api, options) => {
165165
}
166166
}
167167
function buildApp () {
168-
console.log('\nBuilding app with electron-builder:\n')
168+
info('Building app with electron-builder:')
169169
// Build the app using electron builder
170170
builder
171171
.build({
@@ -179,7 +179,7 @@ module.exports = (api, options) => {
179179
})
180180
.then(() => {
181181
// handle result
182-
console.log('\nBuild complete!\n')
182+
done('Build complete!')
183183
resolve()
184184
})
185185
.catch(err => {
@@ -206,7 +206,6 @@ module.exports = (api, options) => {
206206
]
207207
const mainProcessArgs = pluginOptions.mainProcessArgs || []
208208

209-
console.log('\nStarting development server:\n')
210209
// Run the serve command
211210
const server = await api.service.run('serve', {
212211
_: [],
@@ -241,37 +240,22 @@ module.exports = (api, options) => {
241240
usesTypescript,
242241
server
243242
})
244-
console.log('Bundling main process:\n')
243+
logWithSpinner('Bundling main process...')
245244
bundle.run((err, stats) => {
245+
stopSpinner(false)
246246
if (err) {
247-
console.error(err.stack || err)
248-
if (err.details) {
249-
console.error(err.details)
250-
}
251-
process.exit(1)
247+
throw err
252248
}
253-
254-
const info = stats.toJson()
255-
256249
if (stats.hasErrors()) {
257-
console.error(info.errors)
250+
error(`Build failed with errors.`)
258251
process.exit(1)
259252
}
260-
261-
if (stats.hasWarnings()) {
262-
console.warn(info.warnings)
263-
}
264-
265-
console.log(
266-
stats.toString({
267-
chunks: false,
268-
colors: true
269-
})
270-
)
253+
const targetDirShort = path.relative(api.service.context, outputDir)
254+
log(formatStats(stats, targetDirShort, api))
271255
launchElectron()
272256
})
273257
} else {
274-
console.log(
258+
info(
275259
'Not bundling main process as bundleMainProcess was set to false in plugin options'
276260
)
277261
// Copy main process file instead of bundling it
@@ -291,14 +275,16 @@ module.exports = (api, options) => {
291275

292276
function launchElectron () {
293277
if (args.debug) {
278+
console.log(info)
279+
294280
// Do not launch electron and provide instructions on launching through debugger
295-
console.log(
296-
'\nNot launching electron as debug argument was passed. You must launch electron though your debugger.'
281+
info(
282+
'Not launching electron as debug argument was passed. You must launch electron though your debugger.'
297283
)
298-
console.log(
284+
info(
299285
`If you are using Spectron, make sure to set the IS_TEST env variable to true.`
300286
)
301-
console.log(
287+
info(
302288
'Learn more about debugging the main process at https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/testingAndDebugging.html#debugging.'
303289
)
304290
} else if (args.headless) {
@@ -307,14 +293,14 @@ module.exports = (api, options) => {
307293
console.log(`$WEBPACK_DEV_SERVER_URL=${server.url}`)
308294
} else {
309295
// Launch electron with execa
310-
if (mainProcessArgs) {
311-
console.log(
312-
'\nLaunching Electron with arguments: ' +
296+
if (mainProcessArgs.length > 0) {
297+
info(
298+
'Launching Electron with arguments: "' +
313299
mainProcessArgs.join(' ') +
314-
' ...'
300+
'" ...'
315301
)
316302
} else {
317-
console.log('\nLaunching Electron...')
303+
info('Launching Electron...')
318304
}
319305
child = execa(
320306
require('electron'),
@@ -369,9 +355,7 @@ module.exports = (api, options) => {
369355
`See https://nklayman.github.io/vue-cli-plugin-electron-builder/ for more details about this plugin.`
370356
},
371357
(args, rawArgs) => {
372-
console.log(
373-
'This command is deprecated. Please use electron:build instead.'
374-
)
358+
warn('This command is deprecated. Please use electron:build instead.')
375359
return api.service.run(
376360
'electron:build',
377361
{ ...args, _: ['First arg is removed', ...args._] },
@@ -389,9 +373,7 @@ module.exports = (api, options) => {
389373
details: `See https://nklayman.github.io/vue-cli-plugin-electron-builder/ for more details about this plugin.`
390374
},
391375
(args, rawArgs) => {
392-
console.log(
393-
'This command is deprecated. Please use electron:serve instead.'
394-
)
376+
warn('This command is deprecated. Please use electron:serve instead.')
395377
return api.service.run(
396378
'electron:serve',
397379
{ ...args, _: ['First arg is removed', ...args._] },
@@ -468,6 +450,18 @@ function bundleMain ({
468450
config
469451
.entry(isBuild ? 'background' : 'index')
470452
.add(api.resolve(mainProcessFile))
453+
const {
454+
transformer,
455+
formatter
456+
} = require('@vue/cli-service/lib/util/resolveLoaderError')
457+
config
458+
.plugin('friendly-errors')
459+
.use(require('friendly-errors-webpack-plugin'), [
460+
{
461+
additionalTransformers: [transformer],
462+
additionalFormatters: [formatter]
463+
}
464+
])
471465
if (usesTypescript) {
472466
config.resolve.extensions.merge(['.js', '.ts'])
473467
config.module

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"dependencies": {
3131
"electron-builder": "^20.28.1",
3232
"execa": "^1.0.0",
33+
"friendly-errors-webpack-plugin": "^1.7.0",
3334
"fs-extra": "^7.0.0",
3435
"lodash.merge": "^4.6.1",
3536
"portfinder": "^1.0.16",

0 commit comments

Comments
 (0)