Blame view

node_modules/mpvue-loader/lib/mp-compiler/parse.js 2.35 KB
ce4c83ff   wxy   初始提交
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
  // babel-plugin-parse-mp-info.js
  
  const generate = require('babel-generator').default
  const babelon = require('babelon')
  
  function getImportsMap (metadata) {
    let { importsMap } = metadata
    const { imports } = metadata.modules
  
    if (!importsMap) {
      importsMap = {}
      imports.forEach(m => {
        m.specifiers.forEach(v => {
          importsMap[v.local] = m.source
        })
      })
      metadata.importsMap = importsMap
    }
  
    return metadata
  }
  
  // 解析 config
  const traverseConfigVisitor = {
    Property: function (path) {
      const k = path.node.key.name || path.node.key.value
      if (k !== 'config') {
        return
      }
      path.stop()
  
      const { metadata } = path.hub.file
      const { code } = generate(path.node.value, {}, '')
      metadata.config = { code, node: path.node.value, value: babelon.eval(code) }
  
      // path.remove()
    }
  }
  
  // config 的遍历器
  const configVisitor = {
    ExportDefaultDeclaration: function (path) {
      path.traverse(traverseConfigVisitor)
      path.remove()
    },
    NewExpression: function (path) {
      const { metadata } = path.hub.file
      const { importsMap } = getImportsMap(metadata)
  
      const calleeName = path.node.callee.name
      const isVue = /vue$/.test(importsMap[calleeName])
  
      if (!isVue) {
        return
      }
  
      const arg = path.node.arguments[0]
      const v = arg.type === 'Identifier' ? importsMap[arg.name] : importsMap['App']
      metadata.rootComponent = v || importsMap['index'] || importsMap['main']
    }
  }
  function parseConfig (babel) {
    return { visitor: configVisitor }
  }
  
  // 解析 components
  const traverseComponentsVisitor = {
    Property: function (path) {
      if (path.node.key.name !== 'components') {
        return
      }
      path.stop()
  
      const { metadata } = path.hub.file
      const { importsMap } = getImportsMap(metadata)
  
      // 找到所有的 imports
      const { properties } = path.node.value
      const components = {}
      properties.forEach(p => {
        const k = p.key.name || p.key.value
        const v = p.value.name || p.value.value
  
        components[k] = importsMap[v]
      })
  
      metadata.components = components
    }
  }
  
  // components 的遍历器
  const componentsVisitor = {
    ExportDefaultDeclaration: function (path) {
      path.traverse(traverseComponentsVisitor)
    }
  }
  function parseComponentsDeps (babel) {
    return { visitor: componentsVisitor }
  }
  
  module.exports = { parseConfig, parseComponentsDeps }