@mpxjs/webpack-plugin 2.10.7-beta.9 → 2.10.8-beta.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.
- package/lib/dependencies/RequireExternalDependency.js +61 -0
- package/lib/file-loader.js +3 -2
- package/lib/index.js +60 -15
- package/lib/json-compiler/index.js +1 -0
- package/lib/parser.js +1 -1
- package/lib/platform/json/wx/index.js +43 -25
- package/lib/platform/template/wx/component-config/fix-component-name.js +2 -2
- package/lib/platform/template/wx/component-config/index.js +2 -0
- package/lib/platform/template/wx/component-config/movable-view.js +10 -1
- package/lib/platform/template/wx/component-config/page-container.js +19 -0
- package/lib/platform/template/wx/component-config/unsupported.js +1 -1
- package/lib/platform/template/wx/index.js +2 -1
- package/lib/react/LoadAsyncChunkModule.js +74 -0
- package/lib/react/index.js +3 -1
- package/lib/react/processJSON.js +74 -13
- package/lib/react/processScript.js +6 -6
- package/lib/react/script-helper.js +100 -41
- package/lib/runtime/components/react/context.ts +2 -12
- package/lib/runtime/components/react/dist/context.js +1 -1
- package/lib/runtime/components/react/dist/getInnerListeners.js +1 -1
- package/lib/runtime/components/react/dist/mpx-async-suspense.jsx +135 -0
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +9 -63
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +58 -301
- package/lib/runtime/components/react/dist/mpx-page-container.jsx +255 -0
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +30 -55
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +14 -28
- package/lib/runtime/components/react/dist/useAnimationHooks.js +2 -87
- package/lib/runtime/components/react/getInnerListeners.ts +1 -1
- package/lib/runtime/components/react/mpx-async-suspense.tsx +180 -0
- package/lib/runtime/components/react/mpx-movable-area.tsx +11 -98
- package/lib/runtime/components/react/mpx-movable-view.tsx +60 -350
- package/lib/runtime/components/react/mpx-page-container.tsx +394 -0
- package/lib/runtime/components/react/mpx-swiper.tsx +29 -55
- package/lib/runtime/components/react/mpx-web-view.tsx +13 -33
- package/lib/runtime/components/react/types/global.d.ts +15 -0
- package/lib/runtime/components/react/useAnimationHooks.ts +2 -85
- package/lib/runtime/optionProcessorReact.d.ts +18 -0
- package/lib/runtime/optionProcessorReact.js +30 -0
- package/lib/script-setup-compiler/index.js +27 -5
- package/lib/template-compiler/compiler.js +27 -6
- package/lib/utils/dom-tag-config.js +18 -4
- package/lib/utils/trans-async-sub-rules.js +19 -0
- package/lib/web/script-helper.js +1 -1
- package/package.json +3 -3
- package/lib/runtime/components/react/AsyncContainer.tsx +0 -189
- package/lib/runtime/components/react/dist/AsyncContainer.jsx +0 -141
|
@@ -42,6 +42,21 @@ declare let global: {
|
|
|
42
42
|
|
|
43
43
|
declare module '@react-navigation/native' {
|
|
44
44
|
export function useNavigation (): Record<string, any>
|
|
45
|
+
export function usePreventRemove(
|
|
46
|
+
enabled: boolean,
|
|
47
|
+
callback: (e: { data: { action: any } }) => void
|
|
48
|
+
): void;
|
|
49
|
+
export interface PreventRemoveEvent {
|
|
50
|
+
data: {
|
|
51
|
+
action: NavigationAction;
|
|
52
|
+
route: {
|
|
53
|
+
key: string;
|
|
54
|
+
name: string;
|
|
55
|
+
params?: unknown;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
preventDefault(): void;
|
|
59
|
+
}
|
|
45
60
|
}
|
|
46
61
|
|
|
47
62
|
declare module '*.png'
|
|
@@ -84,88 +84,6 @@ const InitialValue: ExtendedViewStyle = Object.assign({
|
|
|
84
84
|
const TransformOrigin = 'transformOrigin'
|
|
85
85
|
// transform
|
|
86
86
|
const isTransform = (key: string) => Object.keys(TransformInitial).includes(key)
|
|
87
|
-
// 多value解析
|
|
88
|
-
const parseValues = (str: string, char = ' ') => {
|
|
89
|
-
let stack = 0
|
|
90
|
-
let temp = ''
|
|
91
|
-
const result = []
|
|
92
|
-
for (let i = 0; i < str.length; i++) {
|
|
93
|
-
if (str[i] === '(') {
|
|
94
|
-
stack++
|
|
95
|
-
} else if (str[i] === ')') {
|
|
96
|
-
stack--
|
|
97
|
-
}
|
|
98
|
-
// 非括号内 或者 非分隔字符且非空
|
|
99
|
-
if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
|
|
100
|
-
temp += str[i]
|
|
101
|
-
}
|
|
102
|
-
if ((stack === 0 && str[i] === char) || i === str.length - 1) {
|
|
103
|
-
result.push(temp)
|
|
104
|
-
temp = ''
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return result
|
|
108
|
-
}
|
|
109
|
-
// parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
|
|
110
|
-
const parseTransform = (transformStr: string) => {
|
|
111
|
-
const values = parseValues(transformStr)
|
|
112
|
-
const transform: {[propName: string]: string|number|number[]}[] = []
|
|
113
|
-
values.forEach(item => {
|
|
114
|
-
const match = item.match(/([/\w]+)\((.+)\)/)
|
|
115
|
-
if (match && match.length >= 3) {
|
|
116
|
-
let key = match[1]
|
|
117
|
-
const val = match[2]
|
|
118
|
-
switch (key) {
|
|
119
|
-
case 'translateX':
|
|
120
|
-
case 'translateY':
|
|
121
|
-
case 'scaleX':
|
|
122
|
-
case 'scaleY':
|
|
123
|
-
case 'rotateX':
|
|
124
|
-
case 'rotateY':
|
|
125
|
-
case 'rotateZ':
|
|
126
|
-
case 'rotate':
|
|
127
|
-
case 'skewX':
|
|
128
|
-
case 'skewY':
|
|
129
|
-
case 'perspective':
|
|
130
|
-
// rotate 处理成 rotateZ
|
|
131
|
-
key = key === 'rotate' ? 'rotateZ' : key
|
|
132
|
-
// 单个值处理
|
|
133
|
-
transform.push({ [key]: global.__formatValue(val) })
|
|
134
|
-
break
|
|
135
|
-
case 'matrix':
|
|
136
|
-
transform.push({ [key]: parseValues(val, ',').map(val => +val) })
|
|
137
|
-
break
|
|
138
|
-
case 'translate':
|
|
139
|
-
case 'scale':
|
|
140
|
-
case 'skew':
|
|
141
|
-
case 'translate3d': // x y 支持 z不支持
|
|
142
|
-
case 'scale3d': // x y 支持 z不支持
|
|
143
|
-
{
|
|
144
|
-
// 2 个以上的值处理
|
|
145
|
-
key = key.replace('3d', '')
|
|
146
|
-
const vals = parseValues(val, ',').splice(0, 3)
|
|
147
|
-
// scale(.5) === scaleX(.5) scaleY(.5)
|
|
148
|
-
if (vals.length === 1 && key === 'scale') {
|
|
149
|
-
vals.push(vals[0])
|
|
150
|
-
}
|
|
151
|
-
const xyz = ['X', 'Y', 'Z']
|
|
152
|
-
transform.push(...vals.map((v, index) => {
|
|
153
|
-
return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) }
|
|
154
|
-
}))
|
|
155
|
-
break
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
})
|
|
160
|
-
return transform
|
|
161
|
-
}
|
|
162
|
-
// format style
|
|
163
|
-
const formatStyle = (style: ExtendedViewStyle): ExtendedViewStyle => {
|
|
164
|
-
if (!style.transform || Array.isArray(style.transform)) return style
|
|
165
|
-
return Object.assign({}, style, {
|
|
166
|
-
transform: parseTransform(style.transform)
|
|
167
|
-
})
|
|
168
|
-
}
|
|
169
87
|
|
|
170
88
|
// transform 数组转对象
|
|
171
89
|
function getTransformObj (transforms: { [propName: string]: string | number }[]) {
|
|
@@ -176,7 +94,7 @@ function getTransformObj (transforms: { [propName: string]: string | number }[])
|
|
|
176
94
|
}
|
|
177
95
|
|
|
178
96
|
export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAnimation?: boolean, layoutRef: MutableRefObject<any>, transitionend?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void }) {
|
|
179
|
-
const { style = {}, animation, enableAnimation, transitionend, layoutRef } = props
|
|
97
|
+
const { style: originalStyle = {}, animation, enableAnimation, transitionend, layoutRef } = props
|
|
180
98
|
const enableStyleAnimation = enableAnimation || !!animation
|
|
181
99
|
const enableAnimationRef = useRef(enableStyleAnimation)
|
|
182
100
|
if (enableAnimationRef.current !== enableStyleAnimation) {
|
|
@@ -185,7 +103,6 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
|
|
|
185
103
|
|
|
186
104
|
if (!enableAnimationRef.current) return { enableStyleAnimation: false }
|
|
187
105
|
|
|
188
|
-
const originalStyle = formatStyle(style)
|
|
189
106
|
// id 标识
|
|
190
107
|
const id = animation?.id || -1
|
|
191
108
|
// 有动画样式的 style key
|
|
@@ -214,7 +131,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
|
|
|
214
131
|
useEffect(() => {
|
|
215
132
|
// style 更新后同步更新 lastStyleRef & shareValMap
|
|
216
133
|
updateStyleVal()
|
|
217
|
-
}, [
|
|
134
|
+
}, [originalStyle])
|
|
218
135
|
// ** 获取动画样式prop & 驱动动画
|
|
219
136
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
220
137
|
useEffect(() => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ReactNode, ComponentType } from 'react'
|
|
1
2
|
declare global {
|
|
2
3
|
namespace NodeJS {
|
|
3
4
|
interface Global {
|
|
@@ -7,3 +8,20 @@ declare global {
|
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
export function getComponent (...args: any): object
|
|
11
|
+
|
|
12
|
+
interface AsyncModule {
|
|
13
|
+
__esModule: boolean
|
|
14
|
+
default: ReactNode
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface AsyncSuspenseProps {
|
|
18
|
+
type: 'component' | 'page'
|
|
19
|
+
chunkName: string
|
|
20
|
+
moduleId: string
|
|
21
|
+
innerProps: any
|
|
22
|
+
loading: ComponentType<unknown>
|
|
23
|
+
fallback: ComponentType<unknown>
|
|
24
|
+
getChildren: () => Promise<AsyncModule>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getAsyncSuspense(props: AsyncSuspenseProps): ReactNode
|
|
@@ -1,6 +1,36 @@
|
|
|
1
|
+
import AsyncSuspense from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-async-suspense'
|
|
2
|
+
import { memo, forwardRef, createElement } from 'react'
|
|
3
|
+
import { extend } from './utils'
|
|
4
|
+
|
|
1
5
|
export function getComponent (component, extendOptions) {
|
|
2
6
|
component = component.__esModule ? component.default : component
|
|
3
7
|
// eslint-disable-next-line
|
|
4
8
|
if (extendOptions) Object.assign(component, extendOptions)
|
|
5
9
|
return component
|
|
6
10
|
}
|
|
11
|
+
|
|
12
|
+
export function getAsyncSuspense (commonProps) {
|
|
13
|
+
if (commonProps.type === 'component') {
|
|
14
|
+
return memo(forwardRef(function (props, ref) {
|
|
15
|
+
return createElement(AsyncSuspense,
|
|
16
|
+
extend(commonProps, {
|
|
17
|
+
innerProps: Object.assign({}, props, { ref })
|
|
18
|
+
})
|
|
19
|
+
)
|
|
20
|
+
}))
|
|
21
|
+
} else {
|
|
22
|
+
return function (props) {
|
|
23
|
+
return createElement(AsyncSuspense,
|
|
24
|
+
extend(commonProps, {
|
|
25
|
+
innerProps: props
|
|
26
|
+
})
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getLazyPage (getComponent) {
|
|
33
|
+
return function (props) {
|
|
34
|
+
return createElement(getComponent(), props)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const babylon = require('@babel/parser')
|
|
2
2
|
const MagicString = require('magic-string')
|
|
3
|
+
const { SourceMapConsumer, SourceMapGenerator } = require('source-map')
|
|
3
4
|
const traverse = require('@babel/traverse').default
|
|
4
5
|
const t = require('@babel/types')
|
|
5
6
|
const formatCodeFrame = require('@babel/code-frame')
|
|
@@ -625,7 +626,12 @@ function compileScriptSetup (
|
|
|
625
626
|
_s.appendRight(endOffset, '})')
|
|
626
627
|
|
|
627
628
|
return {
|
|
628
|
-
content: _s.toString()
|
|
629
|
+
content: _s.toString(),
|
|
630
|
+
map: _s.generateMap({
|
|
631
|
+
source: filePath,
|
|
632
|
+
hires: true,
|
|
633
|
+
includeContent: true
|
|
634
|
+
})
|
|
629
635
|
}
|
|
630
636
|
}
|
|
631
637
|
|
|
@@ -1165,14 +1171,30 @@ function getCtor (ctorType) {
|
|
|
1165
1171
|
return ctor
|
|
1166
1172
|
}
|
|
1167
1173
|
|
|
1168
|
-
module.exports = function (content) {
|
|
1174
|
+
module.exports = async function (content, sourceMap) {
|
|
1169
1175
|
const { queryObj } = parseRequest(this.resource)
|
|
1170
1176
|
const { ctorType, lang } = queryObj
|
|
1171
1177
|
const filePath = this.resourcePath
|
|
1172
|
-
const
|
|
1178
|
+
const callback = this.async()
|
|
1179
|
+
let finalSourceMap = null
|
|
1180
|
+
const {
|
|
1181
|
+
content: callbackContent,
|
|
1182
|
+
map
|
|
1183
|
+
} = compileScriptSetup({
|
|
1173
1184
|
content,
|
|
1174
1185
|
lang
|
|
1175
1186
|
}, ctorType, filePath)
|
|
1176
|
-
|
|
1177
|
-
|
|
1187
|
+
finalSourceMap = map
|
|
1188
|
+
if (sourceMap) {
|
|
1189
|
+
const compiledMapConsumer = await new SourceMapConsumer(map)
|
|
1190
|
+
const compiledMapGenerator = SourceMapGenerator.fromSourceMap(compiledMapConsumer)
|
|
1191
|
+
|
|
1192
|
+
const originalConsumer = await new SourceMapConsumer(sourceMap)
|
|
1193
|
+
compiledMapGenerator.applySourceMap(
|
|
1194
|
+
originalConsumer,
|
|
1195
|
+
filePath // 需要确保与原始映射的source路径一致
|
|
1196
|
+
)
|
|
1197
|
+
finalSourceMap = compiledMapGenerator.toJSON()
|
|
1198
|
+
}
|
|
1199
|
+
callback(null, callbackContent, finalSourceMap)
|
|
1178
1200
|
}
|
|
@@ -38,7 +38,7 @@ const endTag = new RegExp(('^<\\/' + qnameCapture + '[^>]*>'))
|
|
|
38
38
|
const doctype = /^<!DOCTYPE [^>]+>/i
|
|
39
39
|
const comment = /^<!--/
|
|
40
40
|
const conditionalComment = /^<!\[/
|
|
41
|
-
const specialClassReg = /^mpx-((cover-)?view|button|navigator|picker-view|input|textarea)$/
|
|
41
|
+
const specialClassReg = /^mpx-((cover-)?view|button|navigator|picker-view|input|textarea|page-container)$/
|
|
42
42
|
let IS_REGEX_CAPTURING_BROKEN = false
|
|
43
43
|
'x'.replace(/x(.)?/g, function (m, g) {
|
|
44
44
|
IS_REGEX_CAPTURING_BROKEN = g === ''
|
|
@@ -180,7 +180,7 @@ const i18nModuleName = '_i'
|
|
|
180
180
|
const stringifyWxsPath = '~' + normalize.lib('runtime/stringify.wxs')
|
|
181
181
|
const stringifyModuleName = '_s'
|
|
182
182
|
const optionalChainWxsPath = '~' + normalize.lib('runtime/oc.wxs')
|
|
183
|
-
const optionalChainWxsName = '_o
|
|
183
|
+
const optionalChainWxsName = '_oc' // 改成_oc解决web下_o重名问题
|
|
184
184
|
|
|
185
185
|
const tagRES = /(\{\{(?:.|\n|\r)+?\}\})(?!})/
|
|
186
186
|
const tagRE = /\{\{((?:.|\n|\r)+?)\}\}(?!})/
|
|
@@ -581,7 +581,8 @@ function parseComponent (content, options) {
|
|
|
581
581
|
let text = content.slice(currentBlock.start, currentBlock.end)
|
|
582
582
|
// pad content so that linters and pre-processors can output correct
|
|
583
583
|
// line numbers in errors and warnings
|
|
584
|
-
|
|
584
|
+
// stylus编译遇到大量空行时会出现栈溢出,故针对stylus不走pad
|
|
585
|
+
if (options.pad && !(currentBlock.tag === 'style' && currentBlock.lang === 'stylus')) {
|
|
585
586
|
text = padContent(currentBlock, options.pad) + text
|
|
586
587
|
}
|
|
587
588
|
currentBlock.content = text
|
|
@@ -1110,8 +1111,28 @@ function processStyleReact (el, options) {
|
|
|
1110
1111
|
}])
|
|
1111
1112
|
}
|
|
1112
1113
|
|
|
1113
|
-
|
|
1114
|
-
|
|
1114
|
+
// 原生组件支持 xx-class 与 xx-style(xx-class 将会被合并到 xx-style 中)
|
|
1115
|
+
const match = el.tag.match(specialClassReg)
|
|
1116
|
+
if (match) {
|
|
1117
|
+
let staticClassNames
|
|
1118
|
+
switch (el.tag) {
|
|
1119
|
+
case 'mpx-view':
|
|
1120
|
+
case 'mpx-cover-view':
|
|
1121
|
+
case 'mpx-button':
|
|
1122
|
+
case 'mpx-navigator':
|
|
1123
|
+
staticClassNames = ['hover']
|
|
1124
|
+
break
|
|
1125
|
+
case 'mpx-page-container':
|
|
1126
|
+
staticClassNames = ['custom', 'overlay']
|
|
1127
|
+
break
|
|
1128
|
+
case 'mpx-input':
|
|
1129
|
+
case 'mpx-textarea':
|
|
1130
|
+
staticClassNames = ['placeholder']
|
|
1131
|
+
break
|
|
1132
|
+
case 'mpx-picker-view':
|
|
1133
|
+
staticClassNames = ['mask', 'indicator']
|
|
1134
|
+
break
|
|
1135
|
+
}
|
|
1115
1136
|
staticClassNames.forEach((className) => {
|
|
1116
1137
|
let staticClass = el.attrsMap[className + '-class'] || ''
|
|
1117
1138
|
let staticStyle = getAndRemoveAttr(el, className + '-style').val || ''
|
|
@@ -2002,7 +2023,7 @@ function postProcessFor (el) {
|
|
|
2002
2023
|
function postProcessForReact (el) {
|
|
2003
2024
|
if (el.for) {
|
|
2004
2025
|
if (el.for.key) {
|
|
2005
|
-
addExp(el, `this.__getWxKey(${el.for.item || 'item'}, ${stringify(el.for.key)}, ${el.for.index || 'index'})`, false, 'key')
|
|
2026
|
+
addExp(el, `this.__getWxKey(${el.for.item || 'item'}, ${stringify(el.for.key === '_' ? 'index' : el.for.key)}, ${el.for.index || 'index'})`, false, 'key')
|
|
2006
2027
|
addAttrs(el, [{
|
|
2007
2028
|
name: 'key',
|
|
2008
2029
|
value: el.for.key
|
|
@@ -72,13 +72,26 @@ const isNativeMiniTag = makeMap(
|
|
|
72
72
|
* 是否为mpx内置组件
|
|
73
73
|
* collected from packages/webpack-plugin/lib/runtime/components/web/
|
|
74
74
|
*/
|
|
75
|
-
const
|
|
75
|
+
const isBuildInWebTag = makeMap(
|
|
76
76
|
'mpx-image,mpx-picker-view,mpx-slider,mpx-textarea,mpx-input,mpx-picker,' +
|
|
77
77
|
'mpx-swiper-item,mpx-video,mpx-button,mpx-keep-alive,mpx-progress,' +
|
|
78
78
|
'mpx-swiper,mpx-view,mpx-checkbox-group,mpx-movable-area,mpx-radio-group,' +
|
|
79
79
|
'mpx-switch,mpx-web-view,mpx-checkbox,mpx-movable-view,mpx-radio,' +
|
|
80
80
|
'mpx-tab-bar-container,mpx-form,mpx-navigator,mpx-rich-text,mpx-tab-bar,' +
|
|
81
|
-
'mpx-icon,mpx-picker-view-column,mpx-scroll-view,mpx-text'
|
|
81
|
+
'mpx-icon,mpx-picker-view-column,mpx-scroll-view,mpx-text,mpx-page-container'
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 是否为mpx2rn内置组件
|
|
86
|
+
*/
|
|
87
|
+
const isBuildInReactTag = makeMap(
|
|
88
|
+
'mpx-web-view,mpx-view,mpx-video,mpx-textarea,mpx-text,mpx-switch,' +
|
|
89
|
+
'mpx-swiper,mpx-swiper-item,mpx-simple-view,mpx-simple-text,mpx-scroll-view,' +
|
|
90
|
+
'mpx-root-portal,mpx-radio,mpx-radio-group,mpx-navigator,mpx-movable-view,' +
|
|
91
|
+
'mpx-movable-area,mpx-label,mpx-keyboard-avoiding-view,mpx-input,mpx-inline-text,' +
|
|
92
|
+
'mpx-image,mpx-form,mpx-checkbox,mpx-checkbox-group,mpx-button,' +
|
|
93
|
+
'mpx-rich-text,mpx-portal,mpx-popup,mpx-picker-view-column,mpx-picker-view,mpx-picker,' +
|
|
94
|
+
'mpx-icon,mpx-canvas'
|
|
82
95
|
)
|
|
83
96
|
|
|
84
97
|
const isSpace = makeMap('ensp,emsp,nbsp')
|
|
@@ -105,11 +118,12 @@ module.exports = {
|
|
|
105
118
|
isVoidTag,
|
|
106
119
|
isNonPhrasingTag,
|
|
107
120
|
isRichTextTag,
|
|
108
|
-
|
|
121
|
+
isBuildInWebTag,
|
|
109
122
|
isUnaryTag,
|
|
110
123
|
isSpace,
|
|
111
124
|
isContWidth,
|
|
112
125
|
isContHeight,
|
|
113
126
|
isNativeMiniTag,
|
|
114
|
-
isContConRow
|
|
127
|
+
isContConRow,
|
|
128
|
+
isBuildInReactTag
|
|
115
129
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function transSubpackage (asyncSubpackageNameRules, tarRoot) {
|
|
2
|
+
// 如果没有tarRoot,则无需进行tarRoot的修改,因此
|
|
3
|
+
if (tarRoot && Array.isArray(asyncSubpackageNameRules) && asyncSubpackageNameRules.length >= 1) {
|
|
4
|
+
for (const item of asyncSubpackageNameRules) {
|
|
5
|
+
if (item?.from) {
|
|
6
|
+
const fromPaths = Array.isArray(item.from) ? item.from : [item.from]
|
|
7
|
+
if (fromPaths.includes(tarRoot)) {
|
|
8
|
+
tarRoot = item.to
|
|
9
|
+
break
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return tarRoot
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = {
|
|
18
|
+
transSubpackage
|
|
19
|
+
}
|
package/lib/web/script-helper.js
CHANGED
|
@@ -13,7 +13,7 @@ function stringifyRequest (loaderContext, request) {
|
|
|
13
13
|
|
|
14
14
|
function getAsyncChunkName (chunkName) {
|
|
15
15
|
if (chunkName && typeof chunkName !== 'boolean') {
|
|
16
|
-
return `/* webpackChunkName: "${chunkName}" */`
|
|
16
|
+
return `/* webpackChunkName: "${chunkName}/index" */`
|
|
17
17
|
}
|
|
18
18
|
return ''
|
|
19
19
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpxjs/webpack-plugin",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.8-beta.1",
|
|
4
4
|
"description": "mpx compile core",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mpx"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@better-scroll/wheel": "^2.5.1",
|
|
29
29
|
"@better-scroll/zoom": "^2.5.1",
|
|
30
30
|
"@mpxjs/template-engine": "^2.8.7",
|
|
31
|
-
"@mpxjs/utils": "^2.10.
|
|
31
|
+
"@mpxjs/utils": "^2.10.8",
|
|
32
32
|
"acorn": "^8.11.3",
|
|
33
33
|
"acorn-walk": "^7.2.0",
|
|
34
34
|
"async": "^2.6.0",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
85
|
"@d11/react-native-fast-image": "^8.6.12",
|
|
86
|
-
"@mpxjs/api-proxy": "^2.10.
|
|
86
|
+
"@mpxjs/api-proxy": "^2.10.8",
|
|
87
87
|
"@types/babel-traverse": "^6.25.4",
|
|
88
88
|
"@types/babel-types": "^7.0.4",
|
|
89
89
|
"@types/react": "^18.2.79",
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
import { ComponentType, ReactNode, Component, Fragment, Suspense } from 'react'
|
|
2
|
-
import { View, Text, Image, StyleSheet, TouchableOpacity } from 'react-native'
|
|
3
|
-
import FastImage from '@d11/react-native-fast-image'
|
|
4
|
-
|
|
5
|
-
const styles = StyleSheet.create({
|
|
6
|
-
container: {
|
|
7
|
-
flex: 1,
|
|
8
|
-
padding: 20,
|
|
9
|
-
backgroundColor: '#fff'
|
|
10
|
-
},
|
|
11
|
-
loadingImage: {
|
|
12
|
-
width: 100,
|
|
13
|
-
height: 100,
|
|
14
|
-
marginTop: 220,
|
|
15
|
-
alignSelf: 'center'
|
|
16
|
-
},
|
|
17
|
-
buttonText: {
|
|
18
|
-
color: '#fff',
|
|
19
|
-
fontSize: 16,
|
|
20
|
-
fontWeight: '500',
|
|
21
|
-
textAlign: 'center'
|
|
22
|
-
},
|
|
23
|
-
errorImage: {
|
|
24
|
-
marginTop: 80,
|
|
25
|
-
width: 220,
|
|
26
|
-
aspectRatio: 1,
|
|
27
|
-
alignSelf: 'center'
|
|
28
|
-
},
|
|
29
|
-
errorText: {
|
|
30
|
-
fontSize: 16,
|
|
31
|
-
textAlign: 'center',
|
|
32
|
-
color: '#333',
|
|
33
|
-
marginBottom: 20
|
|
34
|
-
},
|
|
35
|
-
retryButton: {
|
|
36
|
-
position: 'absolute',
|
|
37
|
-
bottom: 54,
|
|
38
|
-
left: 20,
|
|
39
|
-
right: 20,
|
|
40
|
-
backgroundColor: '#fff',
|
|
41
|
-
paddingVertical: 15,
|
|
42
|
-
borderRadius: 30,
|
|
43
|
-
marginTop: 40,
|
|
44
|
-
borderWidth: 1,
|
|
45
|
-
borderColor: '#FF5F00'
|
|
46
|
-
},
|
|
47
|
-
retryButtonText: {
|
|
48
|
-
color: '#FF5F00',
|
|
49
|
-
fontSize: 16,
|
|
50
|
-
fontWeight: '500',
|
|
51
|
-
textAlign: 'center'
|
|
52
|
-
}
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
type AsyncType = 'page' | 'component'
|
|
56
|
-
|
|
57
|
-
interface PropsType<T extends AsyncType> {
|
|
58
|
-
type: T
|
|
59
|
-
props: object
|
|
60
|
-
loading: ComponentType<unknown>
|
|
61
|
-
fallback: ComponentType<unknown>
|
|
62
|
-
children: (props: unknown) => ReactNode
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
interface StateType {
|
|
66
|
-
hasError: boolean,
|
|
67
|
-
key: number
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
interface ComponentError extends Error {
|
|
71
|
-
request?: string
|
|
72
|
-
type: 'timeout' | 'fail'
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const DefaultLoading = () => {
|
|
76
|
-
return (
|
|
77
|
-
<View style={styles.container}>
|
|
78
|
-
<FastImage
|
|
79
|
-
style={styles.loadingImage}
|
|
80
|
-
source={{ uri: 'https://dpubstatic.udache.com/static/dpubimg/439jiCVOtNOnEv9F2LaDs_loading.gif' }}
|
|
81
|
-
resizeMode={FastImage.resizeMode.contain}></FastImage>
|
|
82
|
-
</View>
|
|
83
|
-
)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
interface DefaultFallbackProps {
|
|
87
|
-
onReload: () => void
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const DefaultFallback = ({ onReload }: DefaultFallbackProps) => {
|
|
91
|
-
return (
|
|
92
|
-
<View style={styles.container}>
|
|
93
|
-
<Image
|
|
94
|
-
source={{ uri: 'https://dpubstatic.udache.com/static/dpubimg/Vak5mZvezPpKV5ZJI6P9b_drn-fallbak.png' }}
|
|
95
|
-
style={styles.errorImage}
|
|
96
|
-
resizeMode="contain"
|
|
97
|
-
/>
|
|
98
|
-
<Text style={styles.errorText}>网络出了点问题,请查看网络环境</Text>
|
|
99
|
-
<TouchableOpacity
|
|
100
|
-
style={styles.retryButton}
|
|
101
|
-
onPress={onReload}
|
|
102
|
-
activeOpacity={0.7}
|
|
103
|
-
>
|
|
104
|
-
<Text style={styles.retryButtonText}>点击重试</Text>
|
|
105
|
-
</TouchableOpacity>
|
|
106
|
-
</View>
|
|
107
|
-
)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export default class AsyncContainer extends Component<PropsType<AsyncType>, StateType> {
|
|
111
|
-
private suspenseFallback: ReactNode
|
|
112
|
-
private errorFallback: ReactNode
|
|
113
|
-
|
|
114
|
-
constructor (props: PropsType<AsyncType>) {
|
|
115
|
-
super(props)
|
|
116
|
-
this.state = {
|
|
117
|
-
hasError: false,
|
|
118
|
-
key: 0
|
|
119
|
-
}
|
|
120
|
-
this.suspenseFallback = this.getSuspenseFallback()
|
|
121
|
-
this.errorFallback = this.getErrorFallback()
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// render 阶段收集到的错误
|
|
125
|
-
static getDerivedStateFromError (error: ComponentError): StateType | undefined {
|
|
126
|
-
if (error.name === 'ChunkLoadError') {
|
|
127
|
-
return {
|
|
128
|
-
hasError: true,
|
|
129
|
-
key: 0
|
|
130
|
-
}
|
|
131
|
-
} else {
|
|
132
|
-
// 被外层捕获
|
|
133
|
-
throw error
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
componentDidCatch (error: ComponentError): void {
|
|
138
|
-
if (error.name === 'ChunkLoadError' && this.props.type === 'component') {
|
|
139
|
-
const request = error.request || ''
|
|
140
|
-
const subpackage = request.split('/').filter((i: string) => !!i)[0]
|
|
141
|
-
global.onLazyLoadError({
|
|
142
|
-
type: 'subpackage',
|
|
143
|
-
subpackage: [subpackage],
|
|
144
|
-
errMsg: `loadSubpackage: ${error.type}`
|
|
145
|
-
})
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
reloadPage () {
|
|
150
|
-
this.setState((prevState) => {
|
|
151
|
-
return {
|
|
152
|
-
hasError: false,
|
|
153
|
-
key: prevState.key + 1
|
|
154
|
-
}
|
|
155
|
-
})
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
getSuspenseFallback () {
|
|
159
|
-
if (this.props.type === 'page') {
|
|
160
|
-
const Fallback = this.props.loading || DefaultLoading
|
|
161
|
-
return <Fallback />
|
|
162
|
-
} else {
|
|
163
|
-
const Fallback = this.props.loading
|
|
164
|
-
return <Fallback {...this.props.props}></Fallback>
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
getErrorFallback () {
|
|
169
|
-
if (this.props.type === 'page') {
|
|
170
|
-
const Fallback = this.props.fallback as ComponentType<DefaultFallbackProps> || DefaultFallback
|
|
171
|
-
return <Fallback onReload={this.reloadPage.bind(this)}></Fallback>
|
|
172
|
-
} else {
|
|
173
|
-
const Fallback = this.props.loading
|
|
174
|
-
return <Fallback {...this.props.props}></Fallback>
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
render () {
|
|
179
|
-
if (this.state.hasError) {
|
|
180
|
-
return this.errorFallback
|
|
181
|
-
} else {
|
|
182
|
-
return (
|
|
183
|
-
<Suspense fallback={this.suspenseFallback} key={this.state.key}>
|
|
184
|
-
{this.props.children(this.props.props)}
|
|
185
|
-
</Suspense>
|
|
186
|
-
)
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|