@mpxjs/webpack-plugin 2.9.69 → 2.9.70-alpha.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 (138) hide show
  1. package/README.md +1 -1
  2. package/lib/config.js +14 -0
  3. package/lib/dependencies/AddEntryDependency.js +24 -0
  4. package/lib/dependencies/ResolveDependency.js +5 -0
  5. package/lib/index.js +38 -7
  6. package/lib/json-compiler/helper.js +3 -3
  7. package/lib/loader.js +53 -0
  8. package/lib/platform/template/wx/component-config/button.js +14 -2
  9. package/lib/platform/template/wx/component-config/image.js +4 -0
  10. package/lib/platform/template/wx/component-config/input.js +5 -1
  11. package/lib/platform/template/wx/component-config/rich-text.js +4 -0
  12. package/lib/platform/template/wx/component-config/scroll-view.js +4 -0
  13. package/lib/platform/template/wx/component-config/swiper.js +1 -1
  14. package/lib/platform/template/wx/component-config/switch.js +4 -0
  15. package/lib/platform/template/wx/component-config/text.js +4 -0
  16. package/lib/platform/template/wx/component-config/textarea.js +6 -1
  17. package/lib/platform/template/wx/component-config/view.js +4 -0
  18. package/lib/platform/template/wx/index.js +127 -1
  19. package/lib/react/processTemplate.js +3 -0
  20. package/lib/resolve-loader.js +4 -1
  21. package/lib/runtime/components/react/context.ts +4 -0
  22. package/lib/runtime/components/react/dist/context.js +1 -0
  23. package/lib/runtime/components/react/dist/event.config.js +24 -24
  24. package/lib/runtime/components/react/dist/getInnerListeners.js +183 -165
  25. package/lib/runtime/components/react/dist/mpx-button.jsx +35 -42
  26. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +30 -12
  27. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +13 -19
  28. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +29 -38
  29. package/lib/runtime/components/react/dist/mpx-form.jsx +16 -19
  30. package/lib/runtime/components/react/dist/mpx-icon.jsx +8 -16
  31. package/lib/runtime/components/react/dist/mpx-image.jsx +291 -0
  32. package/lib/runtime/components/react/dist/mpx-input.jsx +54 -27
  33. package/lib/runtime/components/react/dist/mpx-label.jsx +15 -22
  34. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +13 -16
  35. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +13 -13
  36. package/lib/runtime/components/react/dist/mpx-navigator.jsx +2 -4
  37. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +6 -2
  38. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +5 -3
  39. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +6 -2
  40. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +6 -2
  41. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +6 -2
  42. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +10 -15
  43. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +39 -0
  44. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +110 -97
  45. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +32 -29
  46. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -19
  47. package/lib/runtime/components/react/dist/mpx-radio.jsx +27 -42
  48. package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
  49. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +63 -0
  50. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +6 -4
  51. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +47 -41
  52. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
  53. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +4 -2
  54. package/lib/runtime/components/react/dist/mpx-swiper.jsx +606 -0
  55. package/lib/runtime/components/react/dist/mpx-switch.jsx +20 -10
  56. package/lib/runtime/components/react/dist/mpx-text.jsx +11 -10
  57. package/lib/runtime/components/react/dist/mpx-textarea.jsx +8 -3
  58. package/lib/runtime/components/react/dist/mpx-view.jsx +29 -44
  59. package/lib/runtime/components/react/dist/mpx-web-view.jsx +105 -42
  60. package/lib/runtime/components/react/dist/pickerFaces.js +12 -6
  61. package/lib/runtime/components/react/dist/pickerVIewContext.js +9 -0
  62. package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
  63. package/lib/runtime/components/react/dist/{pickerOverlay.jsx → pickerViewOverlay.jsx} +5 -3
  64. package/lib/runtime/components/react/dist/useAnimationHooks.js +35 -9
  65. package/lib/runtime/components/react/dist/utils.jsx +20 -24
  66. package/lib/runtime/components/react/getInnerListeners.ts +35 -28
  67. package/lib/runtime/components/react/mpx-button.tsx +55 -36
  68. package/lib/runtime/components/react/mpx-canvas/index.tsx +2 -2
  69. package/lib/runtime/components/react/mpx-checkbox-group.tsx +13 -12
  70. package/lib/runtime/components/react/mpx-checkbox.tsx +28 -28
  71. package/lib/runtime/components/react/mpx-form.tsx +10 -8
  72. package/lib/runtime/components/react/mpx-icon.tsx +10 -15
  73. package/lib/runtime/components/react/mpx-image.tsx +396 -0
  74. package/lib/runtime/components/react/mpx-input.tsx +61 -33
  75. package/lib/runtime/components/react/mpx-label.tsx +14 -13
  76. package/lib/runtime/components/react/mpx-movable-area.tsx +8 -7
  77. package/lib/runtime/components/react/mpx-movable-view.tsx +1 -1
  78. package/lib/runtime/components/react/mpx-picker/date.tsx +5 -2
  79. package/lib/runtime/components/react/mpx-picker/index.tsx +3 -2
  80. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +5 -2
  81. package/lib/runtime/components/react/mpx-picker/region.tsx +5 -2
  82. package/lib/runtime/components/react/mpx-picker/selector.tsx +5 -2
  83. package/lib/runtime/components/react/mpx-picker/time.tsx +10 -15
  84. package/lib/runtime/components/react/mpx-picker/type.ts +48 -43
  85. package/lib/runtime/components/react/mpx-picker-view-column.tsx +4 -1
  86. package/lib/runtime/components/react/mpx-picker-view.tsx +7 -1
  87. package/lib/runtime/components/react/mpx-radio-group.tsx +11 -12
  88. package/lib/runtime/components/react/mpx-radio.tsx +26 -29
  89. package/lib/runtime/components/react/mpx-scroll-view.tsx +32 -30
  90. package/lib/runtime/components/react/mpx-simple-text.tsx +18 -0
  91. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +4 -2
  92. package/lib/runtime/components/react/mpx-swiper-item.tsx +3 -2
  93. package/lib/runtime/components/react/mpx-switch.tsx +10 -8
  94. package/lib/runtime/components/react/mpx-text.tsx +6 -2
  95. package/lib/runtime/components/react/mpx-view.tsx +37 -45
  96. package/lib/runtime/components/react/mpx-web-view.tsx +25 -15
  97. package/lib/runtime/components/react/types/global.d.ts +1 -16
  98. package/lib/runtime/components/react/utils.tsx +24 -24
  99. package/lib/runtime/components/tenon/getInnerListeners.js +334 -0
  100. package/lib/runtime/components/tenon/tenon-button.vue +309 -0
  101. package/lib/runtime/components/tenon/tenon-image.vue +66 -0
  102. package/lib/runtime/components/tenon/tenon-input.vue +171 -0
  103. package/lib/runtime/components/tenon/tenon-rich-text.vue +26 -0
  104. package/lib/runtime/components/tenon/tenon-scroll-view.vue +127 -0
  105. package/lib/runtime/components/tenon/tenon-switch.vue +96 -0
  106. package/lib/runtime/components/tenon/tenon-text.vue +70 -0
  107. package/lib/runtime/components/tenon/tenon-textarea.vue +86 -0
  108. package/lib/runtime/components/tenon/tenon-view.vue +93 -0
  109. package/lib/runtime/components/web/getInnerListeners.js +6 -6
  110. package/lib/runtime/components/web/mpx-movable-view.vue +334 -344
  111. package/lib/runtime/components/web/mpx-picker-view-column.vue +75 -75
  112. package/lib/runtime/components/web/mpx-picker.vue +382 -385
  113. package/lib/runtime/components/web/mpx-web-view.vue +162 -162
  114. package/lib/runtime/optionProcessor.js +7 -16
  115. package/lib/runtime/optionProcessor.tenon.js +84 -0
  116. package/lib/runtime/utils.js +2 -0
  117. package/lib/style-compiler/index.js +1 -1
  118. package/lib/style-compiler/plugins/hm.js +20 -0
  119. package/lib/template-compiler/bind-this.js +7 -2
  120. package/lib/template-compiler/compiler.js +67 -40
  121. package/lib/template-compiler/gen-node-react.js +2 -2
  122. package/lib/tenon/index.js +117 -0
  123. package/lib/tenon/processJSON.js +352 -0
  124. package/lib/tenon/processScript.js +203 -0
  125. package/lib/tenon/processStyles.js +21 -0
  126. package/lib/tenon/processTemplate.js +126 -0
  127. package/lib/tenon/script-helper.js +223 -0
  128. package/lib/utils/env.js +6 -1
  129. package/lib/utils/get-relative-path.js +25 -0
  130. package/package.json +7 -3
  131. package/LICENSE +0 -433
  132. package/lib/runtime/components/react/dist/mpx-image/index.jsx +0 -226
  133. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -7
  134. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +0 -478
  135. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +0 -68
  136. package/lib/runtime/components/react/dist/mpx-swiper/type.js +0 -1
  137. package/lib/runtime/components/react/mpx-image/index.tsx +0 -345
  138. package/lib/runtime/components/react/mpx-image/svg.tsx +0 -22
@@ -15,7 +15,7 @@ const { isNonPhrasingTag } = require('../utils/dom-tag-config')
15
15
  const setBaseWxml = require('../runtime-render/base-wxml')
16
16
  const { parseExp } = require('./parse-exps')
17
17
  const shallowStringify = require('../utils/shallow-stringify')
18
- const { isReact, isWeb } = require('../utils/env')
18
+ const { isReact, isWeb, isTenon } = require('../utils/env')
19
19
 
20
20
  const no = function () {
21
21
  return false
@@ -725,7 +725,7 @@ function parse (template, options) {
725
725
  stack.push(element)
726
726
  } else {
727
727
  element.unary = true
728
- closeElement(element, meta, options)
728
+ closeElement(element, options, meta)
729
729
  }
730
730
  },
731
731
 
@@ -740,7 +740,7 @@ function parse (template, options) {
740
740
  // pop stack
741
741
  stack.pop()
742
742
  currentParent = stack[stack.length - 1]
743
- closeElement(element, meta, options)
743
+ closeElement(element, options, meta)
744
744
  }
745
745
  },
746
746
 
@@ -765,7 +765,7 @@ function parse (template, options) {
765
765
  parent: currentParent
766
766
  }
767
767
  children.push(el)
768
- runtimeCompile ? processTextDynamic(el) : processText(el)
768
+ runtimeCompile ? processTextDynamic(el) : processText(el, options, meta)
769
769
  }
770
770
  },
771
771
  comment: function comment (text) {
@@ -1164,7 +1164,7 @@ function processEventReact (el) {
1164
1164
  configs: []
1165
1165
  }
1166
1166
  }
1167
- eventConfigMap[type].configs.push(Object.assign({ name }, parsedFunc))
1167
+ eventConfigMap[type].configs.push(Object.assign({ name, value }, parsedFunc))
1168
1168
  }
1169
1169
  }
1170
1170
  })
@@ -1205,26 +1205,31 @@ function processEventReact (el) {
1205
1205
 
1206
1206
  // let wrapper
1207
1207
  for (const type in eventConfigMap) {
1208
- let { configs } = eventConfigMap[type]
1209
- configs.forEach(({ name }) => {
1210
- if (name) {
1211
- // 清空原始事件绑定
1212
- let has
1213
- do {
1214
- has = getAndRemoveAttr(el, name).has
1215
- } while (has)
1216
- }
1217
- })
1218
- configs = configs.map((item) => {
1219
- return item.expStr
1220
- })
1221
- const value = `{{(e)=>this.__invoke(e, [${configs}])}}`
1222
- addAttrs(el, [
1223
- {
1224
- name: type,
1225
- value
1226
- }
1227
- ])
1208
+ const { configs } = eventConfigMap[type]
1209
+ if (!configs.length) continue
1210
+ const needBind = configs.length > 1 || configs[0].hasArgs
1211
+ if (needBind) {
1212
+ configs.forEach(({ name }) => {
1213
+ if (name) {
1214
+ // 清空原始事件绑定
1215
+ let has
1216
+ do {
1217
+ has = getAndRemoveAttr(el, name).has
1218
+ } while (has)
1219
+ }
1220
+ })
1221
+ const value = `{{(e)=>this.__invoke(e, [${configs.map(item => item.expStr)}])}}`
1222
+ addAttrs(el, [
1223
+ {
1224
+ name: type,
1225
+ value
1226
+ }
1227
+ ])
1228
+ } else {
1229
+ const { name, value } = configs[0]
1230
+ modifyAttr(el, name, `{{${value}}}`)
1231
+ }
1232
+
1228
1233
  // 非button的情况下,press/longPress时间需要包裹TouchableWithoutFeedback进行响应,后续可支持配置
1229
1234
  // if ((type === 'press' || type === 'longPress') && el.tag !== 'mpx-button') {
1230
1235
  // if (!wrapper) {
@@ -2036,7 +2041,7 @@ function postProcessIfReact (el) {
2036
2041
  }
2037
2042
  }
2038
2043
 
2039
- function processText (el) {
2044
+ function processText (el, options, meta) {
2040
2045
  if (el.type !== 3 || el.isComment) {
2041
2046
  return
2042
2047
  }
@@ -2046,17 +2051,32 @@ function processText (el) {
2046
2051
  }
2047
2052
  el.text = parsed.val
2048
2053
  if (isReact(mode)) {
2049
- processWrapTextReact(el)
2054
+ processWrapTextReact(el, options, meta)
2050
2055
  }
2051
2056
  }
2052
2057
 
2053
- // RN中文字需被Text包裹
2054
- function processWrapTextReact (el) {
2055
- const parentTag = el.parent.tag
2058
+ // RN中裸文字需被Text包裹
2059
+ // 为了批量修改Text默认属性,如allowFontScaling,使用mpx-simple-text进行包裹
2060
+ function processWrapTextReact (el, options, meta) {
2061
+ const parent = el.parent
2062
+ const parentTag = parent.tag
2056
2063
  if (parentTag !== 'mpx-text' && parentTag !== 'Text' && parentTag !== 'wxs') {
2057
- const wrapper = createASTElement('Text')
2064
+ const wrapper = createASTElement('mpx-simple-text')
2065
+ wrapper.isBuiltIn = true
2066
+ const dataSetAttrs = []
2067
+ parent.attrsList.forEach(({ name, value }) => {
2068
+ if (/^data-/.test(name)) {
2069
+ dataSetAttrs.push({
2070
+ name,
2071
+ value
2072
+ })
2073
+ }
2074
+ })
2075
+ addAttrs(wrapper, dataSetAttrs)
2058
2076
  replaceNode(el, wrapper, true)
2059
2077
  addChild(wrapper, el)
2078
+ processBuiltInComponents(wrapper, meta)
2079
+ processAttrs(wrapper, options)
2060
2080
  }
2061
2081
  }
2062
2082
 
@@ -2074,7 +2094,7 @@ function processWrapTextReact (el) {
2074
2094
  // }
2075
2095
 
2076
2096
  function injectWxs (meta, module, src) {
2077
- if (runtimeCompile || addWxsModule(meta, module, src) || isReact(mode) || isWeb(mode)) {
2097
+ if (runtimeCompile || addWxsModule(meta, module, src) || isReact(mode) || isWeb(mode) || isTenon(mode)) {
2078
2098
  return
2079
2099
  }
2080
2100
 
@@ -2361,12 +2381,11 @@ function getVirtualHostRoot (options, meta) {
2361
2381
  {
2362
2382
  name: 'class',
2363
2383
  value: `${MPX_ROOT_VIEW} host-${moduleId}`
2384
+ },
2385
+ {
2386
+ name: 'ishost',
2387
+ value: '{{true}}'
2364
2388
  }
2365
- // todo 运行时通过root标识确定是否合并rootProps
2366
- // {
2367
- // name: 'is-root',
2368
- // value: '{{true}}'
2369
- // }
2370
2389
  ])
2371
2390
  processElement(rootView, rootView, options, meta)
2372
2391
  return rootView
@@ -2612,6 +2631,15 @@ function processElement (el, root, options, meta) {
2612
2631
  processComponentGenericsWeb(el, options, meta)
2613
2632
  return
2614
2633
  }
2634
+ if (mode === 'tenon') {
2635
+ // 收集内建组件
2636
+ processBuiltInComponents(el, meta)
2637
+ // 预处理代码维度条件编译
2638
+ processIfWeb(el)
2639
+ // processWebExternalClassesHack(el, options)
2640
+ // processComponentGenericsForWeb(el, options, meta)
2641
+ return
2642
+ }
2615
2643
 
2616
2644
  if (isReact(mode)) {
2617
2645
  const pass = isReactComponent(el, options)
@@ -2663,11 +2691,11 @@ function processElement (el, root, options, meta) {
2663
2691
  processAttrs(el, options)
2664
2692
  }
2665
2693
 
2666
- function closeElement (el, meta, options) {
2694
+ function closeElement (el, options, meta) {
2667
2695
  postProcessAtMode(el)
2668
2696
  postProcessWxs(el, meta)
2669
2697
 
2670
- if (isWeb(mode)) {
2698
+ if (isWeb(mode) || isTenon(mode)) {
2671
2699
  // 处理代码维度条件编译移除死分支
2672
2700
  postProcessIf(el)
2673
2701
  return
@@ -2800,7 +2828,6 @@ function serialize (root) {
2800
2828
  result += node.text
2801
2829
  }
2802
2830
  }
2803
-
2804
2831
  if (node.type === 1) {
2805
2832
  if (node.tag !== 'temp-node') {
2806
2833
  result += '<' + node.tag
@@ -19,7 +19,7 @@ function genFor (node) {
19
19
  node.forProcessed = true
20
20
  const index = node.for.index || 'index'
21
21
  const item = node.for.item || 'item'
22
- return `_i(${node.for.exp}, function(${item},${index}){return ${genNode(node)}})`
22
+ return `this.__iter(${node.for.exp}, function(${item},${index}){return ${genNode(node)}})`
23
23
  }
24
24
 
25
25
  const s = JSON.stringify
@@ -57,7 +57,7 @@ function genNode (node) {
57
57
  }, {})
58
58
  if (node.slot) {
59
59
  const { name, slot } = node.slot
60
- exp += `__getSlot(${name ? s(name) : ''}${slot ? `, ${s(slot)}` : ''})`
60
+ exp += `this.__getSlot(${name ? s(name) : ''}${slot ? `, ${s(slot)}` : ''})`
61
61
  } else {
62
62
  exp += `createElement(${`getComponent(${node.is || s(node.tag)})`}`
63
63
  if (node.attrsList.length) {
@@ -0,0 +1,117 @@
1
+ const async = require('async')
2
+ const processJSON = require('./processJSON')
3
+ // const processMainScript = require('./processMainScript')
4
+ const processTemplate = require('./processTemplate')
5
+ const processStyles = require('./processStyles')
6
+ const processScript = require('./processScript')
7
+ const RecordLoaderContentDependency = require('../dependencies/RecordLoaderContentDependency')
8
+ const {stringifyRequest} = require('./script-helper')
9
+ const addQuery = require('../utils/add-query')
10
+ const parseRequest = require('../utils/parse-request')
11
+
12
+
13
+
14
+ module.exports = function ({
15
+ parts,
16
+ jsonContent,
17
+ loaderContext,
18
+ pagesMap,
19
+ componentsMap,
20
+ queryObj,
21
+ ctorType,
22
+ srcMode,
23
+ moduleId,
24
+ isProduction,
25
+ hasScoped,
26
+ hasComment,
27
+ isNative,
28
+ usingComponentsInfo,
29
+ componentGenerics,
30
+ autoScope,
31
+ callback
32
+ }) {
33
+
34
+ let output = ''
35
+
36
+
37
+ const mpx = loaderContext.getMpx()
38
+ // const hasComment = parts.template && parts.template.attrs && parts.template.attrs.comments
39
+ // const isNative = false
40
+ const mode = mpx.mode
41
+ // const srcMode = mpx.srcMode
42
+ const env = mpx.env
43
+ const defs = mpx.defs
44
+ const resolveMode = mpx.resolveMode
45
+ // const pagesMap = mpx.pagesMap
46
+ const projectRoot = mpx.projectRoot
47
+
48
+ // 通过RecordLoaderContentDependency和loaderContentCache确保子request不再重复生成loaderContent
49
+ const cacheContent = mpx.loaderContentCache.get(loaderContext.resourcePath)
50
+ if (cacheContent) return callback(null, cacheContent)
51
+ return async.waterfall([
52
+ (callback) => {
53
+ async.parallel([
54
+ (callback) => {
55
+ processTemplate(parts.template, {
56
+ loaderContext,
57
+ hasScoped,
58
+ hasComment,
59
+ isNative,
60
+ srcMode,
61
+ moduleId,
62
+ ctorType,
63
+ usingComponentsInfo,
64
+ componentGenerics
65
+ }, callback)
66
+ },
67
+ (callback) => {
68
+ processStyles(parts.styles, {
69
+ ctorType,
70
+ autoScope,
71
+ moduleId
72
+ }, callback)
73
+ },
74
+ (callback) => {
75
+ processJSON(jsonContent, {
76
+ mode,
77
+ env,
78
+ defs,
79
+ resolveMode,
80
+ loaderContext,
81
+ pagesMap,
82
+ pathHash: mpx.pathHash,
83
+ componentsMap,
84
+ projectRoot
85
+ }, callback)
86
+ }
87
+ ], (err, res) => {
88
+ callback(err, res)
89
+ })
90
+ },
91
+ ([templateRes, stylesRes, jsonRes], callback) => {
92
+ output += templateRes.output
93
+ output += stylesRes.output
94
+ output += jsonRes.output
95
+ processScript(parts.script, {
96
+ loaderContext,
97
+ ctorType,
98
+ srcMode,
99
+ moduleId,
100
+ isProduction,
101
+ componentGenerics,
102
+ jsonConfig: jsonRes.jsonObj,
103
+ outputPath: queryObj.outputPath || '',
104
+ builtInComponentsMap: templateRes.builtInComponentsMap,
105
+ localPagesMap: jsonRes.localPagesMap,
106
+ genericsInfo: templateRes.genericsInfo,
107
+ wxsModuleMap: templateRes.wxsModuleMap,
108
+ localComponentsMap: jsonRes.localComponentsMap
109
+ }, callback)
110
+ }
111
+ ], (err, scriptRes) => {
112
+ if (err) return callback(err)
113
+ output += scriptRes.output
114
+ loaderContext._module.addPresentationalDependency(new RecordLoaderContentDependency(loaderContext.resourcePath, output))
115
+ callback(null, output)
116
+ })
117
+ }
@@ -0,0 +1,352 @@
1
+ const async = require('async')
2
+ const path = require('path')
3
+ const JSON5 = require('json5')
4
+ const loaderUtils = require('loader-utils')
5
+ const parseRequest = require('../utils/parse-request')
6
+ // const toPosix = require('../utils/to-posix')
7
+ const addQuery = require('../utils/add-query')
8
+ const parseComponent = require('../parser')
9
+ const getJSONContent = require('../utils/get-json-content')
10
+ const isUrlRequest = require('../utils/is-url-request')
11
+
12
+ module.exports = function (jsonContent, options, rawCallback) {
13
+ const mode = options.mode
14
+ const env = options.env
15
+ const defs = options.defs
16
+ const loaderContext = options.loaderContext
17
+ const resolveMode = options.resolveMode
18
+ // const pagesMap = options.pagesMap
19
+ const componentsMap = options.componentsMap
20
+ const projectRoot = options.projectRoot
21
+ const pathHash = options.pathHash
22
+ const localPagesMap = {}
23
+ const localComponentsMap = {}
24
+ const buildInfo = loaderContext._module.buildInfo
25
+
26
+ const output = '/* json */\n'
27
+ let jsonObj = {}
28
+ let tabBarMap
29
+ let tabBarStr
30
+ const context = loaderContext.context
31
+
32
+ // const emitWarning = (msg) => {
33
+ // loaderContext.emitWarning(
34
+ // new Error('[json processor][' + loaderContext.resource + ']: ' + msg)
35
+ // )
36
+ // }
37
+
38
+ // const emitError = (msg) => {
39
+ // this.emitError(
40
+ // new Error('[json compiler][' + this.resource + ']: ' + msg)
41
+ // )
42
+ // }
43
+
44
+ // const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
45
+
46
+ const callback = (err) => {
47
+ return rawCallback(err, {
48
+ output,
49
+ jsonObj,
50
+ localPagesMap,
51
+ localComponentsMap,
52
+ tabBarMap,
53
+ tabBarStr
54
+ })
55
+ }
56
+
57
+ if (!jsonContent) {
58
+ return callback()
59
+ }
60
+ // 由于json需要提前读取在template处理中使用,src的场景已经在loader中处理了,此处无需考虑json.src的场景
61
+ try {
62
+ jsonObj = JSON5.parse(jsonContent)
63
+ } catch (e) {
64
+ return callback(e)
65
+ }
66
+
67
+ const fs = loaderContext._compiler.inputFileSystem
68
+
69
+ const resolve = (context, request, callback) => {
70
+ // const { queryObj } = parseRequest(request)
71
+ // todo delete. parseRequest 不会返回 context 属性
72
+ // context = queryObj.context || context
73
+ return loaderContext.resolve(context, request, callback)
74
+ }
75
+
76
+ // const defaultTabbar = {
77
+ // borderStyle: 'black',
78
+ // position: 'bottom',
79
+ // custom: false,
80
+ // isShow: true
81
+ // }
82
+
83
+ // const processTabBar = (tabBar, callback) => {
84
+ // if (tabBar) {
85
+ // tabBar = Object.assign({}, defaultTabbar, tabBar)
86
+ // tabBarMap = {}
87
+ // jsonObj.tabBar.list.forEach(({ pagePath }) => {
88
+ // tabBarMap[pagePath] = true
89
+ // })
90
+ // tabBarStr = JSON.stringify(tabBar)
91
+ // tabBarStr = tabBarStr.replace(/"(iconPath|selectedIconPath)":"([^"]+)"/g, function (matched, $1, $2) {
92
+ // if (isUrlRequest($2, projectRoot)) {
93
+ // return `"${$1}":require(${stringifyRequest(loaderUtils.urlToRequest($2, projectRoot))})`
94
+ // }
95
+ // return matched
96
+ // })
97
+ // }
98
+ // callback()
99
+ // }
100
+
101
+ const processPackages = (packages, context, callback) => {
102
+ if (packages) {
103
+ async.forEach(packages, (packagePath, callback) => {
104
+ const parsed = parseRequest(packagePath)
105
+ const queryObj = parsed.queryObj
106
+ // readFile无法处理query
107
+ packagePath = parsed.resourcePath
108
+ async.waterfall([
109
+ (callback) => {
110
+ resolve(context, packagePath, (err, result) => {
111
+ callback(err, result)
112
+ })
113
+ },
114
+ (result, callback) => {
115
+ loaderContext.addDependency(result)
116
+ fs.readFile(result, (err, content) => {
117
+ if (err) return callback(err)
118
+ callback(err, result, content.toString('utf-8'))
119
+ })
120
+ },
121
+ (result, content, callback) => {
122
+ const filePath = result
123
+ const extName = path.extname(filePath)
124
+ if (extName === '.mpx' || extName === '.vue') {
125
+ const parts = parseComponent(content, {
126
+ filePath,
127
+ needMap: loaderContext.sourceMap,
128
+ mode,
129
+ defs,
130
+ env
131
+ })
132
+ getJSONContent(parts.json || {}, result, loaderContext, (err, content) => {
133
+ callback(err, result, content)
134
+ })
135
+ } else {
136
+ callback(null, result, content)
137
+ }
138
+ },
139
+ (result, content, callback) => {
140
+ try {
141
+ content = JSON5.parse(content)
142
+ } catch (err) {
143
+ return callback(err)
144
+ }
145
+
146
+ const processSelfQueue = []
147
+ const context = path.dirname(result)
148
+
149
+ if (content.pages) {
150
+ const tarRoot = queryObj.root
151
+ if (tarRoot) {
152
+ delete queryObj.root
153
+ const subPackage = {
154
+ tarRoot,
155
+ pages: content.pages,
156
+ ...queryObj
157
+ }
158
+ processSelfQueue.push((callback) => {
159
+ processSubPackage(subPackage, context, callback)
160
+ })
161
+ } else {
162
+ processSelfQueue.push((callback) => {
163
+ processPages(content.pages, '', '', context, callback)
164
+ })
165
+ }
166
+ }
167
+ if (content.packages) {
168
+ processSelfQueue.push((callback) => {
169
+ processPackages(content.packages, context, callback)
170
+ })
171
+ }
172
+ if (processSelfQueue.length) {
173
+ async.parallel(processSelfQueue, callback)
174
+ } else {
175
+ callback()
176
+ }
177
+ }
178
+ ], callback)
179
+ }, callback)
180
+ } else {
181
+ callback()
182
+ }
183
+ }
184
+
185
+ // const getPageName = (resourcePath, ext) => {
186
+ // const baseName = path.basename(resourcePath, ext)
187
+ // return path.join('pages', baseName + pathHash(resourcePath), baseName)
188
+ // }
189
+
190
+ const processPages = (pages, srcRoot = '', tarRoot = '', context, callback) => {
191
+ if (pages) {
192
+ context = path.join(context, srcRoot)
193
+ async.forEach(pages, (page, callback) => {
194
+ let pagePath = page
195
+ if (typeof page !== 'string') {
196
+ pagePath = page.src
197
+ }
198
+ // if (!isUrlRequest(page, projectRoot)) return callback()
199
+ // if (resolveMode === 'native') {
200
+ // page = loaderUtils.urlToRequest(page, projectRoot)
201
+ // }
202
+ // resolve(context, page, (err, resource) => {
203
+ // if (err) return callback(err)
204
+ // const { resourcePath, queryObj } = parseRequest(resource)
205
+ // const ext = path.extname(resourcePath)
206
+ // // 获取pageName
207
+ // let pageName
208
+ // if (aliasPath) {
209
+ // pageName = toPosix(path.join(tarRoot, aliasPath))
210
+ // // 判断 key 存在重复情况直接报错
211
+ // for (let key in pagesMap) {
212
+ // if (pagesMap[key] === pageName && key !== resourcePath) {
213
+ // emitError(`Current page [${resourcePath}] registers a conflict page path [${pageName}] with existed page [${key}], which is not allowed, please rename it!`)
214
+ // return callback()
215
+ // }
216
+ // }
217
+ // } else {
218
+ // const relative = path.relative(context, resourcePath)
219
+ // if (/^\./.test(relative)) {
220
+ // // 如果当前page不存在于context中,对其进行重命名
221
+ // pageName = toPosix(path.join(tarRoot, getPageName(resourcePath, ext)))
222
+ // emitWarning(`Current page [${resourcePath}] is not in current pages directory [${context}], the page path will be replaced with [${pageName}], use ?resolve to get the page path and navigate to it!`)
223
+ // } else {
224
+ // pageName = toPosix(path.join(tarRoot, /^(.*?)(\.[^.]*)?$/.exec(relative)[1]))
225
+ // // 如果当前page与已有page存在命名冲突,也进行重命名
226
+ // for (let key in pagesMap) {
227
+ // // 此处引入pagesMap确保相同entry下路由路径重复注册才报错,不同entry下的路由路径重复则无影响
228
+ // if (pagesMap[key] === pageName && key !== resourcePath && pagesMap[key] === loaderContext.resourcePath) {
229
+ // const pageNameRaw = pageName
230
+ // pageName = toPosix(path.join(tarRoot, getPageName(resourcePath, ext)))
231
+ // emitWarning(`Current page [${resourcePath}] is registered with a conflict page path [${pageNameRaw}] which is already existed in system, the page path will be replaced with [${pageName}], use ?resolve to get the page path and navigate to it!`)
232
+ // break
233
+ // }
234
+ // }
235
+ // }
236
+ // }
237
+ // if (pagesMap[resourcePath]) {
238
+ // emitWarning(`Current page [${resourcePath}] which is imported from [${loaderContext.resourcePath}] has been registered in pagesMap already, it will be ignored, please check it and remove the redundant page declaration!`)
239
+ // return callback()
240
+ // }
241
+ // buildInfo.pagesMap = buildInfo.pagesMap || {}
242
+ // buildInfo.pagesMap[resourcePath] = pagesMap[resourcePath] = pageName
243
+ // pagesMap[resourcePath] = loaderContext.resourcePath
244
+ localPagesMap[pagePath] = page
245
+ // callback()
246
+ // })
247
+ callback()
248
+ }, callback)
249
+ } else {
250
+ callback()
251
+ }
252
+ }
253
+
254
+ const processSubPackage = (subPackage, context, callback) => {
255
+ if (subPackage) {
256
+ const tarRoot = subPackage.tarRoot || subPackage.root || ''
257
+ const srcRoot = subPackage.srcRoot || subPackage.root || ''
258
+ if (!tarRoot) return callback()
259
+ processPages(subPackage.pages, srcRoot, tarRoot, context, callback)
260
+ } else {
261
+ callback()
262
+ }
263
+ }
264
+
265
+ const processSubPackages = (subPackages, context, callback) => {
266
+ if (subPackages) {
267
+ async.forEach(subPackages, (subPackage, callback) => {
268
+ processSubPackage(subPackage, context, callback)
269
+ }, callback)
270
+ } else {
271
+ callback()
272
+ }
273
+ }
274
+
275
+ const processComponents = (components, context, callback) => {
276
+ if (components) {
277
+ async.forEachOf(components, (component, name, callback) => {
278
+ processComponent(component, name, context, callback)
279
+ }, callback)
280
+ } else {
281
+ callback()
282
+ }
283
+ }
284
+
285
+ const processComponent = (component, name, context, callback) => {
286
+ if (!isUrlRequest(component, projectRoot)) return callback()
287
+
288
+ if (resolveMode === 'native') {
289
+ component = loaderUtils.urlToRequest(component, projectRoot)
290
+ }
291
+
292
+ resolve(context, component, (err, resource) => {
293
+ if (err) return callback(err)
294
+ const { resourcePath, queryObj } = parseRequest(resource)
295
+ const parsed = path.parse(resourcePath)
296
+ const componentId = parsed.name + pathHash(resourcePath)
297
+
298
+ buildInfo.packageName = 'main'
299
+ buildInfo.componentsMap = buildInfo.componentsMap || {}
300
+ buildInfo.componentsMap[resourcePath] = componentsMap[resourcePath] = componentId
301
+
302
+ localComponentsMap[name] = {
303
+ resource: addQuery(resource, { isComponent: true, componentId }),
304
+ async: queryObj.async
305
+ }
306
+ callback()
307
+ })
308
+ }
309
+
310
+ // const processGenerics = (generics, context, callback) => {
311
+ // if (generics) {
312
+ // async.forEachOf(generics, (generic, name, callback) => {
313
+ // if (generic.default) {
314
+ // processComponent(generic.default, `${name}default`, context, callback)
315
+ // } else {
316
+ // callback()
317
+ // }
318
+ // }, callback)
319
+ // } else {
320
+ // callback()
321
+ // }
322
+ // }
323
+
324
+ async.parallel([
325
+ (callback) => {
326
+ if (jsonObj.pages && jsonObj.pages[0]) {
327
+ // 标记首页
328
+ if (typeof jsonObj.pages[0] !== 'string') {
329
+ jsonObj.pages[0].src = addQuery(jsonObj.pages[0].src, { isFirst: true })
330
+ } else {
331
+ jsonObj.pages[0] = addQuery(jsonObj.pages[0], { isFirst: true })
332
+ }
333
+ }
334
+ processPages(jsonObj.pages, '', '', context, callback)
335
+ },
336
+ (callback) => {
337
+ processComponents(jsonObj.usingComponents, context, callback)
338
+ },
339
+ (callback) => {
340
+ processPackages(jsonObj.packages, context, callback)
341
+ },
342
+ (callback) => {
343
+ processSubPackages(jsonObj.subPackages || jsonObj.subpackages, context, callback)
344
+ }
345
+ // (callback) => {
346
+ // processGenerics(jsonObj.componentGenerics, context, callback)
347
+ // },
348
+ // (callback) => {
349
+ // processTabBar(jsonObj.tabBar, callback)
350
+ // }
351
+ ], callback)
352
+ }