@mpxjs/webpack-plugin 2.10.15-4 → 2.10.15-prelease.1

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 (45) hide show
  1. package/lib/dependencies/DynamicEntryDependency.js +1 -1
  2. package/lib/dependencies/ImportDependency.js +102 -0
  3. package/lib/{retry-runtime-module.js → dependencies/RetryRuntimeModule.js} +1 -1
  4. package/lib/index.js +13 -15
  5. package/lib/platform/template/wx/component-config/progress.js +12 -0
  6. package/lib/platform/template/wx/component-config/slider.js +12 -0
  7. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  8. package/lib/platform/template/wx/index.js +3 -1
  9. package/lib/resolver/AddEnvPlugin.js +13 -0
  10. package/lib/resolver/AddModePlugin.js +18 -0
  11. package/lib/runtime/components/react/dist/getInnerListeners.js +35 -21
  12. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +102 -34
  13. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +3 -5
  14. package/lib/runtime/components/react/dist/mpx-progress.jsx +163 -0
  15. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +51 -9
  16. package/lib/runtime/components/react/dist/mpx-slider.jsx +321 -0
  17. package/lib/runtime/components/react/dist/mpx-swiper.jsx +9 -16
  18. package/lib/runtime/components/react/dist/mpx-view.jsx +7 -10
  19. package/lib/runtime/components/react/dist/mpx-web-view.jsx +20 -1
  20. package/lib/runtime/components/react/getInnerListeners.ts +41 -22
  21. package/lib/runtime/components/react/mpx-movable-view.tsx +156 -48
  22. package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +4 -8
  23. package/lib/runtime/components/react/mpx-progress.tsx +259 -0
  24. package/lib/runtime/components/react/mpx-scroll-view.tsx +54 -9
  25. package/lib/runtime/components/react/mpx-slider.tsx +444 -0
  26. package/lib/runtime/components/react/mpx-swiper.tsx +9 -16
  27. package/lib/runtime/components/react/mpx-view.tsx +7 -10
  28. package/lib/runtime/components/react/mpx-web-view.tsx +22 -1
  29. package/lib/runtime/components/react/types/getInnerListeners.d.ts +7 -2
  30. package/lib/runtime/components/web/mpx-input.vue +14 -0
  31. package/lib/runtime/components/web/mpx-movable-area.vue +43 -19
  32. package/lib/runtime/components/web/mpx-movable-view.vue +93 -3
  33. package/lib/runtime/components/web/mpx-scroll-view.vue +7 -1
  34. package/lib/runtime/components/web/mpx-swiper.vue +1 -2
  35. package/lib/runtime/components/web/mpx-video.vue +12 -1
  36. package/lib/runtime/components/web/mpx-web-view.vue +3 -3
  37. package/lib/runtime/optionProcessor.js +3 -1
  38. package/lib/runtime/optionProcessorReact.js +4 -2
  39. package/lib/template-compiler/compiler.js +69 -35
  40. package/lib/utils/chain-assign.js +47 -0
  41. package/lib/utils/check-core-version-match.js +75 -15
  42. package/lib/wxs/pre-loader.js +5 -5
  43. package/lib/wxss/utils.js +1 -1
  44. package/package.json +3 -2
  45. package/lib/dependencies/ImportDependencyTemplate.js +0 -50
@@ -1,21 +1,23 @@
1
1
  <template>
2
- <div class="mpx-movable-area-container" ref="movableArea">
3
- <div class="mpx-movable-scroll-wrapper" ref="scroll">
4
- <slot></slot>
5
- </div>
2
+ <div class="mpx-movable-area-container" ref="movableArea">
3
+ <div class="mpx-movable-scroll-wrapper" ref="scroll">
4
+ <slot></slot>
6
5
  </div>
6
+ </div>
7
7
  </template>
8
8
 
9
9
  <script type="text/ecmascript-6">
10
10
  export default {
11
- data () {
12
- return {}
11
+ data() {
12
+ return {
13
+ isInited: false,
14
+ }
13
15
  },
14
- mounted () {
16
+ mounted() {
15
17
  this.computedStyle()
16
- },
17
- beforeDestroy () {
18
-
18
+ if (!this.closeResizeObserver) {
19
+ this.createResizeObserver()
20
+ }
19
21
  },
20
22
  methods: {
21
23
  computedStyle() {
@@ -26,17 +28,39 @@
26
28
  if (!style.height) {
27
29
  this.$refs.movableArea.style.height = '10px'
28
30
  }
31
+ },
32
+ createResizeObserver() {
33
+ if (typeof ResizeObserver !== 'undefined') {
34
+ this.resizeObserver = new ResizeObserver(entries => {
35
+ if (!this.isInited) {
36
+ this.isInited = true
37
+ return
38
+ }
39
+ this.$children.forEach(child => {
40
+ if (child && child.refresh) {
41
+ child.refresh()
42
+ }
43
+ })
44
+ })
45
+ this.resizeObserver.observe(this.$refs.movableArea)
46
+ }
47
+ },
48
+ },
49
+ beforeDestroy () {
50
+ if (this.resizeObserver) {
51
+ this.resizeObserver.disconnect()
52
+ this.resizeObserver = null
29
53
  }
30
- }
54
+ },
31
55
  }
32
56
  </script>
33
57
  <style lang="stylus" rel="stylesheet/stylus" scoped>
34
- .mpx-movable-area-container
35
- position: absolute
36
- .mpx-movable-scroll-wrapper
37
- position: absolute
38
- top: 0
39
- left: 0
40
- bottom: 0
41
- right: 0
58
+ .mpx-movable-area-container
59
+ position: relative
60
+ .mpx-movable-scroll-wrapper
61
+ position: absolute
62
+ top: 0
63
+ left: 0
64
+ bottom: 0
65
+ right: 0
42
66
  </style>
@@ -38,7 +38,13 @@ export default {
38
38
  touchEvent: '',
39
39
  isInited: false,
40
40
  deactivatedX: 0,
41
- deactivatedY: 0
41
+ deactivatedY: 0,
42
+ // 缓存高度,用于检测变化
43
+ cachedContentHeight: 0,
44
+ cachedWrapperHeight: 0,
45
+ // 缓存宽度,用于检测变化
46
+ cachedContentWidth: 0,
47
+ cachedWrapperWidth: 0
42
48
  }
43
49
  },
44
50
  props: {
@@ -107,7 +113,24 @@ export default {
107
113
  },
108
114
  watch: {
109
115
  x (newVal) {
116
+ if (this.direction === 'vertical' || this.direction === 'none') {
117
+ return
118
+ }
110
119
  this.source = ''
120
+ // 检查宽度是否发生变化,只有在变化时才调用 refresh
121
+ const widthChanged = this.checkWidthChange()
122
+ let currentX = this.bs.x
123
+
124
+ if (widthChanged) {
125
+ // 兼容容器尺寸变化且同时改变x的场景,ResizeObserver回调是异步的,如果不直接refresh,minScrollX, maxScrollX 拿到的都是上一次的值
126
+ this.refresh()
127
+ // bs refresh 方法内会触发 resetPosition(),如果容器宽度从 100 - 50,y 从 100 - 50,这会导致位置立即跳转到边界内,没有动画效果,造成视觉突兀
128
+ // 如果 refresh 导致了位置变化,先恢复到原位置再动画滚动
129
+ if (this.bs.x !== currentX) {
130
+ this.bs.scrollTo(currentX, this.bs.y, 0)
131
+ }
132
+ }
133
+
111
134
  if (newVal > this.bs.minScrollX) {
112
135
  newVal = this.bs.minScrollX
113
136
  }
@@ -118,7 +141,24 @@ export default {
118
141
  this.bs.scrollTo(newVal, this.bs.y, this.speed)
119
142
  },
120
143
  y (newVal) {
144
+ if (this.direction === 'horizontal' || this.direction === 'none') {
145
+ return
146
+ }
121
147
  this.source = ''
148
+ // 检查高度是否发生变化,只有在变化时才调用 refresh
149
+ const heightChanged = this.checkHeightChange()
150
+ let currentY = this.bs.y
151
+
152
+ if (heightChanged) {
153
+ // 兼容容器尺寸变化且同时改变y的场景,ResizeObserver回调是异步的,如果不直接refresh,minScrollY, maxScrollY 拿到的都是上一次的值
154
+ this.refresh()
155
+ // bs refresh 方法内会触发 resetPosition(),如果容器高度从 100 - 50,y 从 100 - 50,这会导致位置立即跳转到边界内,没有动画效果,造成视觉突兀
156
+ // 如果 refresh 导致了位置变化,先恢复到原位置再动画滚动
157
+ if (this.bs.y !== currentY) {
158
+ this.bs.scrollTo(this.bs.x, currentY, 0)
159
+ }
160
+ }
161
+
122
162
  if (newVal > this.bs.minScrollY) {
123
163
  newVal = this.bs.minScrollY
124
164
  }
@@ -146,6 +186,10 @@ export default {
146
186
  if (!this.scrollOptions.closeResizeObserver) {
147
187
  this.createResizeObserver()
148
188
  }
189
+ // 初始化尺寸缓存
190
+ this.$nextTick(() => {
191
+ this.initSizeCache()
192
+ })
149
193
  this.init()
150
194
  },
151
195
  activated () {
@@ -178,13 +222,50 @@ export default {
178
222
  }
179
223
  this.refresh()
180
224
  })
181
- const elementToObserve = document.querySelector('.mpx-movable-scroll-content')
182
- elementToObserve && this.resizeObserver.observe(elementToObserve)
225
+ this.resizeObserver.observe(this.$refs.scrollContent)
183
226
  }
184
227
  },
185
228
  refresh () {
186
229
  this.bs && this.bs.refresh()
187
230
  },
231
+ // 检查高度是否发生变化
232
+ checkHeightChange () {
233
+ if (!this.$refs.scrollContent || !this.$parent.$refs.movableArea) {
234
+ return false
235
+ }
236
+
237
+ const currentContentHeight = this.$refs.scrollContent.clientHeight
238
+ const currentWrapperHeight = this.$parent.$refs.movableArea.clientHeight
239
+
240
+ const heightChanged =
241
+ currentContentHeight !== this.cachedContentHeight ||
242
+ currentWrapperHeight !== this.cachedWrapperHeight
243
+
244
+ // 更新缓存的高度
245
+ this.cachedContentHeight = currentContentHeight
246
+ this.cachedWrapperHeight = currentWrapperHeight
247
+
248
+ return heightChanged
249
+ },
250
+ // 检查宽度是否发生变化
251
+ checkWidthChange () {
252
+ if (!this.$refs.scrollContent || !this.$parent.$refs.movableArea) {
253
+ return false
254
+ }
255
+
256
+ const currentContentWidth = this.$refs.scrollContent.clientWidth
257
+ const currentWrapperWidth = this.$parent.$refs.movableArea.clientWidth
258
+
259
+ const widthChanged =
260
+ currentContentWidth !== this.cachedContentWidth ||
261
+ currentWrapperWidth !== this.cachedWrapperWidth
262
+
263
+ // 更新缓存的宽度
264
+ this.cachedContentWidth = currentContentWidth
265
+ this.cachedWrapperWidth = currentWrapperWidth
266
+
267
+ return widthChanged
268
+ },
188
269
  destroyBs () {
189
270
  if (!this.bs) return
190
271
  this.bs.destroy()
@@ -364,6 +445,15 @@ export default {
364
445
  }
365
446
  extend(this.bsOptions, this.scrollOptions)
366
447
  },
448
+ // 初始化尺寸缓存
449
+ initSizeCache () {
450
+ if (this.$refs.scrollContent && this.$parent.$refs.movableArea) {
451
+ this.cachedContentHeight = this.$refs.scrollContent.clientHeight
452
+ this.cachedWrapperHeight = this.$parent.$refs.movableArea.clientHeight
453
+ this.cachedContentWidth = this.$refs.scrollContent.clientWidth
454
+ this.cachedWrapperWidth = this.$parent.$refs.movableArea.clientWidth
455
+ }
456
+ },
367
457
  // 处理小数点,四舍五入,默认保留一位小数
368
458
  roundFun (value, n = 1) {
369
459
  return Math.round(value * Math.pow(10, n)) / Math.pow(10, n)
@@ -4,10 +4,12 @@
4
4
  import { processSize } from '../../utils'
5
5
  import BScroll from '@better-scroll/core'
6
6
  import PullDown from '@better-scroll/pull-down'
7
+ import MouseWheel from '@better-scroll/mouse-wheel'
7
8
  import throttle from 'lodash/throttle'
8
9
  import debounce from 'lodash/debounce'
9
10
 
10
11
  BScroll.use(PullDown)
12
+ BScroll.use(MouseWheel)
11
13
 
12
14
  let mutationObserver = null
13
15
  let resizeObserver = null
@@ -222,7 +224,11 @@
222
224
  bounce: false,
223
225
  stopPropagation: true,
224
226
  bindToWrapper: true,
225
- eventPassthrough: (this.scrollX && 'vertical') || (this.scrollY && 'horizontal') || ''
227
+ eventPassthrough: (this.scrollX && 'vertical') || (this.scrollY && 'horizontal') || '',
228
+ mouseWheel: {
229
+ speed: 20,
230
+ easeTime: 300
231
+ }
226
232
  }
227
233
  if (this.refresherEnabled) {
228
234
  originBsOptions.bounce = true
@@ -256,8 +256,7 @@
256
256
  }
257
257
  this.initBs()
258
258
  })
259
- const elementToObserve = document.querySelector('.mpx-swiper');
260
- this.resizeObserver.observe(elementToObserve);
259
+ this.resizeObserver.observe(this.$refs.wrapper);
261
260
  }
262
261
  },
263
262
  refresh () {
@@ -148,6 +148,11 @@
148
148
  },
149
149
  controls: function (show) {
150
150
  this.$emit('controlstoggle', inheritEvent('controlstoggle', {}, { show }))
151
+ },
152
+ objectFit (val) {
153
+ if (this._player && this._player.video) {
154
+ this._player.video.style.objectFit = val
155
+ }
151
156
  }
152
157
  },
153
158
  mounted () {
@@ -189,6 +194,9 @@
189
194
  if (this.initialTime) {
190
195
  this._player.seek(this.initialTime)
191
196
  }
197
+ if (this.objectFit) {
198
+ this._player.video.style.objectFit = this.objectFit
199
+ }
192
200
  },
193
201
  initStyle () {
194
202
 
@@ -239,7 +247,10 @@
239
247
 
240
248
  this._player.on('progress', (e) => {
241
249
  const eNode = e.target
242
- const buffered = (eNode?.buffered?.end(0)) / (eNode?.duration)
250
+ let buffered = 0
251
+ if (eNode?.buffered && eNode.buffered.length > 0) {
252
+ buffered = (eNode.buffered.end(0)) / (eNode?.duration)
253
+ }
243
254
  this.$emit('progress', inheritEvent('progress', e, { buffered: buffered * 100 }))
244
255
  })
245
256
 
@@ -124,7 +124,7 @@ export default {
124
124
  case 'postMessage':
125
125
  let data = {
126
126
  type: 'message',
127
- data: params[0]?.data
127
+ data: params[0]?.data || params[0] // 补充兜底逻辑
128
128
  }
129
129
  this.$emit(eventMessage, getCustomEvent(eventMessage, data, this))
130
130
  asyncCallback = Promise.resolve({
@@ -148,7 +148,7 @@ export default {
148
148
  break
149
149
  default:
150
150
  if (type) {
151
- const implement = mpx.config.webviewConfig.apiImplementations && mpx.config.webviewConfig.apiImplementations[type]
151
+ const implement = mpx.config.webConfig?.webviewConfig?.apiImplementations?.[type]
152
152
  if (isFunction(implement)) {
153
153
  asyncCallback = Promise.resolve(implement(...params))
154
154
  } else {
@@ -174,7 +174,7 @@ export default {
174
174
  })
175
175
  },
176
176
  hostValidate (host) {
177
- const hostWhitelists = mpx.config.webviewConfig && mpx.config.webviewConfig.hostWhitelists || []
177
+ const hostWhitelists = mpx.config.webConfig?.webviewConfig?.hostWhitelists || []
178
178
  if (hostWhitelists.length) {
179
179
  return hostWhitelists.some((item) => {
180
180
  return host.endsWith(item)
@@ -108,7 +108,9 @@ registered in parent context!`)
108
108
  export function getComponent (component, extendOptions) {
109
109
  component = component.__esModule ? component.default : component
110
110
  // eslint-disable-next-line
111
- if (extendOptions) extend(component, extendOptions)
111
+ if (extendOptions && !component.__mpxExtended) {
112
+ extend(component, extendOptions, { __mpxExtended: true })
113
+ }
112
114
  return component
113
115
  }
114
116
 
@@ -5,7 +5,9 @@ import { extend } from './utils'
5
5
  export function getComponent (component, extendOptions) {
6
6
  component = component.__esModule ? component.default : component
7
7
  // eslint-disable-next-line
8
- if (extendOptions) Object.assign(component, extendOptions)
8
+ if (extendOptions && !component.__mpxExtended) {
9
+ extend(component, extendOptions, { __mpxExtended: true })
10
+ }
9
11
  return component
10
12
  }
11
13
 
@@ -15,7 +17,7 @@ export function getAsyncSuspense (commonProps) {
15
17
  result = memo(forwardRef(function (props, ref) {
16
18
  return createElement(AsyncSuspense,
17
19
  extend({}, commonProps, {
18
- innerProps: Object.assign({}, props, { ref })
20
+ innerProps: extend({}, props, { ref })
19
21
  })
20
22
  )
21
23
  }))
@@ -176,11 +176,11 @@ const i18nWxsPath = normalize.lib('runtime/i18n.wxs')
176
176
  const i18nWxsLoaderPath = normalize.lib('wxs/i18n-loader.js')
177
177
  // 添加~前缀避免wxs绝对路径在存在projectRoot时被拼接为错误路径
178
178
  const i18nWxsRequest = '~' + i18nWxsLoaderPath + '!' + i18nWxsPath
179
- const i18nModuleName = '_i'
179
+ const i18nModuleName = '_i_'
180
180
  const stringifyWxsPath = '~' + normalize.lib('runtime/stringify.wxs')
181
- const stringifyModuleName = '_s'
181
+ const stringifyModuleName = '_s_'
182
182
  const optionalChainWxsPath = '~' + normalize.lib('runtime/oc.wxs')
183
- const optionalChainWxsName = '_oc' // 改成_oc解决web下_o重名问题
183
+ const optionalChainWxsName = '_oc_' // 改成_oc解决web下_o重名问题
184
184
 
185
185
  const tagRES = /(\{\{(?:.|\n|\r)+?\}\})(?!})/
186
186
  const tagRE = /\{\{((?:.|\n|\r)+?)\}\}(?!})/
@@ -1333,8 +1333,35 @@ function processEventReact (el, options) {
1333
1333
  // }
1334
1334
  }
1335
1335
 
1336
+ function isNeedBind (configs, isProxy) {
1337
+ if (isProxy) return true
1338
+ if (configs.length > 1) return true
1339
+ if (configs.length === 1) return configs[0].hasArgs
1340
+ return false
1341
+ }
1342
+
1343
+ function processEventBinding (el, configs) {
1344
+ let resultName
1345
+ configs.forEach(({ name }) => {
1346
+ if (name) {
1347
+ // 清空原始事件绑定
1348
+ let has
1349
+ do {
1350
+ has = getAndRemoveAttr(el, name).has
1351
+ } while (has)
1352
+
1353
+ if (!resultName) {
1354
+ // 清除修饰符
1355
+ resultName = name.replace(/\..*/, '')
1356
+ }
1357
+ }
1358
+ })
1359
+ return { resultName }
1360
+ }
1361
+
1336
1362
  function processEvent (el, options) {
1337
1363
  const eventConfigMap = {}
1364
+ const finalEventsMap = {}
1338
1365
  el.attrsList.forEach(function ({ name, value }) {
1339
1366
  const parsedEvent = config[mode].event.parseEvent(name)
1340
1367
 
@@ -1346,14 +1373,21 @@ function processEvent (el, options) {
1346
1373
  const extraStr = runtimeCompile && prefix === 'catch' ? `, "__mpx_${prefix}"` : ''
1347
1374
  const parsedFunc = parseFuncStr(value, extraStr)
1348
1375
  if (parsedFunc) {
1376
+ const isCapture = /^capture/.test(prefix)
1349
1377
  if (!eventConfigMap[type]) {
1350
1378
  eventConfigMap[type] = {
1351
- configs: []
1379
+ configs: [],
1380
+ captureConfigs: []
1352
1381
  }
1353
1382
  }
1354
- eventConfigMap[type].configs.push(Object.assign({ name }, parsedFunc))
1383
+ const targetConfigs = isCapture ? eventConfigMap[type].captureConfigs : eventConfigMap[type].configs
1384
+ targetConfigs.push(Object.assign({ name }, parsedFunc))
1355
1385
  if (modifiers.indexOf('proxy') > -1 || options.forceProxyEvent) {
1356
- eventConfigMap[type].proxy = true
1386
+ if (isCapture) {
1387
+ eventConfigMap[type].captureProxy = true
1388
+ } else {
1389
+ eventConfigMap[type].proxy = true
1390
+ }
1357
1391
  }
1358
1392
  }
1359
1393
  }
@@ -1393,57 +1427,57 @@ function processEvent (el, options) {
1393
1427
  }
1394
1428
 
1395
1429
  for (const type in eventConfigMap) {
1396
- let needBind = false
1397
- const { configs, proxy } = eventConfigMap[type]
1398
- delete eventConfigMap[type]
1399
- if (proxy) {
1400
- needBind = true
1401
- } else if (configs.length > 1) {
1402
- needBind = true
1403
- } else if (configs.length === 1) {
1404
- needBind = !!configs[0].hasArgs
1405
- }
1430
+ const { configs = [], captureConfigs = [], proxy, captureProxy } = eventConfigMap[type]
1431
+
1432
+ let needBubblingBind = isNeedBind(configs, proxy)
1433
+ let needCaptureBind = isNeedBind(captureConfigs, captureProxy)
1406
1434
 
1407
1435
  const escapedType = dash2hump(type)
1408
1436
  // 排除特殊情况
1409
1437
  if (!isValidIdentifierStr(escapedType)) {
1410
1438
  warn$1(`EventName ${type} which need be framework proxy processed must be a valid identifier!`)
1411
- needBind = false
1439
+ needBubblingBind = false
1440
+ needCaptureBind = false
1412
1441
  }
1413
1442
 
1414
- if (needBind) {
1415
- let resultName
1416
- configs.forEach(({ name }) => {
1417
- if (name) {
1418
- // 清空原始事件绑定
1419
- let has
1420
- do {
1421
- has = getAndRemoveAttr(el, name).has
1422
- } while (has)
1443
+ if (needBubblingBind) {
1444
+ const { resultName } = processEventBinding(el, configs)
1423
1445
 
1424
- if (!resultName) {
1425
- // 清除修饰符
1426
- resultName = name.replace(/\..*/, '')
1427
- }
1446
+ addAttrs(el, [
1447
+ {
1448
+ name: resultName || config[mode].event.getEvent(type),
1449
+ value: '__invoke'
1428
1450
  }
1451
+ ])
1452
+ if (!finalEventsMap.bubble) {
1453
+ finalEventsMap.bubble = {}
1454
+ }
1455
+ finalEventsMap.bubble[escapedType] = configs.map((item) => {
1456
+ return item.expStr
1429
1457
  })
1458
+ }
1430
1459
 
1460
+ if (needCaptureBind) {
1461
+ const { resultName } = processEventBinding(el, captureConfigs)
1431
1462
  addAttrs(el, [
1432
1463
  {
1433
1464
  name: resultName || config[mode].event.getEvent(type),
1434
- value: '__invoke'
1465
+ value: '__captureInvoke'
1435
1466
  }
1436
1467
  ])
1437
- eventConfigMap[escapedType] = configs.map((item) => {
1468
+ if (!finalEventsMap.capture) {
1469
+ finalEventsMap.capture = {}
1470
+ }
1471
+ finalEventsMap.capture[escapedType] = captureConfigs.map((item) => {
1438
1472
  return item.expStr
1439
1473
  })
1440
1474
  }
1441
1475
  }
1442
1476
 
1443
- if (!isEmptyObject(eventConfigMap)) {
1477
+ if (!isEmptyObject(finalEventsMap)) {
1444
1478
  addAttrs(el, [{
1445
1479
  name: 'data-eventconfigs',
1446
- value: `{{${shallowStringify(eventConfigMap, true)}}}`
1480
+ value: `{{${shallowStringify(finalEventsMap, true)}}}`
1447
1481
  }])
1448
1482
  }
1449
1483
  }
@@ -2737,8 +2771,8 @@ function processElement (el, root, options, meta) {
2737
2771
  processIf(el)
2738
2772
  processFor(el)
2739
2773
  processRefReact(el, meta)
2774
+ processStyleReact(el, options)
2740
2775
  if (!pass) {
2741
- processStyleReact(el, options)
2742
2776
  processEventReact(el, options)
2743
2777
  processComponentGenerics(el, meta)
2744
2778
  processComponentIs(el, options)
@@ -0,0 +1,47 @@
1
+ /**
2
+ * 链式合并方法的工具函数
3
+ *
4
+ * 在多条件分支下使用 Object.assign 会导致同名方法被覆盖,
5
+ * 这个函数通过创建组合函数来确保所有方法都能按顺序执行。
6
+ *
7
+ * @param {Object} target - 目标 visitor 对象
8
+ * @param {Object} source - 要链式分配的 visitor 方法对象
9
+ *
10
+ * @example
11
+ * const visitor = {}
12
+ *
13
+ * // 第一次合并
14
+ * chainAssign(visitor, {
15
+ * CallExpression(path) {
16
+ * console.log('第一个处理器')
17
+ * }
18
+ * })
19
+ *
20
+ * // 第二次合并 - 不会覆盖,而是组合执行
21
+ * chainAssign(visitor, {
22
+ * CallExpression(path) {
23
+ * console.log('第二个处理器')
24
+ * }
25
+ * })
26
+ *
27
+ * // 执行时会依次输出:
28
+ * // 第一个处理器
29
+ * // 第二个处理器
30
+ */
31
+ module.exports = function chainAssign (target, source) {
32
+ for (const [key, value] of Object.entries(source)) {
33
+ if (target[key]) {
34
+ // 如果已存在同名方法,创建组合函数依次执行
35
+ const originalMethod = target[key]
36
+ target[key] = function (path) {
37
+ originalMethod.call(this, path)
38
+ // 只有当节点没有停止遍历或被移除时才继续执行
39
+ if (!path.removed && !path.shouldStop) {
40
+ value.call(this, path)
41
+ }
42
+ }
43
+ } else {
44
+ target[key] = value
45
+ }
46
+ }
47
+ }
@@ -1,22 +1,82 @@
1
- const coreVersion = require('@mpxjs/core/package.json').version
2
- const utilsVersion = require('@mpxjs/utils/package.json').version
3
- const corePath = require.resolve('@mpxjs/core')
4
- const utilsPath = require.resolve('@mpxjs/utils')
5
- const semverLt = require('semver/functions/lt')
1
+ const semverSatisfies = require('semver/functions/satisfies')
2
+ const semverCoerce = require('semver/functions/coerce')
6
3
 
7
- const leastCoreVersion = '2.8.59'
8
- const leastUtilsVersion = '2.8.59'
4
+ // 定义包之间的依赖关系和最低版本要求
5
+ const PACKAGE_DEPENDENCIES = {
6
+ '@mpxjs/webpack-plugin': {
7
+ '@mpxjs/core': '^2.10.15 || ^2.10.15-beta.1',
8
+ '@mpxjs/utils': '^2.10.13 || ^2.10.13-beta.1',
9
+ '@mpxjs/api-proxy': '^2.10.15 || ^2.10.15-beta.1'
10
+ }
11
+ }
12
+
13
+ function getPackageVersion (packageName) {
14
+ try {
15
+ return require(`${packageName}/package.json`).version
16
+ } catch (e) {
17
+ console.warn(`无法获取 ${packageName} 的版本信息: ${e.message}`)
18
+ return null
19
+ }
20
+ }
21
+
22
+ function checkVersionSatisfies (version, requiredVersion) {
23
+ try {
24
+ const normalizedVersion = semverCoerce(version).version
25
+ return semverSatisfies(normalizedVersion, requiredVersion)
26
+ } catch (e) {
27
+ console.warn(`版本检查失败: ${e.message}`)
28
+ return false
29
+ }
30
+ }
31
+
32
+ function checkPackageDependencies (packageName) {
33
+ const dependencies = PACKAGE_DEPENDENCIES[packageName]
34
+ if (!dependencies) return []
35
+
36
+ const results = []
37
+
38
+ for (const depName in dependencies) {
39
+ const requiredVersion = dependencies[depName]
40
+ const actualVersion = getPackageVersion(depName)
41
+
42
+ if (!actualVersion) {
43
+ results.push({
44
+ dependency: depName,
45
+ required: requiredVersion,
46
+ actual: null,
47
+ compatible: false,
48
+ error: `无法获取 ${depName} 的版本信息`
49
+ })
50
+ continue
51
+ }
52
+
53
+ const isCompatible = checkVersionSatisfies(actualVersion, requiredVersion)
54
+ results.push({
55
+ dependency: depName,
56
+ required: requiredVersion,
57
+ actual: actualVersion,
58
+ compatible: isCompatible
59
+ })
60
+ }
61
+
62
+ return results
63
+ }
9
64
 
10
- function compare (version, leastVersion, npmName, npmPath) {
11
- if (semverLt(version, leastVersion)) {
65
+ function checkVersionCompatibility () {
66
+ const pluginResults = checkPackageDependencies('@mpxjs/webpack-plugin')
67
+ const incompatibleResults = pluginResults.filter(result => !result.compatible)
68
+ if (incompatibleResults.length > 0) {
69
+ const errorMessages = incompatibleResults.map(result => {
70
+ if (!result.actual) {
71
+ return ` - ${result.error || `${result.dependency} 未安装`}`
72
+ }
73
+ return ` - ${result.dependency}@${result.actual} 不满足所需版本 ${result.required}`
74
+ })
12
75
  throw new Error(
13
- `${npmName} packages version mismatch:
14
- -${npmName}@${version}(${npmPath})
15
- This may cause things to work incorrectly, Make sure the usage version is greater than ${leastVersion}.
16
- `
76
+ `检测到 @mpxjs 包版本不兼容问题:\n${errorMessages.join('\n')}\n\n` +
77
+ '这可能导致编译或运行异常。请确保所有 @mpxjs 相关包的版本兼容,建议使用相同版本。'
17
78
  )
18
79
  }
19
80
  }
20
81
 
21
- compare(coreVersion, leastCoreVersion, '@mpxjs/core', corePath)
22
- compare(utilsVersion, leastUtilsVersion, '@mpxjs/utils', utilsPath)
82
+ module.exports = checkVersionCompatibility