optimizer.js 2.4 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1 2 3 4 5 6 7 8 9
const {
  ID,
  isVar
} = require('./util')

const {
  isComponent
} = require('../util')

fxy060608's avatar
fxy060608 已提交
10 11 12 13 14 15 16
let isPlatformReservedTag

function no (a, b, c) {
  return false
}

function isBuiltInTag (tag) {
fxy060608's avatar
fxy060608 已提交
17 18 19 20 21
  if (
    tag === 'slot' ||
    tag === 'component' ||
    tag === 'keep-alive'
  ) {
fxy060608's avatar
fxy060608 已提交
22 23 24 25 26 27 28 29 30 31 32
    return true
  }
}

function isStatic (node) {
  if (node.type === 2) {
    return false
  }
  if (node.type === 3) {
    return true
  }
fxy060608's avatar
fxy060608 已提交
33
  if (node.staticClass || node.classBinding || node.styleBinding) {
fxy060608's avatar
fxy060608 已提交
34 35 36 37 38 39 40 41 42 43 44 45
    return false
  }
  return !!(node.pre || (
    !node.hasBindings && // no dynamic bindings
    !isBuiltInTag(node.tag) && // not a built-in
    isPlatformReservedTag(node.tag)
  ))
}

function markStatic (node) {
  if (isStatic(node)) { // 静态节点且仅包含 ID 属性
    if (
fxy060608's avatar
fxy060608 已提交
46
      node.attrs &&
fxy060608's avatar
fxy060608 已提交
47 48 49 50 51 52 53
      node.attrs.length === 1 &&
      !node.key &&
      !node.ref &&
      !node.slotTarget
    ) {
      node.plain = true
    }
fxy060608's avatar
fxy060608 已提交
54
    if (!node.attrsMap || !node.attrsMap.id) { // 保留 id 属性, selectComponent 需要使用
fxy060608's avatar
fxy060608 已提交
55 56
      delete node.attrs
    }
fxy060608's avatar
fxy060608 已提交
57
  }
fxy060608's avatar
fxy060608 已提交
58
  if (node.type === 1) {
fxy060608's avatar
fxy060608 已提交
59 60
    // 需要保留 staticClass , selectComponent,externalClasses
    // delete node.staticClass
fxy060608's avatar
fxy060608 已提交
61 62
    delete node.staticStyle

fxy060608's avatar
fxy060608 已提交
63 64
    const isCustomComponent = isComponent(node.tag)
    if (node.attrs && !isCustomComponent && node.tag !== 'keep-alive') { // 移除静态属性
fxy060608's avatar
fxy060608 已提交
65
      // 保留 id 属性, selectComponent 需要使用
fxy060608's avatar
fxy060608 已提交
66 67 68 69 70 71 72 73 74 75
      node.attrs = node.attrs.filter(attr => {
        const {
          name,
          value
        } = attr
        return name === 'id' ||
          name === ID ||
          // name.indexOf('data-') === 0 || // TODO dataset
          isVar(value)
      })
fxy060608's avatar
fxy060608 已提交
76 77 78 79
    }

    node.children = node.children.filter(child => { // 移除静态文本
      if (child.type === 3) { // ASTText
fxy060608's avatar
fxy060608 已提交
80 81 82 83
        if (!isCustomComponent) {
          return false
        }
        child.text = '' // slot <custom>ABCD</custom>
fxy060608's avatar
fxy060608 已提交
84 85 86 87
      }
      return true
    })

fxy060608's avatar
fxy060608 已提交
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
    for (let i = 0, l = node.children.length; i < l; i++) {
      const child = node.children[i]
      markStatic(child)
    }
    if (node.ifConditions) {
      for (let i = 1, l = node.ifConditions.length; i < l; i++) {
        const block = node.ifConditions[i].block
        markStatic(block)
      }
    }
  }
}

module.exports = function optimize (root, options) {
  isPlatformReservedTag = options.isReservedTag || no
  markStatic(root)
}