11const fs = require ( 'fs' )
22const { SourceMapConsumer } = require ( 'source-map' )
33const path = require ( 'path' )
4+ const pify = require ( 'pify' )
5+ const fsAsync = pify ( fs )
6+
47//
58// Utility to help check if sourcemaps are working
69//
@@ -9,39 +12,85 @@ const path = require('path')
912// if not working it may error or print minified garbage
1013//
1114
12- start ( )
15+ start ( ) . catch ( console . error )
1316
1417
1518async function start ( ) {
16- const rawBuild = fs . readFileSync ( path . join ( __dirname , '/../dist/chrome/' , 'inpage.js' )
17- , 'utf8' )
18- const rawSourceMap = fs . readFileSync ( path . join ( __dirname , '/../dist/sourcemaps/' , 'inpage.js.map' ) , 'utf8' )
19+ const targetFiles = [ `inpage.js` , `contentscript.js` , `ui.js` , `background.js` ]
20+ for ( const buildName of targetFiles ) {
21+ await validateSourcemapForFile ( { buildName } )
22+ }
23+ }
24+
25+ async function validateSourcemapForFile ( { buildName } ) {
26+ console . log ( `build "${ buildName } "` )
27+ const platform = `chrome`
28+ // load build and sourcemaps
29+ let rawBuild
30+ try {
31+ const filePath = path . join ( __dirname , `/../dist/${ platform } /` , `${ buildName } ` )
32+ rawBuild = await fsAsync . readFile ( filePath , 'utf8' )
33+ } catch ( err ) { }
34+ if ( ! rawBuild ) {
35+ throw new Error ( `SourcemapValidator - failed to load source file for "${ buildName } "` )
36+ }
37+ // attempt to load in dist mode
38+ let rawSourceMap
39+ try {
40+ const filePath = path . join ( __dirname , `/../dist/sourcemaps/` , `${ buildName } .map` )
41+ rawSourceMap = await fsAsync . readFile ( filePath , 'utf8' )
42+ } catch ( err ) { }
43+ // attempt to load in dev mode
44+ try {
45+ const filePath = path . join ( __dirname , `/../dist/${ platform } /` , `${ buildName } .map` )
46+ rawSourceMap = await fsAsync . readFile ( filePath , 'utf8' )
47+ } catch ( err ) { }
48+ if ( ! rawSourceMap ) {
49+ throw new Error ( `SourcemapValidator - failed to load sourcemaps for "${ buildName } "` )
50+ }
51+
1952 const consumer = await new SourceMapConsumer ( rawSourceMap )
2053
21- console . log ( 'hasContentsOfAllSources:' , consumer . hasContentsOfAllSources ( ) , '\n' )
22- console . log ( 'sources:' )
23- consumer . sources . map ( ( sourcePath ) => console . log ( sourcePath ) )
24-
25- console . log ( '\nexamining "new Error" statements:\n' )
26- const sourceLines = rawBuild . split ( '\n' )
27- sourceLines . map ( line => indicesOf ( 'new Error' , line ) )
28- . forEach ( ( errorIndices , lineIndex ) => {
29- // if (errorIndex === null) return console.log('line does not contain "new Error"')
30- errorIndices . forEach ( ( errorIndex ) => {
31- const position = { line : lineIndex + 1 , column : errorIndex }
54+ const hasContentsOfAllSources = consumer . hasContentsOfAllSources ( )
55+ if ( ! hasContentsOfAllSources ) console . warn ( 'SourcemapValidator - missing content of some sources...' )
56+
57+ console . log ( ` sampling from ${ consumer . sources . length } files` )
58+ let sampleCount = 0
59+
60+ const buildLines = rawBuild . split ( '\n' )
61+ const targetString = 'new Error'
62+ // const targetString = 'null'
63+ const matchesPerLine = buildLines . map ( line => indicesOf ( targetString , line ) )
64+ matchesPerLine . forEach ( ( matchIndices , lineIndex ) => {
65+ matchIndices . forEach ( ( matchColumn ) => {
66+ sampleCount ++
67+ const position = { line : lineIndex + 1 , column : matchColumn }
3268 const result = consumer . originalPositionFor ( position )
33- if ( ! result . source ) return console . warn ( `!! missing source for position: ${ position } ` )
34- // filter out deps distributed minified without sourcemaps
35- if ( result . source === 'node_modules/browserify/node_modules/browser-pack/_prelude.js' ) return // minified mess
36- if ( result . source === 'node_modules/web3/dist/web3.min.js' ) return // minified mess
69+ // warn if source content is missing
70+ if ( ! result . source ) {
71+ console . warn ( `!! missing source for position: ${ JSON . stringify ( position ) } ` )
72+ // const buildLine = buildLines[position.line - 1]
73+ console . warn ( ` origin in build:` )
74+ console . warn ( ` ${ buildLines [ position . line - 2 ] } ` )
75+ console . warn ( `-> ${ buildLines [ position . line - 1 ] } ` )
76+ console . warn ( ` ${ buildLines [ position . line - 0 ] } ` )
77+ return
78+ }
3779 const sourceContent = consumer . sourceContentFor ( result . source )
3880 const sourceLines = sourceContent . split ( '\n' )
3981 const line = sourceLines [ result . line - 1 ]
40- console . log ( `\n========================== ${ result . source } ====================================\n` )
41- console . log ( line )
42- console . log ( `\n==============================================================================\n` )
82+ // this sometimes includes the whole line though we tried to match somewhere in the middle
83+ const portion = line . slice ( result . column )
84+ const isMaybeValid = portion . includes ( targetString )
85+ if ( ! isMaybeValid ) {
86+ console . error ( 'Sourcemap seems invalid:' )
87+ console . log ( `\n========================== ${ result . source } ====================================\n` )
88+ console . log ( line )
89+ console . log ( `\n==============================================================================\n` )
90+ }
4391 } )
4492 } )
93+ console . log ( ` checked ${ sampleCount } samples` )
4594}
4695
4796function indicesOf ( substring , string ) {
0 commit comments