extendJSConfig.js 1.9 KB

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