1
- const { red, yellow } = require ( 'kleur' ) ;
1
+ const { red, gray } = require ( 'kleur' ) ;
2
2
const { resolve } = require ( 'path' ) ;
3
3
const { readFileSync } = require ( 'fs' ) ;
4
4
const stackTrace = require ( 'stack-trace' ) ;
5
5
const { SourceMapConsumer } = require ( 'source-map' ) ;
6
+ const { error, info } = require ( '../../util' ) ;
6
7
7
8
module . exports = function ( env , params ) {
8
9
params = params || { } ;
@@ -14,8 +15,8 @@ module.exports = function(env, params) {
14
15
global . location = { href : url , pathname : url } ;
15
16
16
17
try {
17
- let m = require ( entry ) ,
18
- app = ( m && m . default ) || m ;
18
+ const m = require ( entry ) ;
19
+ const app = ( m && m . default ) || m ;
19
20
20
21
if ( typeof app !== 'function' ) {
21
22
// eslint-disable-next-line no-console
@@ -33,91 +34,139 @@ module.exports = function(env, params) {
33
34
34
35
return renderToString ( preact . h ( app , { ...params , url } ) ) ;
35
36
} catch ( err ) {
36
- let stack = stackTrace . parse ( err ) . filter ( s => s . getFileName ( ) === entry ) [ 0 ] ;
37
+ const stack = stackTrace
38
+ . parse ( err )
39
+ . filter ( s => s . getFileName ( ) . includes ( 'ssr-build' ) ) [ 0 ] ;
37
40
if ( ! stack ) {
38
- throw err ;
41
+ error ( err ) ;
42
+ return '' ;
39
43
}
40
44
41
45
handlePrerenderError ( err , env , stack , entry ) ;
46
+ return '' ;
42
47
}
43
48
} ;
44
49
45
50
async function handlePrerenderError ( err , env , stack , entry ) {
46
- let errorMessage = err . toString ( ) ;
47
- let isReferenceError = errorMessage . startsWith ( 'ReferenceError' ) ;
48
- let methodName = stack . getMethodName ( ) ;
49
- let sourceMapContent , position , sourcePath , sourceLines , sourceCodeHighlight ;
50
-
51
- try {
52
- sourceMapContent = JSON . parse ( readFileSync ( `${ entry } .map` ) ) ;
53
- } catch ( err ) {
54
- process . stderr . write ( red ( `Unable to read sourcemap: ${ entry } .map\n` ) ) ;
55
- }
51
+ const errorMessage = err . toString ( ) ;
52
+ const isReferenceError = errorMessage . startsWith ( 'ReferenceError' ) ;
53
+ const methodName = stack . getMethodName ( ) ;
54
+ const fileName = stack . getFileName ( ) . replace ( / \\ / g, '/' ) ;
55
+ let sourceCodeHighlight = '' ;
56
+
57
+ let position ;
58
+
59
+ info ( fileName ) ;
60
+ if ( / w e b p a c k : / . test ( fileName ) ) {
61
+ position = {
62
+ source : fileName . replace ( / .+ w e b p a c k : / , 'webpack://' ) ,
63
+ line : stack . getLineNumber ( ) ,
64
+ column : stack . getColumnNumber ( ) ,
65
+ } ;
66
+ } else {
67
+ try {
68
+ const sourceMapContent = JSON . parse ( readFileSync ( `${ entry } .map` ) ) ;
56
69
57
- if ( sourceMapContent ) {
58
- await SourceMapConsumer . with ( sourceMapContent , null , consumer => {
59
- position = consumer . originalPositionFor ( {
60
- line : stack . getLineNumber ( ) ,
61
- column : stack . getColumnNumber ( ) ,
70
+ await SourceMapConsumer . with ( sourceMapContent , null , consumer => {
71
+ position = consumer . originalPositionFor ( {
72
+ line : stack . getLineNumber ( ) ,
73
+ column : stack . getColumnNumber ( ) ,
74
+ } ) ;
62
75
} ) ;
63
- } ) ;
76
+ } catch ( err ) {
77
+ error ( `Unable to read sourcemap: ${ entry } .map` ) ;
78
+ return ;
79
+ }
80
+ }
64
81
82
+ if ( position ) {
83
+ info ( position . source ) ;
65
84
position . source = position . source
66
85
. replace ( 'webpack://' , '.' )
67
86
. replace ( / ^ .* ~ \/ ( (?: @ [ ^ / ] + \/ ) ? [ ^ / ] + ) / , ( s , name ) =>
68
87
require
69
88
. resolve ( name )
70
89
. replace ( / ^ ( .* ?\/ n o d e _ m o d u l e s \/ ( @ [ ^ / ] + \/ ) ? [ ^ / ] + ) ( \/ .* ) $ / , '$1' )
71
90
) ;
91
+ info ( position . source ) ;
72
92
73
- sourcePath = resolve ( env . src , position . source ) ;
74
- sourceLines ;
93
+ let sourcePath ;
94
+ let sourceLines ;
75
95
try {
96
+ sourcePath = resolve ( env . src , position . source ) ;
76
97
sourceLines = readFileSync ( sourcePath , 'utf-8' ) . split ( '\n' ) ;
77
98
} catch ( err ) {
78
99
try {
79
- sourceLines = readFileSync (
80
- require . resolve ( position . source ) ,
81
- 'utf-8'
82
- ) . split ( '\n' ) ;
100
+ sourcePath = resolve ( env . cwd , position . source ) ;
101
+ // sourcePath = require.resolve(position.source);
102
+ sourceLines = readFileSync ( sourcePath , 'utf-8' ) . split ( '\n' ) ;
83
103
} catch ( err ) {
84
- process . stderr . write ( red ( `Unable to read file: ${ sourcePath } \n` ) ) ;
104
+ error ( `Unable to read file: ${ sourcePath } (${ position . source } )\n` ) ;
105
+ return ;
85
106
}
86
- // process.stderr.write(red(`Unable to read file: ${sourcePath}\n`));
87
107
}
88
- sourceCodeHighlight = '' ;
89
108
90
109
if ( sourceLines ) {
91
- for ( var i = - 4 ; i <= 4 ; i ++ ) {
92
- let color = i === 0 ? red : yellow ;
93
- let line = position . line + i ;
94
- let sourceLine = sourceLines [ line - 1 ] ;
95
- sourceCodeHighlight += sourceLine ? `${ color ( sourceLine ) } \n` : '' ;
96
- }
110
+ let lnrl = position . line . toString ( ) . length + 1 ;
111
+ sourceCodeHighlight +=
112
+ gray (
113
+ ( position . line - 2 || '' ) . toString ( ) . padStart ( lnrl ) +
114
+ ' | ' +
115
+ sourceLines [ position . line - 3 ] || ''
116
+ ) + '\n' ;
117
+ sourceCodeHighlight +=
118
+ gray (
119
+ ( position . line - 1 || '' ) . toString ( ) . padStart ( lnrl ) +
120
+ ' | ' +
121
+ sourceLines [ position . line - 2 ] || ''
122
+ ) + '\n' ;
123
+ sourceCodeHighlight +=
124
+ red ( position . line . toString ( ) . padStart ( lnrl ) ) +
125
+ gray ( ' | ' ) +
126
+ sourceLines [ position . line - 1 ] +
127
+ '\n' ;
128
+ sourceCodeHighlight +=
129
+ gray ( '| ' . padStart ( lnrl + 3 ) ) +
130
+ red ( '^' . padStart ( position . column + 1 ) ) +
131
+ '\n' ;
132
+ sourceCodeHighlight +=
133
+ gray (
134
+ ( position . line + 1 ) . toString ( ) . padStart ( lnrl ) +
135
+ ' | ' +
136
+ sourceLines [ position . line + 0 ] || ''
137
+ ) + '\n' ;
138
+ sourceCodeHighlight +=
139
+ gray (
140
+ ( position . line + 2 ) . toString ( ) . padStart ( lnrl ) +
141
+ ' | ' +
142
+ sourceLines [ position . line + 1 ] || ''
143
+ ) + '\n' ;
97
144
}
145
+ } else {
146
+ position = {
147
+ source : stack . getFileName ( ) ,
148
+ line : stack . getLineNumber ( ) ,
149
+ column : stack . getColumnNumber ( ) ,
150
+ } ;
98
151
}
99
152
100
153
process . stderr . write ( '\n' ) ;
101
- process . stderr . write ( red ( `${ errorMessage } \n` ) ) ;
102
- process . stderr . write ( `method: ${ methodName } \n` ) ;
103
- if ( sourceMapContent ) {
104
- process . stderr . write (
105
- `at: ${ sourcePath } :${ position . line } :${ position . column } \n`
106
- ) ;
107
- process . stderr . write ( '\n' ) ;
108
- process . stderr . write ( 'Source code:\n\n' ) ;
109
- process . stderr . write ( sourceCodeHighlight ) ;
110
- process . stderr . write ( '\n' ) ;
111
- } else {
112
- process . stderr . write ( stack . toString ( ) + '\n' ) ;
113
- }
154
+ process . stderr . write ( `[PrerenderError]: ${ red ( `${ errorMessage } \n` ) } ` ) ;
155
+ process . stderr . write (
156
+ ` --> ${ position . source } :${ position . line } :${
157
+ position . column
158
+ } (${ methodName || '<anonymous>' } )\n`
159
+ ) ;
160
+ process . stderr . write ( sourceCodeHighlight + '\n' ) ;
161
+ process . stderr . write ( red ( `${ err . stack } \n` ) ) ;
162
+
114
163
process . stderr . write (
115
164
`This ${
116
165
isReferenceError ? 'is most likely' : 'could be'
117
166
} caused by using DOM or Web APIs.\n`
118
167
) ;
119
168
process . stderr . write (
120
- `Pre-render runs in node and has no access to globals available in browsers.\n\n `
169
+ `Pre-render runs in node and has no access to globals available in browsers.\n`
121
170
) ;
122
171
process . stderr . write (
123
172
`Consider wrapping code producing error in: 'if (typeof window !== "undefined") { ... }'\n`
@@ -128,7 +177,7 @@ async function handlePrerenderError(err, env, stack, entry) {
128
177
}
129
178
process . stderr . write ( '\n' ) ;
130
179
process . stderr . write (
131
- ` Alternatively use ' preact build --no-prerender' to disable prerendering.\n\n`
180
+ ' Alternatively use ` preact build --no-prerender` to disable prerendering.\n'
132
181
) ;
133
182
process . stderr . write (
134
183
'See https://github.com/developit/preact-cli#pre-rendering for further information.'
0 commit comments