forked from vuejs/vue-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextendJSConfig.js
70 lines (62 loc) · 1.86 KB
/
extendJSConfig.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
module.exports = function extendJSConfig (value, source) {
const recast = require('recast')
const stringifyJS = require('./stringifyJS')
let exportsIdentifier = null
const ast = recast.parse(source)
recast.types.visit(ast, {
visitAssignmentExpression (path) {
const { node } = path
if (
node.left.type === 'MemberExpression' &&
node.left.object.name === 'module' &&
node.left.property.name === 'exports'
) {
if (node.right.type === 'ObjectExpression') {
augmentExports(node.right)
} else if (node.right.type === 'Identifier') {
// do a second pass
exportsIdentifier = node.right.name
}
return false
}
this.traverse(path)
}
})
if (exportsIdentifier) {
recast.types.visit(ast, {
visitVariableDeclarator ({ node }) {
if (
node.id.name === exportsIdentifier &&
node.init.type === 'ObjectExpression'
) {
augmentExports(node.init)
}
return false
}
})
}
function augmentExports (node) {
const valueAST = recast.parse(`(${stringifyJS(value, null, 2)})`)
const props = valueAST.program.body[0].expression.properties
const existingProps = node.properties
for (const prop of props) {
const isUndefinedProp =
prop.value.type === 'Identifier' && prop.value.name === 'undefined'
const existing = existingProps.findIndex(p => {
return !p.computed && p.key.name === prop.key.name
})
if (existing > -1) {
// replace
existingProps[existing].value = prop.value
// remove `undefined` props
if (isUndefinedProp) {
existingProps.splice(existing, 1)
}
} else if (!isUndefinedProp) {
// append
existingProps.push(prop)
}
}
}
return recast.print(ast).code
}