@@ -9,67 +9,56 @@ module.exports = function injectImportsAndOptions (source, imports, injections)
99 return source
1010 }
1111
12- const recast = require ( 'recast ' )
13- const ast = recast . parse ( source )
12+ const j = require ( 'jscodeshift ' )
13+ const root = j ( source )
1414
1515 if ( hasImports ) {
16- const toImport = i => recast . parse ( `${ i } \n` ) . program . body [ 0 ]
17- const importDeclarations = [ ]
18- let lastImportIndex = - 1
19-
20- recast . types . visit ( ast , {
21- visitImportDeclaration ( { node } ) {
22- lastImportIndex = ast . program . body . findIndex ( n => n === node )
23- importDeclarations . push ( node )
24- return false
25- }
16+ const toImportAST = i => j ( `${ i } \n` ) . nodes ( ) [ 0 ] . program . body [ 0 ]
17+ const toImportHash = node => JSON . stringify ( {
18+ specifiers : node . specifiers . map ( s => s . local . name ) ,
19+ source : node . source . raw
2620 } )
27- // avoid blank line after the previous import
28- if ( lastImportIndex !== - 1 ) {
29- delete ast . program . body [ lastImportIndex ] . loc
30- }
3121
32- const nonDuplicates = i => {
33- return ! importDeclarations . some ( node => {
34- const result = node . source . raw === i . source . raw && node . specifiers . length === i . specifiers . length
22+ const declarations = root . find ( j . ImportDeclaration )
23+ const importSet = new Set ( declarations . nodes ( ) . map ( toImportHash ) )
24+ const nonDuplicates = node => ! importSet . has ( toImportHash ( node ) )
3525
36- return result && node . specifiers . every ( ( item , index ) => {
37- return i . specifiers [ index ] . local . name === item . local . name
38- } )
39- } )
40- }
26+ const importASTNodes = imports . map ( toImportAST ) . filter ( nonDuplicates )
4127
42- const newImports = imports . map ( toImport ) . filter ( nonDuplicates )
43- ast . program . body . splice ( lastImportIndex + 1 , 0 , ...newImports )
28+ if ( declarations . length ) {
29+ declarations
30+ . at ( - 1 )
31+ // a tricky way to avoid blank line after the previous import
32+ . forEach ( ( { node } ) => delete node . loc )
33+ . insertAfter ( importASTNodes )
34+ } else {
35+ // no pre-existing import declarations
36+ root . get ( ) . node . program . body . unshift ( ...importASTNodes )
37+ }
4438 }
4539
4640 if ( hasInjections ) {
47- const toProperty = i => {
48- return recast . parse ( `({${ i } })` ) . program . body [ 0 ] . expression . properties
41+ const toPropertyAST = i => {
42+ return j ( `({${ i } })` ) . nodes ( ) [ 0 ] . program . body [ 0 ] . expression . properties [ 0 ]
4943 }
50- recast . types . visit ( ast , {
51- visitNewExpression ( { node } ) {
52- if ( node . callee . name === 'Vue' ) {
53- const options = node . arguments [ 0 ]
54- if ( options && options . type === 'ObjectExpression' ) {
55- const nonDuplicates = i => {
56- return ! options . properties . slice ( 0 , - 1 ) . some ( p => {
57- return p . key . name === i [ 0 ] . key . name &&
58- recast . print ( p . value ) . code === recast . print ( i [ 0 ] . value ) . code
59- } )
60- }
61- // inject at index length - 1 as it's usually the render fn
62- options . properties = [
63- ...options . properties . slice ( 0 , - 1 ) ,
64- ...( [ ] . concat ( ...injections . map ( toProperty ) . filter ( nonDuplicates ) ) ) ,
65- ...options . properties . slice ( - 1 )
66- ]
67- }
68- }
69- return false
70- }
71- } )
44+
45+ const properties = root
46+ . find ( j . NewExpression , {
47+ callee : { name : 'Vue' } ,
48+ arguments : [ { type : 'ObjectExpression' } ]
49+ } )
50+ . map ( path => path . get ( 'arguments' , 0 ) )
51+ . get ( )
52+ . node
53+ . properties
54+
55+ const toPropertyHash = p => `${ p . key . name } : ${ j ( p . value ) . toSource ( ) } `
56+ const propertySet = new Set ( properties . map ( toPropertyHash ) )
57+ const nonDuplicates = p => ! propertySet . has ( toPropertyHash ( p ) )
58+
59+ // inject at index length - 1 as it's usually the render fn
60+ properties . splice ( - 1 , 0 , ...injections . map ( toPropertyAST ) . filter ( nonDuplicates ) )
7261 }
7362
74- return recast . print ( ast ) . code
63+ return root . toSource ( )
7564}
0 commit comments