@mpxjs/webpack-plugin 2.9.69-beta.0 → 2.9.69-beta.10

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 (74) hide show
  1. package/lib/config.js +3 -1
  2. package/lib/index.js +17 -1
  3. package/lib/platform/style/wx/index.js +18 -18
  4. package/lib/platform/template/wx/component-config/movable-view.js +8 -1
  5. package/lib/platform/template/wx/component-config/scroll-view.js +1 -1
  6. package/lib/platform/template/wx/index.js +3 -1
  7. package/lib/react/processScript.js +6 -4
  8. package/lib/resolver/AddEnvPlugin.js +1 -0
  9. package/lib/resolver/AddModePlugin.js +1 -0
  10. package/lib/runtime/components/react/context.ts +25 -0
  11. package/lib/runtime/components/react/dist/context.js +4 -0
  12. package/lib/runtime/components/react/dist/getInnerListeners.js +5 -6
  13. package/lib/runtime/components/react/dist/locale-provider.jsx +15 -0
  14. package/lib/runtime/components/react/dist/mpx-button.jsx +16 -44
  15. package/lib/runtime/components/react/dist/mpx-image.jsx +13 -9
  16. package/lib/runtime/components/react/dist/mpx-input.jsx +1 -1
  17. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +1 -1
  18. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +2 -1
  19. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +2 -2
  20. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +72 -57
  21. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +1 -1
  22. package/lib/runtime/components/react/dist/mpx-portal/portal-consumer.jsx +23 -0
  23. package/lib/runtime/components/react/dist/mpx-portal/portal-host.jsx +93 -0
  24. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +40 -0
  25. package/lib/runtime/components/react/dist/mpx-portal.jsx +13 -0
  26. package/lib/runtime/components/react/dist/mpx-provider.jsx +31 -0
  27. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +10 -11
  28. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +1 -1
  29. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +18 -9
  30. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +31 -8
  31. package/lib/runtime/components/react/dist/mpx-swiper.jsx +437 -372
  32. package/lib/runtime/components/react/dist/mpx-view.jsx +18 -53
  33. package/lib/runtime/components/react/dist/mpx-web-view.jsx +163 -49
  34. package/lib/runtime/components/react/dist/pickerFaces.js +3 -8
  35. package/lib/runtime/components/react/dist/useAnimationHooks.js +31 -14
  36. package/lib/runtime/components/react/dist/utils.jsx +120 -4
  37. package/lib/runtime/components/react/getInnerListeners.ts +5 -7
  38. package/lib/runtime/components/react/locale-provider.tsx +83 -0
  39. package/lib/runtime/components/react/mpx-button.tsx +20 -57
  40. package/lib/runtime/components/react/mpx-image.tsx +41 -25
  41. package/lib/runtime/components/react/mpx-input.tsx +1 -1
  42. package/lib/runtime/components/react/mpx-movable-view.tsx +1 -1
  43. package/lib/runtime/components/react/mpx-picker/time.tsx +2 -1
  44. package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +88 -0
  45. package/lib/runtime/components/react/mpx-picker-view-column.tsx +196 -163
  46. package/lib/runtime/components/react/mpx-picker-view.tsx +35 -37
  47. package/lib/runtime/components/react/mpx-portal/portal-consumer.tsx +32 -0
  48. package/lib/runtime/components/react/mpx-portal/portal-host.tsx +127 -0
  49. package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +64 -0
  50. package/lib/runtime/components/react/mpx-portal.tsx +30 -0
  51. package/lib/runtime/components/react/mpx-provider.tsx +51 -0
  52. package/lib/runtime/components/react/mpx-rich-text/index.tsx +12 -18
  53. package/lib/runtime/components/react/mpx-root-portal.tsx +1 -1
  54. package/lib/runtime/components/react/mpx-scroll-view.tsx +29 -18
  55. package/lib/runtime/components/react/mpx-swiper-item.tsx +45 -11
  56. package/lib/runtime/components/react/mpx-swiper.tsx +743 -0
  57. package/lib/runtime/components/react/mpx-view.tsx +22 -65
  58. package/lib/runtime/components/react/mpx-web-view.tsx +199 -47
  59. package/lib/runtime/components/react/pickerFaces.ts +10 -7
  60. package/lib/runtime/components/react/pickerVIewContext.ts +18 -0
  61. package/lib/runtime/components/react/pickerViewMask.tsx +30 -0
  62. package/lib/runtime/components/react/{pickerOverlay.tsx → pickerViewOverlay.tsx} +5 -3
  63. package/lib/runtime/components/react/types/global.d.ts +10 -1
  64. package/lib/runtime/components/react/useAnimationHooks.ts +35 -15
  65. package/lib/runtime/components/react/utils.tsx +139 -5
  66. package/lib/style-compiler/index.js +3 -4
  67. package/lib/style-compiler/strip-conditional-loader.js +118 -0
  68. package/lib/template-compiler/compiler.js +10 -15
  69. package/lib/utils/pre-process-json.js +5 -9
  70. package/lib/wxss/loader.js +15 -2
  71. package/package.json +1 -1
  72. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +0 -527
  73. package/lib/runtime/components/react/mpx-swiper/index.tsx +0 -80
  74. package/lib/runtime/components/react/mpx-swiper/type.ts +0 -87
@@ -13,6 +13,7 @@ import {
13
13
  WithTimingConfig,
14
14
  AnimationCallback
15
15
  } from 'react-native-reanimated'
16
+ import { error } from '@mpxjs/utils'
16
17
  import { ExtendedViewStyle } from './types/common'
17
18
  import type { _ViewProps } from './mpx-view'
18
19
 
@@ -39,10 +40,10 @@ export type AnimationProp = {
39
40
  // 微信 timingFunction 和 RN Easing 对应关系
40
41
  const EasingKey = {
41
42
  linear: Easing.linear,
42
- ease: Easing.ease,
43
- 'ease-in': Easing.in(Easing.ease),
44
- 'ease-in-out': Easing.inOut(Easing.ease),
45
- 'ease-out': Easing.out(Easing.ease)
43
+ ease: Easing.inOut(Easing.ease),
44
+ 'ease-in': Easing.in(Easing.poly(3)),
45
+ 'ease-in-out': Easing.inOut(Easing.poly(3)),
46
+ 'ease-out': Easing.out(Easing.poly(3))
46
47
  // 'step-start': '',
47
48
  // 'step-end': ''
48
49
  }
@@ -110,7 +111,7 @@ const parseTransform = (transformStr: string) => {
110
111
  const values = parseValues(transformStr)
111
112
  const transform: {[propName: string]: string|number|number[]}[] = []
112
113
  values.forEach(item => {
113
- const match = item.match(/([/\w]+)\(([^)]+)\)/)
114
+ const match = item.match(/([/\w]+)\((.+)\)/)
114
115
  if (match && match.length >= 3) {
115
116
  let key = match[1]
116
117
  const val = match[2]
@@ -166,20 +167,32 @@ const formatStyle = (style: ExtendedViewStyle): ExtendedViewStyle => {
166
167
  })
167
168
  }
168
169
 
169
- export default function useAnimationHooks<T, P> (props: _ViewProps) {
170
- const { style = {}, animation } = props
170
+ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAnimation?: boolean }) {
171
+ const { style = {}, animation, enableAnimation } = props
172
+
173
+ const enableStyleAnimation = enableAnimation || !!animation
174
+ const enableAnimationRef = useRef(enableStyleAnimation)
175
+ if (enableAnimationRef.current !== enableStyleAnimation) {
176
+ error('[Mpx runtime error]: animation use should be stable in the component lifecycle, or you can set [enable-animation] with true.')
177
+ }
178
+
179
+ if (!enableAnimationRef.current) return { enableStyleAnimation: false }
180
+
171
181
  const originalStyle = formatStyle(style)
172
182
  // id 标识
173
183
  const id = animation?.id || -1
174
184
  // 有动画样式的 style key
185
+ // eslint-disable-next-line react-hooks/rules-of-hooks
175
186
  const animatedStyleKeys = useSharedValue([] as (string|string[])[])
176
187
  // 记录动画key的style样式值 没有的话设置为false
188
+ // eslint-disable-next-line react-hooks/rules-of-hooks
177
189
  const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean})
178
190
  // const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean|number|string})
179
191
  // ** 全量 style prop sharedValue
180
192
  // 不能做增量的原因:
181
193
  // 1 尝试用 useRef,但 useAnimatedStyle 访问后的 ref 不能在增加新的值,被冻结
182
194
  // 2 尝试用 useSharedValue,因为实际触发的 style prop 需要是 sharedValue 才能驱动动画,若外层 shareValMap 也是 sharedValue,动画无法驱动。
195
+ // eslint-disable-next-line react-hooks/rules-of-hooks
183
196
  const shareValMap = useMemo(() => {
184
197
  return Object.keys(InitialValue).reduce((valMap, key) => {
185
198
  const defaultVal = getInitialVal(key, isTransform(key))
@@ -188,6 +201,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
188
201
  }, {} as { [propName: keyof ExtendedViewStyle]: SharedValue<string|number> })
189
202
  }, [])
190
203
  // ** 获取动画样式prop & 驱动动画
204
+ // eslint-disable-next-line react-hooks/rules-of-hooks
191
205
  useEffect(() => {
192
206
  if (id === -1) return
193
207
  // 更新动画样式 key map
@@ -208,6 +222,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
208
222
  // })
209
223
  // }, [style])
210
224
  // ** 清空动画
225
+ // eslint-disable-next-line react-hooks/rules-of-hooks
211
226
  useEffect(() => {
212
227
  return () => {
213
228
  Object.values(shareValMap).forEach((value) => {
@@ -240,14 +255,13 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
240
255
  }
241
256
  // 添加每个key的多次step动画
242
257
  animatedKeys.forEach(key => {
258
+ const ruleV = isTransform(key) ? transform.get(key) : rules.get(key)
243
259
  // key不存在,第一轮取shareValMap[key]value,非第一轮取上一轮的
244
- const toVal = rules.get(key) !== undefined
245
- ? rules.get(key)
246
- : transform.get(key) !== undefined
247
- ? transform.get(key)
248
- : index > 0
249
- ? lastValueMap[key]
250
- : shareValMap[key].value
260
+ const toVal = ruleV !== undefined
261
+ ? ruleV
262
+ : index > 0
263
+ ? lastValueMap[key]
264
+ : shareValMap[key].value
251
265
  const animation = getAnimation({ key, value: toVal! }, { delay, duration, easing }, needSetCallback ? setTransformOrigin : undefined)
252
266
  needSetCallback = false
253
267
  if (!sequence[key]) {
@@ -336,7 +350,8 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
336
350
  }, {} as { [propName: string]: string | number })
337
351
  }
338
352
  // ** 生成动画样式
339
- return useAnimatedStyle(() => {
353
+ // eslint-disable-next-line react-hooks/rules-of-hooks
354
+ const animationStyle = useAnimatedStyle(() => {
340
355
  // console.info(`useAnimatedStyle styles=`, originalStyle)
341
356
  return animatedStyleKeys.value.reduce((styles, key) => {
342
357
  // console.info('getAnimationStyles', key, shareValMap[key].value)
@@ -354,4 +369,9 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
354
369
  return styles
355
370
  }, {} as ExtendedViewStyle)
356
371
  })
372
+
373
+ return {
374
+ enableStyleAnimation: enableAnimationRef.current,
375
+ animationStyle
376
+ }
357
377
  }
@@ -1,11 +1,13 @@
1
1
  import { useEffect, useCallback, useMemo, useRef, ReactNode, ReactElement, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react'
2
- import { LayoutChangeEvent, TextStyle, ImageProps, Image } from 'react-native'
2
+ import { LayoutChangeEvent, TextStyle, ImageProps, Image, Platform } from 'react-native'
3
3
  import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils'
4
- import { VarContext } from './context'
4
+ import { VarContext, ScrollViewContext } from './context'
5
5
  import { ExpressionParser, parseFunc, ReplaceSource } from './parser'
6
6
  import { initialWindowMetrics } from 'react-native-safe-area-context'
7
7
  import FastImage, { FastImageProps } from '@d11/react-native-fast-image'
8
- import type { AnyFunc, ExtendedFunctionComponent } from './types/common'
8
+ import type { AnyFunc, ExtendedFunctionComponent, ExtendedViewStyle } from './types/common'
9
+ import { runOnJS } from 'react-native-reanimated'
10
+ import { Gesture } from 'react-native-gesture-handler'
9
11
 
10
12
  export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
11
13
  export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/
@@ -18,6 +20,9 @@ export const HIDDEN_STYLE = {
18
20
  opacity: 0
19
21
  }
20
22
 
23
+ export const isIOS = Platform.OS === 'ios'
24
+ export const isAndroid = Platform.OS === 'android'
25
+
21
26
  const varDecRegExp = /^--.*/
22
27
  const varUseRegExp = /var\(/
23
28
  const calcUseRegExp = /calc\(/
@@ -497,6 +502,7 @@ export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout
497
502
  props.onLayout && props.onLayout(e)
498
503
  }
499
504
  }
505
+
500
506
  return {
501
507
  layoutRef,
502
508
  layoutStyle,
@@ -534,13 +540,14 @@ export const debounce = <T extends AnyFunc> (
534
540
  ): ((...args: Parameters<T>) => void) & { clear: () => void } => {
535
541
  let timer: any
536
542
  const wrapper = (...args: ReadonlyArray<any>) => {
537
- clearTimeout(timer)
543
+ timer && clearTimeout(timer)
538
544
  timer = setTimeout(() => {
539
545
  func(...args)
540
546
  }, delay)
541
547
  }
542
548
  wrapper.clear = () => {
543
- clearTimeout(timer)
549
+ timer && clearTimeout(timer)
550
+ timer = null
544
551
  }
545
552
  return wrapper
546
553
  }
@@ -610,3 +617,130 @@ export function pickStyle (styleObj: Record<string, any> = {}, pickedKeys: Array
610
617
  return acc
611
618
  }, {})
612
619
  }
620
+
621
+ export function useHoverStyle ({ hoverStyle, hoverStartTime, hoverStayTime, disabled } : { hoverStyle?: ExtendedViewStyle, hoverStartTime: number, hoverStayTime: number, disabled?: boolean }) {
622
+ const enableHoverStyle = !!hoverStyle
623
+ const enableHoverStyleRef = useRef(enableHoverStyle)
624
+ if (enableHoverStyleRef.current !== enableHoverStyle) {
625
+ throw new Error('[Mpx runtime error]: hover-class use should be stable in the component lifecycle.')
626
+ }
627
+
628
+ if (!enableHoverStyle) return { enableHoverStyle }
629
+
630
+ const gestureRef = useContext(ScrollViewContext).gestureRef
631
+ const [isHover, setIsHover] = useState(false)
632
+ const dataRef = useRef<{
633
+ startTimer?: ReturnType<typeof setTimeout>
634
+ stayTimer?: ReturnType<typeof setTimeout>
635
+ }>({})
636
+
637
+ useEffect(() => {
638
+ return () => {
639
+ dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
640
+ dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
641
+ }
642
+ }, [])
643
+
644
+ const setStartTimer = () => {
645
+ dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
646
+ dataRef.current.startTimer = setTimeout(() => {
647
+ setIsHover(true)
648
+ }, +hoverStartTime)
649
+ }
650
+
651
+ const setStayTimer = () => {
652
+ dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
653
+ dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
654
+ dataRef.current.stayTimer = setTimeout(() => {
655
+ setIsHover(false)
656
+ }, +hoverStayTime)
657
+ }
658
+
659
+ const gesture = useMemo(() => {
660
+ return Gesture.Pan()
661
+ .onTouchesDown(() => {
662
+ 'worklet'
663
+ if (disabled) return
664
+ runOnJS(setStartTimer)()
665
+ })
666
+ .onTouchesUp(() => {
667
+ 'worklet'
668
+ if (disabled) return
669
+ runOnJS(setStayTimer)()
670
+ })
671
+ }, [disabled])
672
+
673
+ if (gestureRef) {
674
+ gesture.simultaneousWithExternalGesture(gestureRef)
675
+ }
676
+
677
+ return {
678
+ isHover,
679
+ gesture,
680
+ enableHoverStyle
681
+ }
682
+ }
683
+
684
+ export function useHover ({ enableHover, hoverStartTime, hoverStayTime, disabled } : { enableHover: boolean, hoverStartTime: number, hoverStayTime: number, disabled?: boolean }) {
685
+ const enableHoverRef = useRef(enableHover)
686
+ if (enableHoverRef.current !== enableHover) {
687
+ error('[Mpx runtime error]: hover-class use should be stable in the component lifecycle.')
688
+ }
689
+
690
+ if (!enableHoverRef.current) return { isHover: false }
691
+ // eslint-disable-next-line react-hooks/rules-of-hooks
692
+ const gestureRef = useContext(ScrollViewContext).gestureRef
693
+ // eslint-disable-next-line react-hooks/rules-of-hooks
694
+ const [isHover, setIsHover] = useState(false)
695
+ // eslint-disable-next-line react-hooks/rules-of-hooks
696
+ const dataRef = useRef<{
697
+ startTimer?: ReturnType<typeof setTimeout>
698
+ stayTimer?: ReturnType<typeof setTimeout>
699
+ }>({})
700
+
701
+ // eslint-disable-next-line react-hooks/rules-of-hooks
702
+ useEffect(() => {
703
+ return () => {
704
+ dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
705
+ dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
706
+ }
707
+ }, [])
708
+
709
+ const setStartTimer = () => {
710
+ if (disabled) return
711
+ dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
712
+ dataRef.current.startTimer = setTimeout(() => {
713
+ setIsHover(true)
714
+ }, +hoverStartTime)
715
+ }
716
+
717
+ const setStayTimer = () => {
718
+ if (disabled) return
719
+ dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer)
720
+ dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer)
721
+ dataRef.current.stayTimer = setTimeout(() => {
722
+ setIsHover(false)
723
+ }, +hoverStayTime)
724
+ }
725
+ // eslint-disable-next-line react-hooks/rules-of-hooks
726
+ const gesture = useMemo(() => {
727
+ return Gesture.Pan()
728
+ .onTouchesDown(() => {
729
+ 'worklet'
730
+ runOnJS(setStartTimer)()
731
+ })
732
+ .onTouchesUp(() => {
733
+ 'worklet'
734
+ runOnJS(setStayTimer)()
735
+ })
736
+ }, [])
737
+
738
+ if (gestureRef) {
739
+ gesture.simultaneousWithExternalGesture(gestureRef)
740
+ }
741
+
742
+ return {
743
+ isHover,
744
+ gesture
745
+ }
746
+ }
@@ -4,7 +4,6 @@ const loadPostcssConfig = require('./load-postcss-config')
4
4
  const { MPX_ROOT_VIEW, MPX_DISABLE_EXTRACTOR_CACHE } = require('../utils/const')
5
5
  const rpx = require('./plugins/rpx')
6
6
  const vw = require('./plugins/vw')
7
- const pluginCondStrip = require('./plugins/conditional-strip')
8
7
  const scopeId = require('./plugins/scope-id')
9
8
  const transSpecial = require('./plugins/trans-special')
10
9
  const cssArrayList = require('./plugins/css-array-list')
@@ -58,9 +57,9 @@ module.exports = function (css, map) {
58
57
  plugins.push(transSpecial({ id }))
59
58
  }
60
59
 
61
- plugins.push(pluginCondStrip({
62
- defs
63
- }))
60
+ // plugins.push(pluginCondStrip({
61
+ // defs
62
+ // }))
64
63
 
65
64
  for (const item of transRpxRules) {
66
65
  const {
@@ -0,0 +1,118 @@
1
+ const MagicString = require('magic-string')
2
+
3
+ function cssConditionalStrip (cssContent, defs) {
4
+ const ms = new MagicString(cssContent)
5
+
6
+ // 正则匹配 @mpx-if, @mpx-elif, @mpx-else, @mpx-endif 的模式
7
+ const ifPattern = /\/\*\s*@mpx-if\s*\((.*?)\)\s*\*\//gs
8
+ const elifPattern = /\/\*\s*@mpx-elif\s*\((.*?)\)\s*\*\//gs
9
+ const elsePattern = /\/\*\s*@mpx-else\s*\*\//gs
10
+ const endifPattern = /\/\*\s*@mpx-endif\s*\*\//gs
11
+
12
+ function evaluateCondition (condition) {
13
+ // 替换变量
14
+ for (const key in defs) {
15
+ condition = condition.replace(new RegExp(`\\b${key}\\b`, 'g'), JSON.stringify(defs[key]))
16
+ }
17
+
18
+ // 解析条件表达式
19
+ try {
20
+ // eslint-disable-next-line no-new-func
21
+ return Function('"use strict";return (' + condition + ')')()
22
+ } catch (e) {
23
+ throw new Error(`Failed to evaluate condition: ${condition}`)
24
+ }
25
+ }
26
+
27
+ let currentStart = 0
28
+ function processCondition (start, end, condition) {
29
+ const conditionResult = evaluateCondition(condition)
30
+ let hasElse = false
31
+ let elseStart = -1
32
+ let elseLen = 0
33
+ currentStart = end + 1
34
+
35
+ while (currentStart < ms.original.length) {
36
+ elsePattern.lastIndex = currentStart
37
+ const elseMatch = elsePattern.exec(ms.original)
38
+ if (elseMatch) {
39
+ elseLen = elseMatch[0].length
40
+ }
41
+
42
+ ifPattern.lastIndex = currentStart
43
+ const ifMatch = ifPattern.exec(ms.original)
44
+
45
+ elifPattern.lastIndex = currentStart
46
+ const elseIfMatch = elifPattern.exec(ms.original)
47
+
48
+ endifPattern.lastIndex = currentStart
49
+ const endifMatch = endifPattern.exec(ms.original)
50
+
51
+ const nextIf = ifMatch ? ifMatch.index : Infinity
52
+ const nextElseIf = elseIfMatch ? elseIfMatch.index : Infinity
53
+ const nextElse = elseMatch ? elseMatch.index : Infinity
54
+ const nextEndif = endifMatch ? endifMatch.index : Infinity
55
+
56
+ const nextMarker = Math.min(nextIf, nextElseIf, nextElse, nextEndif)
57
+
58
+ if (nextMarker === Infinity) break
59
+
60
+ if (nextMarker === nextElse) {
61
+ // 处理 @mpx-else
62
+ hasElse = true
63
+ elseStart = nextElse
64
+ currentStart = elseMatch.index + elseLen
65
+ ms.remove(elseStart, elseStart + elseLen) // 移除 @mpx-else 注释
66
+ } else if (nextMarker === nextElseIf) {
67
+ // 处理 @mpx-elif
68
+ if (!conditionResult) {
69
+ // 前边的if为false,则直接移除前边代码
70
+ ms.remove(start, nextElseIf)
71
+ }
72
+ currentStart = nextElseIf + elseIfMatch[0].length
73
+ ms.remove(nextElseIf, nextElseIf + elseIfMatch[0].length) // 移除 @mpx-elif 注释
74
+ processCondition(nextElseIf, nextElseIf + elseIfMatch[0].length, elseIfMatch[1])
75
+ } else if (nextMarker === nextIf) {
76
+ // 处理嵌套的 @mpx-if
77
+ // 如果遇到了新的 @mpx-if,则递归处理
78
+ currentStart = nextIf + ifMatch[0].length
79
+ ms.remove(nextIf, nextIf + ifMatch[0].length) // 移除 @mpx-if 注释
80
+ processCondition(nextIf, nextIf + ifMatch[0].length, ifMatch[1])
81
+ } else if (nextMarker === nextEndif) {
82
+ // 处理 @mpx-endif block块
83
+ if (conditionResult && hasElse) {
84
+ // 移除 @mpx-else 至 @mpx-endif 代码
85
+ ms.remove(elseStart, endifMatch.index + endifMatch[0].length)
86
+ } else if (!conditionResult && hasElse) {
87
+ ms.remove(start, elseStart + elseLen)
88
+ } else if (!conditionResult) {
89
+ ms.remove(start, endifMatch.index + endifMatch[0].length)
90
+ }
91
+ ms.remove(endifMatch.index, endifMatch.index + endifMatch[0].length) // 移除 @mpx-endif 注释
92
+ currentStart = endifMatch.index + endifMatch[0].length
93
+ break
94
+ }
95
+ // 兜底更新当前开始位置
96
+ if (currentStart < nextMarker) {
97
+ currentStart = nextMarker + 1
98
+ }
99
+ }
100
+ }
101
+
102
+ let match
103
+ while ((match = ifPattern.exec(ms.original)) !== null) {
104
+ processCondition(match.index, ifPattern.lastIndex, match[1])
105
+ // 移除匹配到的 @mpx-if 注释
106
+ ms.remove(match.index, match.index + match[0].length)
107
+ ifPattern.lastIndex = currentStart
108
+ }
109
+
110
+ return ms.toString()
111
+ }
112
+
113
+ module.exports = function (css) {
114
+ this.cacheable()
115
+ const mpx = this.getMpx()
116
+ const defs = mpx.defs
117
+ return cssConditionalStrip(css, defs)
118
+ }
@@ -117,7 +117,6 @@ let hasOptionalChaining = false
117
117
  let processingTemplate = false
118
118
  const rulesResultMap = new Map()
119
119
  let usingComponents = []
120
- let usingComponentsInfo = {}
121
120
 
122
121
  function updateForScopesMap () {
123
122
  forScopesMap = {}
@@ -637,7 +636,6 @@ function parse (template, options) {
637
636
 
638
637
  if (typeof options.usingComponentsInfo === 'string') options.usingComponentsInfo = JSON.parse(options.usingComponentsInfo)
639
638
  usingComponents = Object.keys(options.usingComponentsInfo)
640
- usingComponentsInfo = options.usingComponentsInfo
641
639
 
642
640
  const _warn = content => {
643
641
  const currentElementRuleResult = rulesResultMap.get(currentEl) || rulesResultMap.set(currentEl, {
@@ -1209,7 +1207,7 @@ function processEventReact (el) {
1209
1207
  for (const type in eventConfigMap) {
1210
1208
  const { configs } = eventConfigMap[type]
1211
1209
  if (!configs.length) continue
1212
- const needBind = configs.length > 1 || configs[0].hasArgs
1210
+ const needBind = configs.length > 1 || configs[0].hasArgs || tagRE.test(configs[0].value)
1213
1211
  if (needBind) {
1214
1212
  configs.forEach(({ name }) => {
1215
1213
  if (name) {
@@ -1773,7 +1771,7 @@ function processRefReact (el, meta) {
1773
1771
  const selectorsConf = selectors.map(item => `["${item.prefix}", ${item.selector}]`)
1774
1772
  addAttrs(el, [{
1775
1773
  name: 'ref',
1776
- value: `{{ this.__getRefVal('${type}', [${selectorsConf}]) }}`
1774
+ value: `{{ this.__getRefVal('${type}', [${selectorsConf}], 'ref_fn_${++refId}') }}`
1777
1775
  }])
1778
1776
  }
1779
1777
 
@@ -2187,20 +2185,16 @@ function isRealNode (el) {
2187
2185
  return !virtualNodeTagMap[el.tag]
2188
2186
  }
2189
2187
 
2190
- function isComponentNode (el) {
2188
+ function isComponentNode (el, options) {
2191
2189
  return usingComponents.indexOf(el.tag) !== -1 || el.tag === 'component'
2192
2190
  }
2193
2191
 
2194
- function getComponentInfo (el) {
2195
- return usingComponentsInfo[el.tag] || {}
2196
- }
2197
-
2198
- function isReactComponent (el) {
2199
- return !isComponentNode(el) && isRealNode(el) && !el.isBuiltIn
2192
+ function isReactComponent (el, options) {
2193
+ return !isComponentNode(el, options) && isRealNode(el) && !el.isBuiltIn
2200
2194
  }
2201
2195
 
2202
2196
  function processExternalClasses (el, options) {
2203
- const isComponent = isComponentNode(el)
2197
+ const isComponent = isComponentNode(el, options)
2204
2198
  const classLikeAttrNames = isComponent ? ['class'].concat(options.externalClasses) : ['class']
2205
2199
 
2206
2200
  classLikeAttrNames.forEach((classLikeAttrName) => {
@@ -2314,7 +2308,8 @@ function postProcessAliComponentRootView (el, options, meta) {
2314
2308
  { condition: /^style$/, action: 'move' },
2315
2309
  { condition: /^slot$/, action: 'move' }
2316
2310
  ]
2317
- const mid = getComponentInfo(el).mid
2311
+ const tagName = el.tag
2312
+ const mid = options.usingComponentsInfo[tagName]?.mid || moduleId
2318
2313
  const processAppendAttrsRules = [
2319
2314
  { name: 'class', value: `${MPX_ROOT_VIEW} host-${mid}` }
2320
2315
  ]
@@ -2421,7 +2416,7 @@ function processShow (el, options, root) {
2421
2416
  show = has ? `{{${parseMustacheWithContext(show).result}&&mpxShow}}` : '{{mpxShow}}'
2422
2417
  }
2423
2418
  if (show === undefined) return
2424
- if (isComponentNode(el) && getComponentInfo(el).hasVirtualHost) {
2419
+ if (isComponentNode(el, options)) {
2425
2420
  if (show === '') {
2426
2421
  show = '{{false}}'
2427
2422
  }
@@ -2720,7 +2715,7 @@ function closeElement (el, options, meta) {
2720
2715
  }
2721
2716
  })
2722
2717
  }
2723
- if (isComponentNode(el) && !hasVirtualHost && mode === 'ali' && el.tag !== 'component') {
2718
+ if (isComponentNode(el, options) && !hasVirtualHost && mode === 'ali' && el.tag !== 'component') {
2724
2719
  postProcessAliComponentRootView(el, options, meta)
2725
2720
  }
2726
2721
  }
@@ -6,7 +6,6 @@ const addQuery = require('./add-query')
6
6
  const resolve = require('./resolve')
7
7
  const getJSONContent = require('./get-json-content')
8
8
  const getRulesRunner = require('../platform')
9
- const { matchCondition } = require('./match-condition')
10
9
  const async = require('async')
11
10
 
12
11
  module.exports = function ({
@@ -20,7 +19,8 @@ module.exports = function ({
20
19
  }, callback) {
21
20
  const mpx = loaderContext.getMpx()
22
21
  const context = loaderContext.context
23
- const { mode, pagesMap, autoVirtualHostRules } = mpx
22
+ const mode = mpx.mode
23
+ const pagesMap = mpx.pagesMap
24
24
  async.waterfall([
25
25
  (callback) => {
26
26
  getJSONContent(json, null, loaderContext, callback)
@@ -78,8 +78,8 @@ module.exports = function ({
78
78
  componentGenerics = Object.assign({}, ret.componentGenerics)
79
79
  }
80
80
  if (usingComponents) {
81
- const setUsingComponentInfo = (name, info) => {
82
- usingComponentsInfo[name] = info
81
+ const setUsingComponentInfo = (name, moduleId) => {
82
+ usingComponentsInfo[name] = { mid: moduleId }
83
83
  }
84
84
  async.eachOf(usingComponents, (component, name, callback) => {
85
85
  if (ctorType === 'app') {
@@ -96,11 +96,7 @@ module.exports = function ({
96
96
  if (err) return callback(err)
97
97
  const { rawResourcePath } = parseRequest(resource)
98
98
  const moduleId = mpx.getModuleId(rawResourcePath, ctorType === 'app')
99
- const hasVirtualHost = matchCondition(rawResourcePath, autoVirtualHostRules)
100
- setUsingComponentInfo(name, {
101
- mid: moduleId,
102
- hasVirtualHost
103
- })
99
+ setUsingComponentInfo(name, moduleId)
104
100
  callback()
105
101
  })
106
102
  }, (err) => {
@@ -32,6 +32,13 @@ const {
32
32
  } = require('./utils')
33
33
  const createHelpers = require('../helpers')
34
34
 
35
+ const RN_PRESET_OPTIMISATION = {
36
+ reduceInitial: false,
37
+ normalizeWhitespace: false,
38
+ minifyFontValues: false,
39
+ convertValues: false
40
+ }
41
+
35
42
  module.exports = async function loader (content, map, meta) {
36
43
  const rawOptions = this.getOptions(schema)
37
44
  const plugins = []
@@ -41,6 +48,7 @@ module.exports = async function loader (content, map, meta) {
41
48
  const externals = mpx.externals
42
49
  const root = mpx.projectRoot
43
50
  const sourceMap = mpx.cssSourceMap || false
51
+ const isRN = ['ios', 'android', 'harmony'].includes(mpx.mode)
44
52
 
45
53
  let options
46
54
 
@@ -152,12 +160,17 @@ module.exports = async function loader (content, map, meta) {
152
160
  if (this.minimize) {
153
161
  const cssnano = require('cssnano')
154
162
  const minimizeOptions = rawOptions.minimize || {}
163
+ const presetOptimisation = Object.assign(
164
+ {},
165
+ isRN ? RN_PRESET_OPTIMISATION : {},
166
+ minimizeOptions.optimisation
167
+ )
155
168
  let cssnanoConfig = {
156
- preset: ['cssnano-preset-default', minimizeOptions.optimisation || {}]
169
+ preset: ['cssnano-preset-default', presetOptimisation]
157
170
  }
158
171
  if (minimizeOptions.advanced) {
159
172
  cssnanoConfig = {
160
- preset: ['cssnano-preset-advanced', minimizeOptions.optimisation || {}]
173
+ preset: ['cssnano-preset-advanced', presetOptimisation]
161
174
  }
162
175
  }
163
176
  plugins.push(cssnano(cssnanoConfig))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.9.69-beta.0",
3
+ "version": "2.9.69-beta.10",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"