UNPKG

4.57 kBJavaScriptView Raw
1const chalk = require('chalk')
2const highlight = require('highlight-es')
3const _ = require('lodash')
4const tildify = require('tildify')
5const logger = require('../../logger')
6
7function groupErrorsByType(errors) {
8 return errors.reduce((res, error) => {
9 res[error.type] = res[error.type] || []
10 res[error.type].push(error)
11 return res
12 }, {})
13}
14
15function moduleNotFound(errors) {
16 if (!errors) return false
17
18 let res = []
19 errors = _.uniqBy(errors, 'payload')
20
21 res.push(`${chalk.red('module not found:')}\n`)
22 res = res.concat(errors.map(error => {
23 const requestedBy = (error.error.origin && error.error.origin.resource) ? chalk.dim(`: imported at ${chalk.italic(tildify(error.error.origin.resource))}`) : ''
24 return `- ${chalk.yellow(error.payload)}${requestedBy}`
25 }))
26
27 return res.join('\n')
28}
29
30function uglifyError(errors) {
31 if (!errors) return false
32 // There's always only ONE uglify-token-error
33 const error = errors[0]
34
35 const res = []
36 const { message } = error.error
37
38 if (error.kind === 'module') {
39 res.push(`${chalk.red('UglifyJS error')}: unexpected ES6+ code in module "${error.payload}", full error message:\n`)
40 res.push(chalk.dim(message))
41 res.push('')
42 res.push(
43 logger.tip(chalk.bold(`To fix this, try adding "${error.payload}" to "transformModules" option, eg:`), false)
44 )
45 res.push('')
46 res.push(highlight(`// poi.config.js
47module.exports = {
48 transformModules: ['${error.payload}'],
49 // ...other config
50}`))
51 } else if (error.kind === 'file') {
52 res.push(`${chalk.red('UglifyJS error')}: unexpected ES6+ code in file "${error.payload}", full error message:\n`)
53 res.push(chalk.dim(message))
54 res.push('')
55 res.push(
56 logger.tip(chalk.bold(`To fix this, please configure .babelrc to compile your app code down to ES5 or use poi-preset-babel-minify if you want to preserve ES6+ code in final bundle.`), false)
57 )
58 }
59
60 return res.join('\n')
61}
62
63function vueVersionMismatch(errors) {
64 if (!errors) return
65
66 const res = []
67 const error = errors[0]
68 let message = error.error.message.replace(/This may cause things to work incorrectly[\s\S]+/, '')
69 message += 'Make sure to install both packages with the same version in your project.\nOtherwise webpack will use transitive dependencies from Poi.'
70 res.push(chalk.red(message))
71
72 return res.join('\n')
73}
74
75function unknownError(errors) {
76 if (!errors) return false
77
78 const res = errors.map(error => {
79 let msg = ''
80 if (error.error.origin && error.error.origin.resource) {
81 msg += chalk.red(`Error in ${chalk.italic(tildify(error.error.origin.resource))}`)
82 msg += '\n\n'
83 }
84 msg += error.error.message.replace(/Module build failed:\s+/, '').trim()
85 return msg
86 })
87
88 return res.join('\n')
89}
90
91function babelPluginNotFound(errors) {
92 if (!errors) return false
93
94 const res = []
95
96 const error = errors[0]
97 res.push(`${chalk.red('missing babel plugin:')} following babel plugin is referenced in ${chalk.italic(tildify(error.payload.location))}\nbut not installed in current project:\n`)
98 res.push(`- ${error.payload.name.replace(/^(babel-plugin-)?/, 'babel-plugin-')}`)
99
100 return res.join('\n')
101}
102
103function babelPresetNotFound(errors) {
104 if (!errors) return false
105
106 const res = []
107 const error = errors[0]
108 res.push(`${chalk.red('missing babel preset:')} following babel preset is not found in ${chalk.italic(tildify(error.payload.location))}:\n`)
109 res.push(`- ${error.payload.name.replace(/^(babel-preset-)?/, 'babel-preset-')}`)
110
111 return res.join('\n')
112}
113
114function eslintError(errors) {
115 if (!errors) return false
116
117 const res = []
118 res.push(`${chalk.red('code quality problems:')}`)
119 const error = errors[0]
120 res.push(error.error.message)
121 res.push(
122 logger.tip('You may use special comments to disable some warnings.', false)
123 )
124 res.push(chalk.dim(`
125- Use ${chalk.yellow('// eslint-disable-next-line')} to ignore the next line.
126- Use ${chalk.yellow('/* eslint-disable */')} to ignore all warnings in a file.`))
127
128 return res.join('\n')
129}
130
131function run(results) {
132 console.log(results.filter(result => result).join('\n\n'))
133 console.log()
134}
135
136module.exports = errors => {
137 errors = groupErrorsByType(errors)
138 run([
139 moduleNotFound(errors['module-not-found']),
140 uglifyError(errors['uglify-error']),
141 vueVersionMismatch(errors['vue-version-mismatch']),
142 babelPluginNotFound(errors['babel-plugin-not-found']),
143 babelPresetNotFound(errors['babel-preset-not-found']),
144 eslintError(errors['eslint-error']),
145 unknownError(errors.unknown)
146 ])
147}