Blame view

node_modules/mpvue-loader/lib/mp-compiler/parse-ts.js 2.4 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
  let ts
  try {
    ts = require('typescript')
  } catch (e) {
  
  }
  
  function parseComponentsDeps (scriptContent) {
    const sourceFile = ts.createSourceFile('test', scriptContent, ts.ScriptTarget.ESNext, /* setParentNodes */ true)
    return delint(sourceFile)
  }
  
  function delint (sourceFile) {
    const compNames = {}
    const importsMap = {}
  
    delintNode(sourceFile)
  
    function parseDecorator (node) {
      // 只处理 @Component({components:{aaa}})
      if (node.expression.expression && node.expression.expression.escapedText === 'Component') {
        const compArgs = node.expression.arguments
        if (compArgs && compArgs.length === 1) {
          const vueClassArg = compArgs[0]
          if (vueClassArg.properties) {
            vueClassArg.properties.forEach((classProp) => {
              // 处理components属性
              if (classProp.name.escapedText === 'components') {
                classProp.initializer.properties.forEach((comp) => {
                  let compName
                  switch (comp.kind) {
                    case ts.SyntaxKind.ShorthandPropertyAssignment: // {Comp}
                      compName = comp.name.escapedText
                      // report(comp, '1')
                      break
                    case ts.SyntaxKind.PropertyAssignment: // {a:Comp}
                      compName = comp.initializer.escapedText
                      // report(comp, '2')
                      break
                  }
                  compNames[compName] = true
                })
              }
            })
          }
        }
      }
    }
  
    function delintNode (node) {
      switch (node.kind) {
        case ts.SyntaxKind.ImportDeclaration:
          // 只处理 import Comp from 'xxx.vue'
          if (node.importClause.name) {
            importsMap[node.importClause.name.escapedText] = node.moduleSpecifier.text
          }
          // report(node, 'import')
          break
        case ts.SyntaxKind.Decorator:
          parseDecorator(node)
          break
      }
  
      ts.forEachChild(node, delintNode)
    }
  
    function report(node, message) { // eslint-disable-line
      const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart())
      console.log(`${sourceFile.fileName} (${line + 1},${character + 1}): ${message}`)
    }
  
    const components = {}
    for (const k in compNames) {
      if (importsMap.hasOwnProperty(k)) {
        components[k] = importsMap[k]
      }
    }
    return {
      importsMap,
      components
    }
  }
  
  module.exports = { parseComponentsDeps }