@mpxjs/webpack-plugin 2.9.39 → 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 +293 -38
  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
@@ -964,8 +969,12 @@ function processComponentIs (el, options) {
964
969
  return
965
970
  }
966
971
 
967
- const isInRange = makeMap(getAndRemoveAttr(el, 'range').val || '')
968
- el.components = (options.usingComponents || []).filter(i => isInRange(i))
972
+ const range = getAndRemoveAttr(el, 'range').val
973
+ const isInRange = makeMap(range || '')
974
+ el.components = (options.usingComponents || []).filter(i => {
975
+ if (!range) return true
976
+ return isInRange(i)
977
+ })
969
978
  if (!el.components.length) {
970
979
  warn$1('Component in which <component> tag is used must have a non blank usingComponents field')
971
980
  }
@@ -1043,6 +1052,128 @@ function stringifyWithResolveComputed (modelValue) {
1043
1052
  return result.join('+')
1044
1053
  }
1045
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
+
1046
1177
  function processEvent (el, options) {
1047
1178
  const eventConfigMap = {}
1048
1179
  el.attrsList.forEach(function ({ name, value }) {
@@ -1053,7 +1184,7 @@ function processEvent (el, options) {
1053
1184
  const modifiers = (parsedEvent.modifier || '').split('.')
1054
1185
  const prefix = parsedEvent.prefix
1055
1186
  // catch 场景下,下发的 eventconfig 里面包含特殊字符,用以运行时的判断
1056
- const extraStr = options.runtimeCompile && prefix === 'catch' ? `, "__mpx_${prefix}"` : ''
1187
+ const extraStr = runtimeCompile && prefix === 'catch' ? `, "__mpx_${prefix}"` : ''
1057
1188
  const parsedFunc = parseFuncStr(value, extraStr)
1058
1189
  if (parsedFunc) {
1059
1190
  if (!eventConfigMap[type]) {
@@ -1174,6 +1305,14 @@ function processEvent (el, options) {
1174
1305
  }
1175
1306
  }
1176
1307
 
1308
+ function processSlotReact (el) {
1309
+ if (el.tag === 'slot') {
1310
+ el.slot = {
1311
+ name: getAndRemoveAttr(el, 'name').val
1312
+ }
1313
+ }
1314
+ }
1315
+
1177
1316
  function wrapMustache (val) {
1178
1317
  return val && !tagRE.test(val) ? `{{${val}}}` : val
1179
1318
  }
@@ -1515,6 +1654,27 @@ function processFor (el) {
1515
1654
  }
1516
1655
  }
1517
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
+
1518
1678
  function processRef (el, options, meta) {
1519
1679
  const val = getAndRemoveAttr(el, config[mode].directive.ref).val
1520
1680
  const type = isComponentNode(el, options) ? 'component' : 'node'
@@ -1655,6 +1815,19 @@ function postProcessFor (el) {
1655
1815
  }
1656
1816
  }
1657
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
+
1658
1831
  function evalExp (exp) {
1659
1832
  let result = { success: false }
1660
1833
  try {
@@ -1731,7 +1904,35 @@ function postProcessIf (el) {
1731
1904
  }
1732
1905
  }
1733
1906
 
1734
- 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) {
1735
1936
  if (el.type !== 3 || el.isComment) {
1736
1937
  return
1737
1938
  }
@@ -1740,6 +1941,19 @@ function processText (el, meta) {
1740
1941
  addExp(el, parsed.result)
1741
1942
  }
1742
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
+ }
1743
1957
  }
1744
1958
 
1745
1959
  // function injectComputed (el, meta, type, body) {
@@ -1755,13 +1969,11 @@ function processText (el, meta) {
1755
1969
  // }])
1756
1970
  // }
1757
1971
 
1758
- function injectWxs (meta, module, src, options) {
1759
- if (addWxsModule(meta, module, src)) {
1760
- return
1761
- }
1762
- if (options && options.runtimeCompile) {
1972
+ function injectWxs (meta, module, src) {
1973
+ if (runtimeCompile || addWxsModule(meta, module, src)) {
1763
1974
  return
1764
1975
  }
1976
+
1765
1977
  const wxsNode = createASTElement(config[mode].wxs.tag, [
1766
1978
  {
1767
1979
  name: config[mode].wxs.module,
@@ -1959,7 +2171,11 @@ function processBuiltInComponents (el, meta) {
1959
2171
  }
1960
2172
  const tag = el.tag
1961
2173
  if (!meta.builtInComponentsMap[tag]) {
1962
- 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
+ }
1963
2179
  }
1964
2180
  }
1965
2181
  }
@@ -2022,9 +2238,9 @@ function postProcessAliComponentRootView (el, options, meta) {
2022
2238
  replaceNode(el, componentWrapView, true)
2023
2239
  addChild(componentWrapView, el)
2024
2240
  processAttrs(componentWrapView, options)
2025
- postMoveBaseDirective(componentWrapView, el, options)
2241
+ postMoveBaseDirective(componentWrapView, el)
2026
2242
 
2027
- if (options.runtimeCompile) {
2243
+ if (runtimeCompile) {
2028
2244
  collectDynamicInfo(componentWrapView, options, meta)
2029
2245
  postProcessAttrsDynamic(componentWrapView, config[mode])
2030
2246
  }
@@ -2054,6 +2270,17 @@ function getVirtualHostRoot (options, meta) {
2054
2270
  processElement(rootView, rootView, options, meta)
2055
2271
  return rootView
2056
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
+ }
2057
2284
  }
2058
2285
  if (mode === 'web' && ctorType === 'page') {
2059
2286
  return createASTElement('page')
@@ -2087,14 +2314,14 @@ function processShow (el, options, root) {
2087
2314
  value: show
2088
2315
  }])
2089
2316
  } else {
2090
- if (options.runtimeCompile) {
2317
+ if (runtimeCompile) {
2091
2318
  processShowStyleDynamic(el, show)
2092
2319
  } else {
2093
2320
  processShowStyle(el, show)
2094
2321
  }
2095
2322
  }
2096
2323
  } else {
2097
- if (options.runtimeCompile) {
2324
+ if (runtimeCompile) {
2098
2325
  processShowStyleDynamic(el, show)
2099
2326
  } else {
2100
2327
  processShowStyle(el, show)
@@ -2129,7 +2356,7 @@ function postProcessTemplate (el) {
2129
2356
  }
2130
2357
  }
2131
2358
 
2132
- 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')
2133
2360
 
2134
2361
  function isValidModeP (i) {
2135
2362
  return isValidMode(i[0] === '_' ? i.slice(1) : i)
@@ -2237,7 +2464,7 @@ function processInjectWxs (el, meta, options) {
2237
2464
  if (el.injectWxsProps && el.injectWxsProps.length) {
2238
2465
  el.injectWxsProps.forEach((injectWxsProp) => {
2239
2466
  const { injectWxsPath, injectWxsModuleName } = injectWxsProp
2240
- injectWxs(meta, injectWxsModuleName, injectWxsPath, options)
2467
+ injectWxs(meta, injectWxsModuleName, injectWxsPath)
2241
2468
  })
2242
2469
  }
2243
2470
  }
@@ -2257,6 +2484,12 @@ function processMpxTagName (el) {
2257
2484
  }
2258
2485
  }
2259
2486
 
2487
+ function postProcessComponent (el, options) {
2488
+ if (isComponentNode(el, options)) {
2489
+ el.isComponent = true
2490
+ }
2491
+ }
2492
+
2260
2493
  function processElement (el, root, options, meta) {
2261
2494
  processAtMode(el)
2262
2495
  // 如果已经标记了这个元素要被清除,直接return跳过后续处理步骤
@@ -2289,6 +2522,21 @@ function processElement (el, root, options, meta) {
2289
2522
  return
2290
2523
  }
2291
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
+
2292
2540
  const pass = isNative || processTemplate(el) || processingTemplate
2293
2541
 
2294
2542
  // 仅ali平台需要scoped模拟样式隔离
@@ -2303,7 +2551,7 @@ function processElement (el, root, options, meta) {
2303
2551
  processIf(el)
2304
2552
  processFor(el)
2305
2553
  processRef(el, options, meta)
2306
- if (options.runtimeCompile) {
2554
+ if (runtimeCompile) {
2307
2555
  processClassDynamic(el, meta)
2308
2556
  processStyleDynamic(el, meta)
2309
2557
  } else {
@@ -2330,16 +2578,23 @@ function closeElement (el, meta, options) {
2330
2578
  postProcessIf(el)
2331
2579
  return
2332
2580
  }
2581
+ if (isReact(mode)) {
2582
+ postProcessForReact(el)
2583
+ postProcessIfReact(el)
2584
+ // flag component for react
2585
+ postProcessComponent(el, options)
2586
+ return
2587
+ }
2333
2588
  const pass = isNative || postProcessTemplate(el) || processingTemplate
2334
2589
  postProcessWxs(el, meta)
2335
2590
  if (!pass) {
2336
2591
  if (isComponentNode(el, options) && !hasVirtualHost && mode === 'ali') {
2337
2592
  postProcessAliComponentRootView(el, options, meta)
2338
2593
  }
2339
- postProcessComponentIs(el, options)
2594
+ postProcessComponentIs(el)
2340
2595
  }
2341
2596
 
2342
- if (options.runtimeCompile) {
2597
+ if (runtimeCompile) {
2343
2598
  postProcessForDynamic(el, config[mode])
2344
2599
  postProcessIfDynamic(el, config[mode])
2345
2600
  postProcessAttrsDynamic(el, config[mode])
@@ -2382,7 +2637,7 @@ function cloneAttrsList (attrsList) {
2382
2637
  })
2383
2638
  }
2384
2639
 
2385
- function postProcessComponentIs (el, options) {
2640
+ function postProcessComponentIs (el) {
2386
2641
  if (el.is && el.components) {
2387
2642
  let tempNode
2388
2643
  if (el.for || el.if || el.elseif || el.else) {
@@ -2391,7 +2646,7 @@ function postProcessComponentIs (el, options) {
2391
2646
  tempNode = getTempNode()
2392
2647
  }
2393
2648
  replaceNode(el, tempNode, true)
2394
- postMoveBaseDirective(tempNode, el, options)
2649
+ postMoveBaseDirective(tempNode, el)
2395
2650
 
2396
2651
  el.components.forEach(function (component) {
2397
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