@@ -9,67 +9,56 @@ module.exports = function injectImportsAndOptions (source, imports, injections)
9
9
return source
10
10
}
11
11
12
- const recast = require ( 'recast ' )
13
- const ast = recast . parse ( source )
12
+ const j = require ( 'jscodeshift ' )
13
+ const root = j ( source )
14
14
15
15
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
26
20
} )
27
- // avoid blank line after the previous import
28
- if ( lastImportIndex !== - 1 ) {
29
- delete ast . program . body [ lastImportIndex ] . loc
30
- }
31
21
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 ) )
35
25
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 )
41
27
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
+ }
44
38
}
45
39
46
40
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 ]
49
43
}
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 ) )
72
61
}
73
62
74
- return recast . print ( ast ) . code
63
+ return root . toSource ( )
75
64
}
0 commit comments