@mpxjs/webpack-plugin 2.9.58 → 2.9.59

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.
package/lib/config.js CHANGED
@@ -5,9 +5,7 @@ const reactConfig = {
5
5
  if (match) {
6
6
  return {
7
7
  prefix: match[1],
8
- eventName: match[2].replace(/^./, function (match) {
9
- return match.toLowerCase()
10
- }),
8
+ eventName: match[2],
11
9
  modifier: match[3]
12
10
  }
13
11
  }
@@ -153,17 +153,21 @@ module.exports = function getSpec ({ warn, error }) {
153
153
  const cssMap = []
154
154
  const props = Object.getOwnPropertyNames(keyMap)
155
155
  let idx = 0
156
+ let propsIdx = 0
156
157
  // 按值的个数循环赋值
157
- while (idx < values.length && idx < props.length) {
158
- const prop = props[idx]
158
+ while (idx < values.length || propsIdx < props.length) {
159
+ const prop = props[propsIdx]
159
160
  const valueType = keyMap[prop]
160
161
  const dashProp = hump2dash(prop)
161
- // 校验 value 类型
162
- verifyValues({ prop, value: values[idx], valueType })
163
162
  const value = values[idx]
164
163
  if (isIllegalValue({ prop: dashProp, value })) {
165
- // 过滤不支持 value
164
+ // 过滤 rn prop 不支持 value
166
165
  unsupportedValueError({ prop: dashProp, value })
166
+ idx += 1
167
+ propsIdx += 1
168
+ } else if (!verifyValues({ prop, value, valueType })) {
169
+ // 校验 value 类型,类型不符则匹配下一个value
170
+ idx += 1
167
171
  } else if (prop.includes('.')) {
168
172
  // 多个属性值的prop
169
173
  const [main, sub] = prop.split('.')
@@ -178,14 +182,17 @@ module.exports = function getSpec ({ warn, error }) {
178
182
  }
179
183
  })
180
184
  }
185
+ idx += 1
186
+ propsIdx += 1
181
187
  } else {
182
188
  // 单个值的属性
183
189
  cssMap.push({
184
190
  prop,
185
191
  value
186
192
  })
193
+ idx += 1
194
+ propsIdx += 1
187
195
  }
188
- idx += 1
189
196
  }
190
197
  return cssMap
191
198
  }
@@ -355,6 +362,69 @@ module.exports = function getSpec ({ warn, error }) {
355
362
  }
356
363
  }
357
364
 
365
+ const formatTransform = ({ prop, value }, { mode }) => {
366
+ if (Array.isArray(value)) return { prop, value }
367
+ const values = value.trim().split(/\s(?![^()]*\))/)
368
+ const transform = []
369
+ values.forEach(item => {
370
+ const match = item.match(/([/\w]+)\(([^)]+)\)/)
371
+ if (match.length >= 3) {
372
+ let key = match[1]
373
+ const val = match[2]
374
+ switch (key) {
375
+ case 'translateX':
376
+ case 'translateY':
377
+ case 'scaleX':
378
+ case 'scaleY':
379
+ case 'rotateX':
380
+ case 'rotateY':
381
+ case 'rotateZ':
382
+ case 'rotate':
383
+ case 'skewX':
384
+ case 'skewY':
385
+ // 单个值处理
386
+ transform.push({ [key]: val })
387
+ break
388
+ case 'matrix':
389
+ case 'matrix3d':
390
+ transform.push({ [key]: val.split(',').map(val => +val) })
391
+ break
392
+ case 'translate':
393
+ case 'scale':
394
+ case 'skew':
395
+ case 'rotate3d': // x y z angle
396
+ case 'translate3d': // x y 支持 z不支持
397
+ case 'scale3d': // x y 支持 z不支持
398
+ {
399
+ // 2 个以上的值处理
400
+ key = key.replace('3d', '')
401
+ const vals = val.split(',').splice(0, key === 'rotate' ? 4 : 3)
402
+ const xyz = ['X', 'Y', 'Z']
403
+ transform.push(...vals.map((v, index) => {
404
+ if (key !== 'rotate' && index > 1) {
405
+ unsupportedPropError({ prop: `${key}Z`, mode })
406
+ }
407
+ return { [`${key}${xyz[index] || ''}`]: v.trim() }
408
+ }))
409
+ break
410
+ }
411
+ case 'translateZ':
412
+ case 'scaleZ':
413
+ default:
414
+ // 不支持的属性处理
415
+ unsupportedPropError({ prop: key, mode })
416
+ break
417
+ }
418
+ } else {
419
+ error(`Property [${prop}] is invalid, please check the value!`)
420
+ }
421
+ })
422
+ return {
423
+ prop,
424
+ value: transform
425
+ }
426
+ }
427
+
358
428
  const spec = {
359
429
  supportedModes: ['ios', 'android'],
360
430
  rules: [
@@ -417,6 +487,11 @@ module.exports = function getSpec ({ warn, error }) {
417
487
  ios: formatLineHeight,
418
488
  android: formatLineHeight
419
489
  },
490
+ {
491
+ test: 'transform',
492
+ ios: formatTransform,
493
+ android: formatTransform
494
+ },
420
495
  // 值类型校验放到最后
421
496
  { // color 颜色值校验 color xx-color 等
422
497
  test: /^(color|(.+-color))$/,
@@ -27,12 +27,16 @@ import { getComponent } from ${stringifyRequest(loaderContext, optionProcessorPa
27
27
  import { NavigationContainer, createNavigationContainerRef, StackActions } from '@react-navigation/native'
28
28
  import { createNativeStackNavigator } from '@react-navigation/native-stack'
29
29
  import { Provider } from '@ant-design/react-native'
30
+ import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context'
31
+
30
32
  global.__navigationHelper = {
31
33
  NavigationContainer: NavigationContainer,
32
34
  createNavigationContainerRef: createNavigationContainerRef,
33
35
  createNativeStackNavigator: createNativeStackNavigator,
34
36
  StackActions: StackActions,
35
- Provider: Provider
37
+ Provider: Provider,
38
+ SafeAreaProvider: SafeAreaProvider,
39
+ useSafeAreaInsets: useSafeAreaInsets
36
40
  }\n`
37
41
  const { pagesMap, firstPage } = buildPagesMap({
38
42
  localPagesMap,
@@ -47,7 +47,16 @@ function getClassMap ({ content, filename, mode, srcMode, warn, error }) {
47
47
  prop = dash2hump(item.prop)
48
48
  value = item.value
49
49
  if (Array.isArray(value)) {
50
- value = value.map(item => formatValue(item))
50
+ value = value.map(val => {
51
+ if (typeof val === 'object') {
52
+ for (const key in val) {
53
+ val[key] = formatValue(val[key])
54
+ }
55
+ return val
56
+ } else {
57
+ return formatValue(val)
58
+ }
59
+ })
51
60
  } else if (typeof value === 'object') {
52
61
  for (const key in value) {
53
62
  value[key] = formatValue(value[key])
@@ -10,8 +10,8 @@ const getTouchEvent = (type, event, props, config) => {
10
10
  ...event,
11
11
  type,
12
12
  timeStamp: timestamp,
13
- target: {
14
- ...(event.target || {}),
13
+ currentTarget: {
14
+ ...(event.currentTarget || {}),
15
15
  id: id || '',
16
16
  dataset: getDataSet(props),
17
17
  offsetLeft: layoutRef?.current?.offsetLeft || 0,
@@ -8,13 +8,13 @@ import { useRef, useEffect, forwardRef } from 'react';
8
8
  import useInnerProps from './getInnerListeners';
9
9
  // @ts-ignore
10
10
  import useNodesRef from './useNodesRef'; // 引入辅助函数
11
- import { PERCENT_REGX } from './utils';
11
+ import { PERCENT_REGEX } from './utils';
12
12
  const DEFAULT_STYLE = {
13
13
  fontSize: 16
14
14
  };
15
15
  const transformStyle = (styleObj) => {
16
16
  let { lineHeight } = styleObj;
17
- if (typeof lineHeight === 'string' && PERCENT_REGX.test(lineHeight)) {
17
+ if (typeof lineHeight === 'string' && PERCENT_REGEX.test(lineHeight)) {
18
18
  lineHeight = (parseFloat(lineHeight) / 100) * (styleObj.fontSize || DEFAULT_STYLE.fontSize);
19
19
  styleObj.lineHeight = lineHeight;
20
20
  }
@@ -10,7 +10,7 @@ import { useRef, useState, useEffect, forwardRef } from 'react';
10
10
  import useInnerProps from './getInnerListeners';
11
11
  // @ts-ignore
12
12
  import useNodesRef from './useNodesRef'; // 引入辅助函数
13
- import { parseUrl, TEXT_STYLE_REGEX, PERCENT_REGX, isText } from './utils';
13
+ import { parseUrl, TEXT_STYLE_REGEX, PERCENT_REGEX, isText } from './utils';
14
14
  const IMAGE_STYLE_REGEX = /^background(Image|Size|Repeat|Position)$/;
15
15
  function groupBy(style, callback, group = {}) {
16
16
  let groupKey = '';
@@ -33,7 +33,7 @@ const applyHandlers = (handlers, args) => {
33
33
  };
34
34
  const checkNeedLayout = (style) => {
35
35
  const [width, height] = style.sizeList;
36
- return (PERCENT_REGX.test(`${height}`) && width === 'auto') || (PERCENT_REGX.test(`${width}`) && height === 'auto');
36
+ return (PERCENT_REGEX.test(`${height}`) && width === 'auto') || (PERCENT_REGEX.test(`${width}`) && height === 'auto');
37
37
  };
38
38
  /**
39
39
  * h - 用户设置的高度
@@ -42,7 +42,7 @@ const checkNeedLayout = (style) => {
42
42
  * **/
43
43
  function calculateSize(h, lh, ratio) {
44
44
  let height, width;
45
- if (PERCENT_REGX.test(`${h}`)) { // auto px/rpx
45
+ if (PERCENT_REGEX.test(`${h}`)) { // auto px/rpx
46
46
  if (!lh)
47
47
  return null;
48
48
  height = (parseFloat(`${h}`) / 100) * lh;
@@ -97,8 +97,8 @@ function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
97
97
  else { // 数值类型 ImageStyle
98
98
  // 数值类型设置为 stretch
99
99
  imageProps.style.resizeMode = 'stretch';
100
- newWidth = PERCENT_REGX.test(`${width}`) ? width : +width;
101
- newHeight = PERCENT_REGX.test(`${width}`) ? height : +height;
100
+ newWidth = PERCENT_REGEX.test(`${width}`) ? width : +width;
101
+ newHeight = PERCENT_REGEX.test(`${width}`) ? height : +height;
102
102
  }
103
103
  // 样式合并
104
104
  imageProps.style = {
@@ -1,7 +1,7 @@
1
1
  import { useEffect, useRef, Children, isValidElement } from 'react';
2
2
  import { StyleSheet } from 'react-native';
3
3
  export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/;
4
- export const PERCENT_REGX = /^\s*-?\d+(\.\d+)?%\s*$/;
4
+ export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/;
5
5
  const URL_REGEX = /url\(["']?(.*?)["']?\)/;
6
6
  export function omit(obj, fields) {
7
7
  const shallowCopy = Object.assign({}, obj);
@@ -33,8 +33,8 @@ const getTouchEvent = (
33
33
  ...event,
34
34
  type,
35
35
  timeStamp: timestamp,
36
- target: {
37
- ...(event.target || {}),
36
+ currentTarget: {
37
+ ...(event.currentTarget || {}),
38
38
  id: id || '',
39
39
  dataset: getDataSet(props),
40
40
  offsetLeft: layoutRef?.current?.offsetLeft || 0,
@@ -9,7 +9,7 @@ import { useRef, useEffect, forwardRef, ReactNode, ForwardedRef, JSX } from 'rea
9
9
  import useInnerProps from './getInnerListeners'
10
10
  // @ts-ignore
11
11
  import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
12
- import { PERCENT_REGX } from './utils'
12
+ import { PERCENT_REGEX } from './utils'
13
13
 
14
14
 
15
15
  interface _TextProps extends TextProps {
@@ -28,7 +28,7 @@ const DEFAULT_STYLE = {
28
28
 
29
29
  const transformStyle = (styleObj: TextStyle) => {
30
30
  let { lineHeight } = styleObj
31
- if (typeof lineHeight === 'string' && PERCENT_REGX.test(lineHeight)) {
31
+ if (typeof lineHeight === 'string' && PERCENT_REGEX.test(lineHeight)) {
32
32
  lineHeight = (parseFloat(lineHeight)/100) * (styleObj.fontSize || DEFAULT_STYLE.fontSize)
33
33
  styleObj.lineHeight = lineHeight
34
34
  }
@@ -5,13 +5,13 @@
5
5
  * ✔ hover-stay-time
6
6
  */
7
7
  import { View, Text, StyleProp, TextStyle, ViewStyle, NativeSyntheticEvent, ViewProps, ImageStyle, ImageResizeMode, StyleSheet, Image, LayoutChangeEvent } from 'react-native'
8
- import { useRef, useState, useEffect, forwardRef, ForwardedRef, ReactNode, JSX } from 'react'
8
+ import { useRef, useState, useEffect, forwardRef, ReactNode, JSX } from 'react'
9
9
  // @ts-ignore
10
10
  import useInnerProps from './getInnerListeners'
11
11
  // @ts-ignore
12
12
  import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
13
13
 
14
- import { parseUrl, TEXT_STYLE_REGEX, PERCENT_REGX, isText} from './utils'
14
+ import { parseUrl, TEXT_STYLE_REGEX, PERCENT_REGEX, isText} from './utils'
15
15
 
16
16
 
17
17
  type ExtendedViewStyle = ViewStyle & {
@@ -79,7 +79,7 @@ const applyHandlers = (handlers: Handler[] , args: any [] ) => {
79
79
 
80
80
  const checkNeedLayout = (style: PreImageInfo) => {
81
81
  const [width, height] = style.sizeList
82
- return (PERCENT_REGX.test(`${height}`) && width === 'auto') || (PERCENT_REGX.test(`${width}`) && height === 'auto')
82
+ return (PERCENT_REGEX.test(`${height}`) && width === 'auto') || (PERCENT_REGEX.test(`${width}`) && height === 'auto')
83
83
  }
84
84
 
85
85
  /**
@@ -89,7 +89,7 @@ const checkNeedLayout = (style: PreImageInfo) => {
89
89
  * **/
90
90
  function calculateSize(h: number, lh: number, ratio: number) {
91
91
  let height, width
92
- if (PERCENT_REGX.test(`${h}`)) { // auto px/rpx
92
+ if (PERCENT_REGEX.test(`${h}`)) { // auto px/rpx
93
93
  if (!lh) return null
94
94
  height = (parseFloat(`${h}`) / 100) * lh
95
95
  width = height * ratio
@@ -136,8 +136,8 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima
136
136
  } else { // 数值类型 ImageStyle
137
137
  // 数值类型设置为 stretch
138
138
  (imageProps.style as ImageStyle).resizeMode = 'stretch'
139
- newWidth = PERCENT_REGX.test(`${width}`) ? width : +width! as DimensionValue
140
- newHeight = PERCENT_REGX.test(`${width}`) ? height : +height! as DimensionValue
139
+ newWidth = PERCENT_REGEX.test(`${width}`) ? width : +width! as DimensionValue
140
+ newHeight = PERCENT_REGEX.test(`${width}`) ? height : +height! as DimensionValue
141
141
  }
142
142
  // 样式合并
143
143
  imageProps.style = {
@@ -3,7 +3,7 @@ import { StyleProp, StyleSheet, TextStyle, ViewStyle } from 'react-native'
3
3
 
4
4
  export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/
5
5
 
6
- export const PERCENT_REGX = /^\s*-?\d+(\.\d+)?%\s*$/
6
+ export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/
7
7
 
8
8
  const URL_REGEX = /url\(["']?(.*?)["']?\)/
9
9
 
@@ -1052,7 +1052,7 @@ function stringifyWithResolveComputed (modelValue) {
1052
1052
  return result.join('+')
1053
1053
  }
1054
1054
 
1055
- function processStyleReact (el) {
1055
+ function processStyleReact (el, options) {
1056
1056
  // process class/wx:class/style/wx:style/wx:show for react native
1057
1057
  const dynamicClass = getAndRemoveAttr(el, config[mode].directive.dynamicClass).val
1058
1058
  let staticClass = getAndRemoveAttr(el, 'class').val || ''
@@ -1088,10 +1088,24 @@ function processStyleReact (el) {
1088
1088
  const staticClassExp = parseMustacheWithContext(staticHoverClass).result
1089
1089
  addAttrs(el, [{
1090
1090
  name: 'hoverStyle',
1091
- // runtime helper
1092
1091
  value: `{{this.__getStyle(${staticClassExp})}}`
1093
1092
  }])
1094
1093
  }
1094
+
1095
+ // 处理externalClasses,将其转换为style作为props传递
1096
+ if (options.externalClasses) {
1097
+ options.externalClasses.forEach((className) => {
1098
+ let externalClass = getAndRemoveAttr(el, className).val || ''
1099
+ externalClass = externalClass.replace(/\s+/g, ' ')
1100
+ if (externalClass) {
1101
+ const externalClassExp = parseMustacheWithContext(externalClass).result
1102
+ addAttrs(el, [{
1103
+ name: className,
1104
+ value: `{{this.__getStyle(${externalClassExp})}}`
1105
+ }])
1106
+ }
1107
+ })
1108
+ }
1095
1109
  }
1096
1110
 
1097
1111
  function getModelConfig (el, match) {
@@ -2590,7 +2604,7 @@ function processElement (el, root, options, meta) {
2590
2604
  processIf(el)
2591
2605
  processFor(el)
2592
2606
  processRefReact(el, meta)
2593
- processStyleReact(el)
2607
+ processStyleReact(el, options)
2594
2608
  processEventReact(el)
2595
2609
  processComponentIs(el, options)
2596
2610
  processSlotReact(el)
@@ -6,7 +6,7 @@ module.exports = function shallowStringify (obj, isTemplateExp) {
6
6
  if (hasOwn(obj, key)) {
7
7
  let value = obj[key]
8
8
  if (Array.isArray(value)) {
9
- value = `[${value.join(',')}]`
9
+ value = `[${value.map((item) => typeof item === 'object' ? shallowStringify(item, isTemplateExp) : item).join(',')}]`
10
10
  } else if (typeof value === 'object') {
11
11
  value = shallowStringify(value, isTemplateExp)
12
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.9.58",
3
+ "version": "2.9.59",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -90,5 +90,5 @@
90
90
  "engines": {
91
91
  "node": ">=14.14.0"
92
92
  },
93
- "gitHead": "49fe4c4bc46ff4bf87cd8adde37981d4b4134aa7"
93
+ "gitHead": "aa001c11cc7b21772fc6f9f5bcdd13118fc6d67c"
94
94
  }