compiler-options.js 3.3 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1 2 3
const {
  tags
} = require('@dcloudio/uni-cli-shared')
4 5
const parser = require('@babel/parser')
const t = require('@babel/types')
fxy060608's avatar
fxy060608 已提交
6 7 8

const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/

9 10
function isFunction (expr) {
  try {
11
    const body = parser.parse(`(${expr})`).program.body[0]
12
    const expression = body.expression
13 14 15
    return t.isFunctionDeclaration(body) || t.isArrowFunctionExpression(expression) || t.isFunctionExpression(
      expression)
  } catch (error) {}
16 17
}

fxy060608's avatar
fxy060608 已提交
18
function processEvent (expr, filterModules) {
fxy060608's avatar
fxy060608 已提交
19
  const isMethodPath = simplePathRE.test(expr)
20
  if (isMethodPath || isFunction(expr)) {
fxy060608's avatar
fxy060608 已提交
21 22 23
    if (filterModules.find(name => expr.indexOf(name + '.') === 0)) {
      return `
$event = $handleWxsEvent($event);
24
(${expr})($event, $getComponentDescriptor())
fxy060608's avatar
fxy060608 已提交
25 26
`
    } else {
27
      expr = `(${expr})(...arguments)`
fxy060608's avatar
fxy060608 已提交
28
    }
fxy060608's avatar
fxy060608 已提交
29 30
  }
  return `
fxy060608's avatar
fxy060608 已提交
31
arguments[0] = $event = $handleEvent($event);
fxy060608's avatar
fxy060608 已提交
32 33 34 35
${expr}
`
}

fxy060608's avatar
fxy060608 已提交
36
function hasOwn (obj, key) {
fxy060608's avatar
fxy060608 已提交
37 38 39 40 41
  return hasOwnProperty.call(obj, key)
}

const deprecated = {
  events: {
fxy060608's avatar
fxy060608 已提交
42 43
    tap: 'click',
    longtap: 'longpress'
fxy060608's avatar
fxy060608 已提交
44 45 46
  }
}

fxy060608's avatar
fxy060608 已提交
47
function addTag (tag) {
fxy060608's avatar
fxy060608 已提交
48 49 50 51 52 53 54
  if (!process.UNI_TAGS) {
    process.UNI_TAGS = new Set()
  }
  process.UNI_TAGS.add(tag)
}

module.exports = {
55
  h5: true,
fxy060608's avatar
fxy060608 已提交
56
  modules: [require('../format-text'), {
fxy060608's avatar
fxy060608 已提交
57
    preTransformNode (el, options) {
fxy060608's avatar
fxy060608 已提交
58 59 60 61 62 63 64
      if (el.tag.indexOf('v-uni-') === 0) {
        addTag(el.tag.replace('v-uni-', ''))
      } else if (hasOwn(tags, el.tag)) {
        addTag(el.tag)
        el.tag = 'v-uni-' + el.tag
      }
    },
fxy060608's avatar
fxy060608 已提交
65
    postTransformNode (el, {
fxy060608's avatar
fxy060608 已提交
66 67
      warn,
      filterModules
fxy060608's avatar
fxy060608 已提交
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
    }) {
      if (el.tag === 'block') {
        el.tag = 'template'
        const vForKey = el.key
        if (vForKey) {
          delete el.key
          el.children.forEach((childEl, index) => {
            const childVForKey = childEl.key
            if (childVForKey) {
              childEl.key = `${childVForKey}+'_'+${vForKey}+'_${index}'`
            } else {
              childEl.key = `${vForKey}+'_${index}'`
            }
          })
        }
      }
84
      if (el.events || el.nativeEvents) {
fxy060608's avatar
fxy060608 已提交
85
        filterModules = filterModules || []
fxy060608's avatar
fxy060608 已提交
86 87 88 89
        const {
          events: eventsMap
        } = deprecated
        // const warnLogs = new Set()
90 91
        normalizeEvent(el, el.events, eventsMap, filterModules)
        normalizeEvent(el, el.nativeEvents, eventsMap, filterModules)
fxy060608's avatar
fxy060608 已提交
92 93 94
      }
    }
  }]
95
}
96

97
function normalizeEvent (el, events, eventsMap, filterModules) {
98 99 100
  if (!events) {
    return
  }
101
  const isMap = el.tag === 'map' || el.tag === 'v-uni-map'
102 103 104
  Object.keys(events).forEach(name => {
    // 过时事件类型转换
    if (eventsMap[name]) {
105 106 107 108 109 110 111 112
      if (isMap && name === 'tap') {
        // 地图组件有自己特定的 tap 事件,不做转换
      } else {
        events[eventsMap[name]] = events[name]
        delete events[name]
        // warnLogs.add(`警告:事件${name}已过时,推荐使用${eventsMap[name]}代替`)
        name = eventsMap[name]
      }
113 114 115 116 117 118 119 120 121 122 123 124
    }

    const handlers = events[name]
    if (Array.isArray(handlers)) {
      handlers.forEach(handler => {
        handler.value = processEvent(handler.value, filterModules)
      })
    } else {
      handlers.value = processEvent(handlers.value, filterModules)
    }
  })
}