@mpxjs/webpack-plugin 2.9.40 → 2.9.41-react.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/lib/config.js +63 -97
  2. package/lib/dependencies/{RecordVueContentDependency.js → RecordLoaderContentDependency.js} +5 -5
  3. package/lib/dependencies/ResolveDependency.js +2 -2
  4. package/lib/helpers.js +5 -1
  5. package/lib/index.js +26 -21
  6. package/lib/loader.js +43 -97
  7. package/lib/native-loader.js +0 -1
  8. package/lib/platform/index.js +3 -0
  9. package/lib/platform/style/wx/index.js +414 -0
  10. package/lib/platform/template/wx/component-config/button.js +36 -0
  11. package/lib/platform/template/wx/component-config/image.js +15 -0
  12. package/lib/platform/template/wx/component-config/input.js +41 -0
  13. package/lib/platform/template/wx/component-config/scroll-view.js +27 -1
  14. package/lib/platform/template/wx/component-config/swiper-item.js +13 -1
  15. package/lib/platform/template/wx/component-config/swiper.js +25 -1
  16. package/lib/platform/template/wx/component-config/text.js +15 -0
  17. package/lib/platform/template/wx/component-config/textarea.js +39 -0
  18. package/lib/platform/template/wx/component-config/unsupported.js +18 -0
  19. package/lib/platform/template/wx/component-config/view.js +14 -0
  20. package/lib/platform/template/wx/index.js +88 -4
  21. package/lib/react/index.js +104 -0
  22. package/lib/react/processJSON.js +361 -0
  23. package/lib/react/processMainScript.js +21 -0
  24. package/lib/react/processScript.js +70 -0
  25. package/lib/react/processStyles.js +69 -0
  26. package/lib/react/processTemplate.js +153 -0
  27. package/lib/react/script-helper.js +133 -0
  28. package/lib/react/style-helper.js +91 -0
  29. package/lib/resolver/PackageEntryPlugin.js +1 -0
  30. package/lib/runtime/components/react/event.config.ts +32 -0
  31. package/lib/runtime/components/react/getInnerListeners.ts +289 -0
  32. package/lib/runtime/components/react/getInnerListeners.type.ts +68 -0
  33. package/lib/runtime/components/react/mpx-button.tsx +402 -0
  34. package/lib/runtime/components/react/mpx-image/index.tsx +351 -0
  35. package/lib/runtime/components/react/mpx-image/svg.tsx +21 -0
  36. package/lib/runtime/components/react/mpx-input.tsx +389 -0
  37. package/lib/runtime/components/react/mpx-scroll-view.tsx +412 -0
  38. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +398 -0
  39. package/lib/runtime/components/react/mpx-swiper/index.tsx +68 -0
  40. package/lib/runtime/components/react/mpx-swiper/type.ts +69 -0
  41. package/lib/runtime/components/react/mpx-swiper-item.tsx +42 -0
  42. package/lib/runtime/components/react/mpx-text.tsx +106 -0
  43. package/lib/runtime/components/react/mpx-textarea.tsx +46 -0
  44. package/lib/runtime/components/react/mpx-view.tsx +397 -0
  45. package/lib/runtime/components/react/useNodesRef.ts +39 -0
  46. package/lib/runtime/components/react/utils.ts +92 -0
  47. package/lib/runtime/optionProcessorReact.d.ts +9 -0
  48. package/lib/runtime/optionProcessorReact.js +21 -0
  49. package/lib/runtime/stringify.wxs +3 -8
  50. package/lib/style-compiler/index.js +2 -1
  51. package/lib/template-compiler/compiler.js +287 -36
  52. package/lib/template-compiler/gen-node-react.js +95 -0
  53. package/lib/template-compiler/index.js +15 -24
  54. package/lib/utils/env.js +17 -0
  55. package/lib/utils/make-map.js +1 -1
  56. package/lib/utils/shallow-stringify.js +12 -12
  57. package/lib/web/index.js +123 -0
  58. package/lib/web/processJSON.js +3 -3
  59. package/lib/web/processMainScript.js +25 -23
  60. package/lib/web/processScript.js +12 -16
  61. package/lib/web/processTemplate.js +13 -12
  62. package/lib/web/script-helper.js +14 -22
  63. package/package.json +4 -3
@@ -14,8 +14,9 @@ const makeMap = require('../utils/make-map')
14
14
  const { isNonPhrasingTag } = require('../utils/dom-tag-config')
15
15
  const setBaseWxml = require('../runtime-render/base-wxml')
16
16
  const { parseExp } = require('./parse-exps')
17
-
18
17
  const shallowStringify = require('../utils/shallow-stringify')
18
+ const { isReact } = require('../utils/env')
19
+
19
20
  const no = function () {
20
21
  return false
21
22
  }
@@ -37,6 +38,7 @@ const endTag = new RegExp(('^<\\/' + qnameCapture + '[^>]*>'))
37
38
  const doctype = /^<!DOCTYPE [^>]+>/i
38
39
  const comment = /^<!--/
39
40
  const conditionalComment = /^<!\[/
41
+ const hoverClassReg = /^mpx-((cover-)?view|button|navigator)$/
40
42
  let IS_REGEX_CAPTURING_BROKEN = false
41
43
  'x'.replace(/x(.)?/g, function (m, g) {
42
44
  IS_REGEX_CAPTURING_BROKEN = g === ''
@@ -77,11 +79,11 @@ function createASTElement (tag, attrs = [], parent = null) {
77
79
 
78
80
  function isForbiddenTag (el) {
79
81
  return (
80
- el.tag === 'style' ||
81
- (el.tag === 'script' && (
82
- !el.attrsMap.type ||
83
- el.attrsMap.type === 'text/javascript'
84
- ))
82
+ el.tag === 'style' ||
83
+ (el.tag === 'script' && (
84
+ !el.attrsMap.type ||
85
+ el.attrsMap.type === 'text/javascript'
86
+ ))
85
87
  )
86
88
  }
87
89
 
@@ -99,6 +101,7 @@ let moduleId
99
101
  let isNative
100
102
  let hasScoped
101
103
  let hasVirtualHost
104
+ let runtimeCompile
102
105
  let rulesRunner
103
106
  let currentEl
104
107
  let injectNodes = []
@@ -285,8 +288,8 @@ function parseHTML (html, options) {
285
288
  endTagLength = endTag.length
286
289
  if (!isPlainTextElement(stackedTag) && stackedTag !== 'noscript') {
287
290
  text = text
288
- .replace(/<!--([\s\S]*?)-->/g, '$1')
289
- .replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1')
291
+ .replace(/<!--([\s\S]*?)-->/g, '$1')
292
+ .replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1')
290
293
  }
291
294
  if (shouldIgnoreFirstNewline(stackedTag, text)) {
292
295
  text = text.slice(1)
@@ -425,7 +428,7 @@ function parseHTML (html, options) {
425
428
  for (let i = stack.length - 1; i >= pos; i--) {
426
429
  if ((i > pos || !tagName) && options.warn) {
427
430
  options.warn(
428
- ('tag <' + (stack[i].tag) + '> has no matching end tag.')
431
+ ('tag <' + (stack[i].tag) + '> has no matching end tag.')
429
432
  )
430
433
  }
431
434
  if (options.end) {
@@ -616,6 +619,7 @@ function parse (template, options) {
616
619
  hasVirtualHost = options.hasVirtualHost
617
620
  filePath = options.filePath
618
621
  i18n = options.i18n
622
+ runtimeCompile = options.runtimeCompile
619
623
  platformGetTagNamespace = options.getTagNamespace || no
620
624
  refId = 0
621
625
  injectNodes = []
@@ -688,9 +692,9 @@ function parse (template, options) {
688
692
  if (isForbiddenTag(element)) {
689
693
  element.forbidden = true
690
694
  warn$1(
691
- 'Templates should only be responsible for mapping the state to the ' +
692
- 'UI. Avoid placing tags with side-effects in your templates, such as ' +
693
- '<' + tag + '>' + ', as they will not be parsed.'
695
+ 'Templates should only be responsible for mapping the state to the ' +
696
+ 'UI. Avoid placing tags with side-effects in your templates, such as ' +
697
+ '<' + tag + '>' + ', as they will not be parsed.'
694
698
  )
695
699
  }
696
700
 
@@ -747,7 +751,7 @@ function parse (template, options) {
747
751
  parent: currentParent
748
752
  }
749
753
  children.push(el)
750
- options.runtimeCompile ? processTextDynamic(el) : processText(el)
754
+ runtimeCompile ? processTextDynamic(el) : processText(el)
751
755
  }
752
756
  }
753
757
  },
@@ -859,20 +863,21 @@ function modifyAttr (el, name, val) {
859
863
  }
860
864
  }
861
865
 
862
- function postMoveBaseDirective (target, source, options, isDelete = true) {
866
+ function postMoveBaseDirective (target, source, isDelete = true) {
863
867
  target.for = source.for
864
868
  target.if = source.if
865
869
  target.elseif = source.elseif
866
870
  target.else = source.else
867
-
868
- if (options.runtimeCompile) {
871
+ if (isReact(mode)) {
872
+ postProcessForReact(target)
873
+ postProcessIfReact(target)
874
+ } else if (runtimeCompile) {
869
875
  postProcessForDynamic(target, config[mode])
870
876
  postProcessIfDynamic(target, config[mode])
871
877
  } else {
872
878
  postProcessFor(target)
873
879
  postProcessIf(target)
874
880
  }
875
-
876
881
  if (isDelete) {
877
882
  delete source.for
878
883
  delete source.if
@@ -1047,6 +1052,128 @@ function stringifyWithResolveComputed (modelValue) {
1047
1052
  return result.join('+')
1048
1053
  }
1049
1054
 
1055
+ function processStyleReact (el) {
1056
+ // process class/wx:class/style/wx:style/wx:show for react native
1057
+ const dynamicClass = getAndRemoveAttr(el, config[mode].directive.dynamicClass).val
1058
+ let staticClass = getAndRemoveAttr(el, 'class').val || ''
1059
+ staticClass = staticClass.replace(/\s+/g, ' ')
1060
+
1061
+ let staticHoverClass = ''
1062
+ if (hoverClassReg.test(el.tag)) {
1063
+ staticHoverClass = el.attrsMap['hover-class'] || ''
1064
+ staticHoverClass = staticHoverClass.replace(/\s+/g, ' ')
1065
+ }
1066
+
1067
+ const dynamicStyle = getAndRemoveAttr(el, config[mode].directive.dynamicStyle).val
1068
+ let staticStyle = getAndRemoveAttr(el, 'style').val || ''
1069
+ staticStyle = staticStyle.replace(/\s+/g, ' ')
1070
+
1071
+ const show = getAndRemoveAttr(el, config[mode].directive.show).val
1072
+
1073
+ if (dynamicClass || staticClass || dynamicStyle || staticStyle || show) {
1074
+ const staticClassExp = parseMustacheWithContext(staticClass).result
1075
+ const dynamicClassExp = parseMustacheWithContext(dynamicClass).result
1076
+ const staticStyleExp = parseMustacheWithContext(staticStyle).result
1077
+ const dynamicStyleExp = parseMustacheWithContext(dynamicStyle).result
1078
+ const showExp = parseMustacheWithContext(show).result
1079
+
1080
+ addAttrs(el, [{
1081
+ name: 'style',
1082
+ // runtime helper
1083
+ value: `{{this.__getStyle(${staticClassExp}, ${dynamicClassExp}, ${staticStyleExp}, ${dynamicStyleExp}, ${showExp})}}`
1084
+ }])
1085
+ }
1086
+
1087
+ if (staticHoverClass && staticHoverClass !== 'none') {
1088
+ const staticClassExp = parseMustacheWithContext(staticHoverClass).result
1089
+ addAttrs(el, [{
1090
+ name: 'hoverStyle',
1091
+ // runtime helper
1092
+ value: `{{this.__getStyle(${staticClassExp})}}`
1093
+ }])
1094
+ }
1095
+ }
1096
+
1097
+ function processEventReact (el, options, meta) {
1098
+ const eventConfigMap = {}
1099
+ el.attrsList.forEach(function ({ name, value }) {
1100
+ const parsedEvent = config[mode].event.parseEvent(name)
1101
+ if (parsedEvent) {
1102
+ const type = parsedEvent.eventName
1103
+ const parsedFunc = parseFuncStr(value)
1104
+ if (parsedFunc) {
1105
+ if (!eventConfigMap[type]) {
1106
+ eventConfigMap[type] = {
1107
+ configs: []
1108
+ }
1109
+ }
1110
+ eventConfigMap[type].configs.push(Object.assign({ name }, parsedFunc))
1111
+ }
1112
+ }
1113
+ })
1114
+
1115
+ let wrapper
1116
+
1117
+ for (const type in eventConfigMap) {
1118
+ let { configs } = eventConfigMap[type]
1119
+
1120
+ let resultName
1121
+ configs.forEach(({ name }) => {
1122
+ if (name) {
1123
+ // 清空原始事件绑定
1124
+ let has
1125
+ do {
1126
+ has = getAndRemoveAttr(el, name).has
1127
+ } while (has)
1128
+
1129
+ if (!resultName) {
1130
+ // 清除修饰符
1131
+ resultName = name.replace(/\..*/, '')
1132
+ }
1133
+ }
1134
+ })
1135
+ configs = configs.map((item) => {
1136
+ return item.expStr
1137
+ })
1138
+ const name = resultName || config[mode].event.getEvent(type)
1139
+ const value = `{{(e)=>this.__invoke(e, [${configs}])}}`
1140
+ addAttrs(el, [
1141
+ {
1142
+ name,
1143
+ value
1144
+ }
1145
+ ])
1146
+ // 非button的情况下,press/longPress时间需要包裹TouchableWithoutFeedback进行响应,后续可支持配置
1147
+ // if ((type === 'press' || type === 'longPress') && el.tag !== 'mpx-button') {
1148
+ // if (!wrapper) {
1149
+ // wrapper = createASTElement('TouchableWithoutFeedback')
1150
+ // wrapper.isBuiltIn = true
1151
+ // processBuiltInComponents(wrapper, meta)
1152
+ // }
1153
+ // addAttrs(el, [
1154
+ // {
1155
+ // name,
1156
+ // value
1157
+ // }
1158
+ // ])
1159
+ // } else {
1160
+ // addAttrs(el, [
1161
+ // {
1162
+ // name,
1163
+ // value
1164
+ // }
1165
+ // ])
1166
+ // }
1167
+ }
1168
+
1169
+ if (wrapper) {
1170
+ replaceNode(el, wrapper, true)
1171
+ addChild(wrapper, el)
1172
+ processAttrs(wrapper, options)
1173
+ postMoveBaseDirective(wrapper, el)
1174
+ }
1175
+ }
1176
+
1050
1177
  function processEvent (el, options) {
1051
1178
  const eventConfigMap = {}
1052
1179
  el.attrsList.forEach(function ({ name, value }) {
@@ -1057,7 +1184,7 @@ function processEvent (el, options) {
1057
1184
  const modifiers = (parsedEvent.modifier || '').split('.')
1058
1185
  const prefix = parsedEvent.prefix
1059
1186
  // catch 场景下,下发的 eventconfig 里面包含特殊字符,用以运行时的判断
1060
- const extraStr = options.runtimeCompile && prefix === 'catch' ? `, "__mpx_${prefix}"` : ''
1187
+ const extraStr = runtimeCompile && prefix === 'catch' ? `, "__mpx_${prefix}"` : ''
1061
1188
  const parsedFunc = parseFuncStr(value, extraStr)
1062
1189
  if (parsedFunc) {
1063
1190
  if (!eventConfigMap[type]) {
@@ -1178,6 +1305,14 @@ function processEvent (el, options) {
1178
1305
  }
1179
1306
  }
1180
1307
 
1308
+ function processSlotReact (el) {
1309
+ if (el.tag === 'slot') {
1310
+ el.slot = {
1311
+ name: getAndRemoveAttr(el, 'name').val
1312
+ }
1313
+ }
1314
+ }
1315
+
1181
1316
  function wrapMustache (val) {
1182
1317
  return val && !tagRE.test(val) ? `{{${val}}}` : val
1183
1318
  }
@@ -1519,6 +1654,27 @@ function processFor (el) {
1519
1654
  }
1520
1655
  }
1521
1656
 
1657
+ function processRefReact (el, options, meta) {
1658
+ const val = getAndRemoveAttr(el, config[mode].directive.ref).val
1659
+ const type = isComponentNode(el, options) ? 'component' : 'node'
1660
+ if (val) {
1661
+ if (!meta.refs) {
1662
+ meta.refs = []
1663
+ }
1664
+ const all = !!forScopes.length
1665
+ meta.refs.push({
1666
+ key: val,
1667
+ all,
1668
+ type
1669
+ })
1670
+
1671
+ addAttrs(el, [{
1672
+ name: 'ref',
1673
+ value: `{{ this.__getRefVal('${val}') }}`
1674
+ }])
1675
+ }
1676
+ }
1677
+
1522
1678
  function processRef (el, options, meta) {
1523
1679
  const val = getAndRemoveAttr(el, config[mode].directive.ref).val
1524
1680
  const type = isComponentNode(el, options) ? 'component' : 'node'
@@ -1659,6 +1815,19 @@ function postProcessFor (el) {
1659
1815
  }
1660
1816
  }
1661
1817
 
1818
+ function postProcessForReact (el) {
1819
+ if (el.for) {
1820
+ if (el.for.key) {
1821
+ addExp(el, `this.__getWxKey(${el.for.item || 'item'}, ${stringify(el.for.key)})`, false, 'key')
1822
+ addAttrs(el, [{
1823
+ name: 'key',
1824
+ value: el.for.key
1825
+ }])
1826
+ }
1827
+ popForScopes()
1828
+ }
1829
+ }
1830
+
1662
1831
  function evalExp (exp) {
1663
1832
  let result = { success: false }
1664
1833
  try {
@@ -1735,7 +1904,35 @@ function postProcessIf (el) {
1735
1904
  }
1736
1905
  }
1737
1906
 
1738
- function processText (el, meta) {
1907
+ function addIfCondition (el, condition) {
1908
+ if (!el.ifConditions) {
1909
+ el.ifConditions = []
1910
+ }
1911
+ el.ifConditions.push(condition)
1912
+ }
1913
+
1914
+ function postProcessIfReact (el) {
1915
+ let prevNode
1916
+ if (el.if) {
1917
+ addIfCondition(el, {
1918
+ exp: el.if.exp,
1919
+ block: el
1920
+ })
1921
+ } else if (el.elseif || el.else) {
1922
+ prevNode = findPrevNode(el)
1923
+ if (prevNode && prevNode.if) {
1924
+ addIfCondition(prevNode, {
1925
+ exp: el.elseif && el.elseif.exp,
1926
+ block: el
1927
+ })
1928
+ removeNode(el, true)
1929
+ } else {
1930
+ warn$1(`wx:${el.elseif ? `elif="${el.elseif.raw}"` : 'else'} used on element [${el.tag}] without corresponding wx:if.`)
1931
+ }
1932
+ }
1933
+ }
1934
+
1935
+ function processText (el) {
1739
1936
  if (el.type !== 3 || el.isComment) {
1740
1937
  return
1741
1938
  }
@@ -1744,6 +1941,19 @@ function processText (el, meta) {
1744
1941
  addExp(el, parsed.result)
1745
1942
  }
1746
1943
  el.text = parsed.val
1944
+ if (isReact(mode)) {
1945
+ processWrapTextReact(el)
1946
+ }
1947
+ }
1948
+
1949
+ // RN中文字需被Text包裹
1950
+ function processWrapTextReact (el) {
1951
+ const parentTag = el.parent.tag
1952
+ if (parentTag !== 'mpx-text' && parentTag !== 'Text') {
1953
+ const wrapper = createASTElement('Text')
1954
+ replaceNode(el, wrapper, true)
1955
+ addChild(wrapper, el)
1956
+ }
1747
1957
  }
1748
1958
 
1749
1959
  // function injectComputed (el, meta, type, body) {
@@ -1759,13 +1969,11 @@ function processText (el, meta) {
1759
1969
  // }])
1760
1970
  // }
1761
1971
 
1762
- function injectWxs (meta, module, src, options) {
1763
- if (addWxsModule(meta, module, src)) {
1764
- return
1765
- }
1766
- if (options && options.runtimeCompile) {
1972
+ function injectWxs (meta, module, src) {
1973
+ if (runtimeCompile || addWxsModule(meta, module, src)) {
1767
1974
  return
1768
1975
  }
1976
+
1769
1977
  const wxsNode = createASTElement(config[mode].wxs.tag, [
1770
1978
  {
1771
1979
  name: config[mode].wxs.module,
@@ -1963,7 +2171,11 @@ function processBuiltInComponents (el, meta) {
1963
2171
  }
1964
2172
  const tag = el.tag
1965
2173
  if (!meta.builtInComponentsMap[tag]) {
1966
- meta.builtInComponentsMap[tag] = `${builtInComponentsPrefix}/${mode}/${tag}`
2174
+ if (isReact(mode)) {
2175
+ meta.builtInComponentsMap[tag] = `${builtInComponentsPrefix}/react/${tag}`
2176
+ } else {
2177
+ meta.builtInComponentsMap[tag] = `${builtInComponentsPrefix}/${mode}/${tag}`
2178
+ }
1967
2179
  }
1968
2180
  }
1969
2181
  }
@@ -2026,9 +2238,9 @@ function postProcessAliComponentRootView (el, options, meta) {
2026
2238
  replaceNode(el, componentWrapView, true)
2027
2239
  addChild(componentWrapView, el)
2028
2240
  processAttrs(componentWrapView, options)
2029
- postMoveBaseDirective(componentWrapView, el, options)
2241
+ postMoveBaseDirective(componentWrapView, el)
2030
2242
 
2031
- if (options.runtimeCompile) {
2243
+ if (runtimeCompile) {
2032
2244
  collectDynamicInfo(componentWrapView, options, meta)
2033
2245
  postProcessAttrsDynamic(componentWrapView, config[mode])
2034
2246
  }
@@ -2058,6 +2270,17 @@ function getVirtualHostRoot (options, meta) {
2058
2270
  processElement(rootView, rootView, options, meta)
2059
2271
  return rootView
2060
2272
  }
2273
+ if (isReact(mode) && !hasVirtualHost) {
2274
+ const rootView = createASTElement('view', [
2275
+ {
2276
+ name: 'class',
2277
+ value: `${MPX_ROOT_VIEW} host-${moduleId}`
2278
+ }
2279
+ ])
2280
+ rootView.isRoot = true
2281
+ processElement(rootView, rootView, options, meta)
2282
+ return rootView
2283
+ }
2061
2284
  }
2062
2285
  if (mode === 'web' && ctorType === 'page') {
2063
2286
  return createASTElement('page')
@@ -2091,14 +2314,14 @@ function processShow (el, options, root) {
2091
2314
  value: show
2092
2315
  }])
2093
2316
  } else {
2094
- if (options.runtimeCompile) {
2317
+ if (runtimeCompile) {
2095
2318
  processShowStyleDynamic(el, show)
2096
2319
  } else {
2097
2320
  processShowStyle(el, show)
2098
2321
  }
2099
2322
  }
2100
2323
  } else {
2101
- if (options.runtimeCompile) {
2324
+ if (runtimeCompile) {
2102
2325
  processShowStyleDynamic(el, show)
2103
2326
  } else {
2104
2327
  processShowStyle(el, show)
@@ -2133,7 +2356,7 @@ function postProcessTemplate (el) {
2133
2356
  }
2134
2357
  }
2135
2358
 
2136
- const isValidMode = makeMap('wx,ali,swan,tt,qq,web,qa,jd,dd,tenon,noMode')
2359
+ const isValidMode = makeMap('wx,ali,swan,tt,qq,web,qa,jd,dd,tenon,ios,android,noMode')
2137
2360
 
2138
2361
  function isValidModeP (i) {
2139
2362
  return isValidMode(i[0] === '_' ? i.slice(1) : i)
@@ -2241,7 +2464,7 @@ function processInjectWxs (el, meta, options) {
2241
2464
  if (el.injectWxsProps && el.injectWxsProps.length) {
2242
2465
  el.injectWxsProps.forEach((injectWxsProp) => {
2243
2466
  const { injectWxsPath, injectWxsModuleName } = injectWxsProp
2244
- injectWxs(meta, injectWxsModuleName, injectWxsPath, options)
2467
+ injectWxs(meta, injectWxsModuleName, injectWxsPath)
2245
2468
  })
2246
2469
  }
2247
2470
  }
@@ -2261,6 +2484,12 @@ function processMpxTagName (el) {
2261
2484
  }
2262
2485
  }
2263
2486
 
2487
+ function postProcessComponent (el, options) {
2488
+ if (isComponentNode(el, options)) {
2489
+ el.isComponent = true
2490
+ }
2491
+ }
2492
+
2264
2493
  function processElement (el, root, options, meta) {
2265
2494
  processAtMode(el)
2266
2495
  // 如果已经标记了这个元素要被清除,直接return跳过后续处理步骤
@@ -2293,6 +2522,21 @@ function processElement (el, root, options, meta) {
2293
2522
  return
2294
2523
  }
2295
2524
 
2525
+ if (isReact(mode)) {
2526
+ // 收集内建组件
2527
+ processBuiltInComponents(el, meta)
2528
+ // 预处理代码维度条件编译
2529
+ processIf(el)
2530
+ processFor(el)
2531
+ processRefReact(el, options, meta)
2532
+ processStyleReact(el)
2533
+ processEventReact(el, options, meta)
2534
+ processComponentIs(el, options)
2535
+ processSlotReact(el)
2536
+ processAttrs(el, options)
2537
+ return
2538
+ }
2539
+
2296
2540
  const pass = isNative || processTemplate(el) || processingTemplate
2297
2541
 
2298
2542
  // 仅ali平台需要scoped模拟样式隔离
@@ -2307,7 +2551,7 @@ function processElement (el, root, options, meta) {
2307
2551
  processIf(el)
2308
2552
  processFor(el)
2309
2553
  processRef(el, options, meta)
2310
- if (options.runtimeCompile) {
2554
+ if (runtimeCompile) {
2311
2555
  processClassDynamic(el, meta)
2312
2556
  processStyleDynamic(el, meta)
2313
2557
  } else {
@@ -2334,16 +2578,23 @@ function closeElement (el, meta, options) {
2334
2578
  postProcessIf(el)
2335
2579
  return
2336
2580
  }
2581
+ if (isReact(mode)) {
2582
+ postProcessForReact(el)
2583
+ postProcessIfReact(el)
2584
+ // flag component for react
2585
+ postProcessComponent(el, options)
2586
+ return
2587
+ }
2337
2588
  const pass = isNative || postProcessTemplate(el) || processingTemplate
2338
2589
  postProcessWxs(el, meta)
2339
2590
  if (!pass) {
2340
2591
  if (isComponentNode(el, options) && !hasVirtualHost && mode === 'ali') {
2341
2592
  postProcessAliComponentRootView(el, options, meta)
2342
2593
  }
2343
- postProcessComponentIs(el, options)
2594
+ postProcessComponentIs(el)
2344
2595
  }
2345
2596
 
2346
- if (options.runtimeCompile) {
2597
+ if (runtimeCompile) {
2347
2598
  postProcessForDynamic(el, config[mode])
2348
2599
  postProcessIfDynamic(el, config[mode])
2349
2600
  postProcessAttrsDynamic(el, config[mode])
@@ -2386,7 +2637,7 @@ function cloneAttrsList (attrsList) {
2386
2637
  })
2387
2638
  }
2388
2639
 
2389
- function postProcessComponentIs (el, options) {
2640
+ function postProcessComponentIs (el) {
2390
2641
  if (el.is && el.components) {
2391
2642
  let tempNode
2392
2643
  if (el.for || el.if || el.elseif || el.else) {
@@ -2395,7 +2646,7 @@ function postProcessComponentIs (el, options) {
2395
2646
  tempNode = getTempNode()
2396
2647
  }
2397
2648
  replaceNode(el, tempNode, true)
2398
- postMoveBaseDirective(tempNode, el, options)
2649
+ postMoveBaseDirective(tempNode, el)
2399
2650
 
2400
2651
  el.components.forEach(function (component) {
2401
2652
  const newChild = createASTElement(component, cloneAttrsList(el.attrsList), tempNode)
@@ -0,0 +1,95 @@
1
+ const isValidIdentifierStr = require('../utils/is-valid-identifier-str')
2
+
3
+ function genIf (node) {
4
+ node.ifProcessed = true
5
+ return genIfConditions(node.ifConditions.slice())
6
+ }
7
+
8
+ function genIfConditions (conditions) {
9
+ if (!conditions.length) return 'null'
10
+ const condition = conditions.shift()
11
+ if (condition.exp) {
12
+ return `(${condition.exp})?${genNode(condition.block)}:${genIfConditions(conditions)}`
13
+ } else {
14
+ return genNode(condition.block)
15
+ }
16
+ }
17
+
18
+ function genFor (node) {
19
+ node.forProcessed = true
20
+ const index = node.for.index || 'index'
21
+ const item = node.for.item || 'item'
22
+ return `_i(${node.for.exp}, function(${item},${index}){return ${genNode(node)}})`
23
+ }
24
+
25
+ const s = JSON.stringify
26
+
27
+ function mapAttrName (name) {
28
+ if (name === 'class') return 'className'
29
+ if (!isValidIdentifierStr(name)) return s(name)
30
+ return name
31
+ }
32
+
33
+ function genNode (node) {
34
+ let exp = ''
35
+ if (node) {
36
+ if (node.type === 3) {
37
+ if (!node.isComment) {
38
+ if (node.exps) {
39
+ exp += `${node.exps[0].exp}`
40
+ } else {
41
+ exp += `${s(node.text)}`
42
+ }
43
+ }
44
+ }
45
+ if (node.type === 1) {
46
+ if (node.tag !== 'temp-node') {
47
+ if (node.for && !node.forProcessed) {
48
+ exp += genFor(node)
49
+ } else if (node.if && !node.ifProcessed) {
50
+ exp += genIf(node)
51
+ } else {
52
+ const attrExpMap = (node.exps || []).reduce((map, { exp, attrName }) => {
53
+ if (attrName) {
54
+ map[attrName] = exp
55
+ }
56
+ return map
57
+ }, {})
58
+ if (node.slot) {
59
+ const name = node.slot.name
60
+ exp += `__getSlot(${name ? s(name) : ''})`
61
+ } else {
62
+ exp += `createElement(${node.isComponent || node.isBuiltIn ? `components[${node.is || s(node.tag)}]` : `getNativeComponent(${s(node.tag)})`}`
63
+ if (node.isRoot) {
64
+ exp += `, Object.assign({}, rootProps, {style: [${attrExpMap.style}, rootProps.style]})`
65
+ } else if (node.attrsList.length) {
66
+ const attrs = []
67
+ node.attrsList && node.attrsList.forEach(({ name, value }) => {
68
+ const attrExp = attrExpMap[name] ? attrExpMap[name] : s(value)
69
+ attrs.push(`${mapAttrName(name)}: ${attrExp}`)
70
+ })
71
+ exp += `, { ${attrs.join(', ')} }`
72
+ } else {
73
+ exp += ', null'
74
+ }
75
+
76
+ if (!node.unary && node.children.length) {
77
+ exp += ','
78
+ node.children.forEach(function (child, index) {
79
+ exp += `${index === 0 ? '' : ','}${genNode(child)}`
80
+ })
81
+ }
82
+ exp += ')'
83
+ }
84
+ }
85
+ } else {
86
+ node.children.forEach(function (child, index) {
87
+ exp += `${index === 0 ? '' : ','}${genNode(child)}`
88
+ })
89
+ }
90
+ }
91
+ }
92
+ return exp
93
+ }
94
+
95
+ module.exports = genNode