@mpxjs/webpack-plugin 2.10.14-beta.2 → 2.10.14-beta.4

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.
@@ -0,0 +1,102 @@
1
+ const Dependency = require('webpack/lib/Dependency')
2
+ const makeSerializable = require('webpack/lib/util/makeSerializable')
3
+ const ModuleDependency = require('webpack/lib/dependencies/ModuleDependency')
4
+ const { RetryRuntimeGlobal } = require('../retry-runtime-module')
5
+
6
+ class ImportDependency extends ModuleDependency {
7
+ /**
8
+ * @param {string} request the request
9
+ * @param {[number, number]} range expression range
10
+ * @param {string[][]=} referencedExports list of referenced exports
11
+ */
12
+ constructor (request, range, referencedExports, extraOptions) {
13
+ super(request)
14
+ this.range = range
15
+ this.referencedExports = referencedExports
16
+ this.extraOptions = extraOptions
17
+ }
18
+
19
+ get type () {
20
+ return 'import()'
21
+ }
22
+
23
+ get category () {
24
+ return 'esm'
25
+ }
26
+
27
+ /**
28
+ * Returns list of exports referenced by this dependency
29
+ * @param {ModuleGraph} moduleGraph module graph
30
+ * @param {RuntimeSpec} runtime the runtime for which the module is analysed
31
+ * @returns {(string[] | ReferencedExport)[]} referenced exports
32
+ */
33
+ getReferencedExports (moduleGraph, runtime) {
34
+ return this.referencedExports
35
+ ? this.referencedExports.map((e) => ({
36
+ name: e,
37
+ canMangle: false
38
+ }))
39
+ : Dependency.EXPORTS_OBJECT_REFERENCED
40
+ }
41
+
42
+ serialize (context) {
43
+ context.write(this.range)
44
+ context.write(this.referencedExports)
45
+ context.write(this.extraOptions)
46
+ super.serialize(context)
47
+ }
48
+
49
+ deserialize (context) {
50
+ this.range = context.read()
51
+ this.referencedExports = context.read()
52
+ this.extraOptions = context.read()
53
+ super.deserialize(context)
54
+ }
55
+ }
56
+
57
+ makeSerializable(ImportDependency, '@mpxjs/webpack-plugin/lib/dependencies/ImportDependency')
58
+
59
+ ImportDependency.Template = class ImportDependencyTemplate extends (
60
+ ModuleDependency.Template
61
+ ) {
62
+ /**
63
+ * @param {Dependency} dependency the dependency for which the template should be applied
64
+ * @param {ReplaceSource} source the current replace source which can be modified
65
+ * @param {DependencyTemplateContext} templateContext the context object
66
+ * @returns {void}
67
+ */
68
+ apply (
69
+ dependency,
70
+ source,
71
+ { runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements }
72
+ ) {
73
+ const dep = /** @type {ImportDependency} */ (dependency)
74
+ const block = /** @type {AsyncDependenciesBlock} */ (
75
+ moduleGraph.getParentBlock(dep)
76
+ )
77
+ let content = runtimeTemplate.moduleNamespacePromise({
78
+ chunkGraph,
79
+ block: block,
80
+ module: /** @type {Module} */ (moduleGraph.getModule(dep)),
81
+ request: dep.request,
82
+ strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule,
83
+ message: 'import()',
84
+ runtimeRequirements
85
+ })
86
+ // replace fakeType by 9 to fix require.async to commonjs2 module like 'module.exports = function(){...}'
87
+ content = content.replace(/(__webpack_require__\.t\.bind\(.+,\s*)(\d+)(\s*\))/, (_, p1, p2, p3) => {
88
+ return p1 + '9' + p3
89
+ })
90
+
91
+ // require.async 的场景且配置了重试次数才注入 RetryRuntimeModule
92
+ const extraOptions = dep.extraOptions || {}
93
+ if (extraOptions.isRequireAsync && extraOptions.retryRequireAsync && extraOptions.retryRequireAsync.times > 0) {
94
+ runtimeRequirements.add(RetryRuntimeGlobal)
95
+ content = `${RetryRuntimeGlobal}(function() { return ${content} }, ${extraOptions.retryRequireAsync.times}, ${extraOptions.retryRequireAsync.interval})`
96
+ }
97
+
98
+ source.replace(dep.range[0], dep.range[1] - 1, content)
99
+ }
100
+ }
101
+
102
+ module.exports = ImportDependency
package/lib/index.js CHANGED
@@ -14,8 +14,7 @@ const EntryPlugin = require('webpack/lib/EntryPlugin')
14
14
  const JavascriptModulesPlugin = require('webpack/lib/javascript/JavascriptModulesPlugin')
15
15
  const FlagEntryExportAsUsedPlugin = require('webpack/lib/FlagEntryExportAsUsedPlugin')
16
16
  const FileSystemInfo = require('webpack/lib/FileSystemInfo')
17
- const ImportDependency = require('webpack/lib/dependencies/ImportDependency')
18
- const ImportDependencyTemplate = require('./dependencies/ImportDependencyTemplate')
17
+ const ImportDependency = require('./dependencies/ImportDependency')
19
18
  const AsyncDependenciesBlock = require('webpack/lib/AsyncDependenciesBlock')
20
19
  const ProvidePlugin = require('webpack/lib/ProvidePlugin')
21
20
  const normalize = require('./utils/normalize')
@@ -696,7 +695,8 @@ class MpxWebpackPlugin {
696
695
  compilation.dependencyFactories.set(RequireExternalDependency, new NullFactory())
697
696
  compilation.dependencyTemplates.set(RequireExternalDependency, new RequireExternalDependency.Template())
698
697
 
699
- compilation.dependencyTemplates.set(ImportDependency, new ImportDependencyTemplate())
698
+ compilation.dependencyFactories.set(ImportDependency, normalModuleFactory)
699
+ compilation.dependencyTemplates.set(ImportDependency, new ImportDependency.Template())
700
700
  })
701
701
 
702
702
  compiler.hooks.thisCompilation.tap('MpxWebpackPlugin', (compilation, { normalModuleFactory }) => {
@@ -1451,10 +1451,6 @@ class MpxWebpackPlugin {
1451
1451
  if (mpx.supportRequireAsync) {
1452
1452
  if (isWeb(mpx.mode) || isReact(mpx.mode)) {
1453
1453
  if (isReact(mpx.mode)) tarRoot = transSubpackage(mpx.transSubpackageRules, tarRoot)
1454
- request = addQuery(request, {
1455
- isRequireAsync: true,
1456
- retryRequireAsync: JSON.stringify(this.options.retryRequireAsync)
1457
- })
1458
1454
  const depBlock = new AsyncDependenciesBlock(
1459
1455
  {
1460
1456
  name: tarRoot + '/index'
@@ -1462,7 +1458,10 @@ class MpxWebpackPlugin {
1462
1458
  expr.loc,
1463
1459
  request
1464
1460
  )
1465
- const dep = new ImportDependency(request, expr.range)
1461
+ const dep = new ImportDependency(request, expr.range, undefined, {
1462
+ isRequireAsync: true,
1463
+ retryRequireAsync: this.options.retryRequireAsync
1464
+ })
1466
1465
  dep.loc = expr.loc
1467
1466
  depBlock.addDependency(dep)
1468
1467
  parser.state.current.addBlock(depBlock)
@@ -1,6 +1,6 @@
1
- import React, { useContext, useEffect } from 'react';
1
+ import React, { useContext, useEffect, useRef } from 'react';
2
2
  import { Keyboard, View } from 'react-native';
3
- import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing } from 'react-native-reanimated';
3
+ import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing, cancelAnimation } from 'react-native-reanimated';
4
4
  import { KeyboardAvoidContext } from './context';
5
5
  import { isIOS } from './utils';
6
6
  const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
@@ -9,14 +9,25 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
9
9
  const offset = useSharedValue(0);
10
10
  const basic = useSharedValue('auto');
11
11
  const keyboardAvoid = useContext(KeyboardAvoidContext);
12
+ // fix: 某些特殊机型下隐藏键盘可能会先触发一次 keyboardWillShow,
13
+ // 比如机型 iPhone 11 Pro,可能会导致显隐动画冲突
14
+ // 因此增加状态标记 + clearTimeout + cancelAnimation 来优化
15
+ const isShow = useRef(false);
16
+ const timerRef = useRef(null);
12
17
  const animatedStyle = useAnimatedStyle(() => ({
13
18
  transform: [{ translateY: -offset.value }],
14
19
  flexBasis: basic.value
15
20
  }));
16
21
  const resetKeyboard = () => {
22
+ if (!isShow.current) {
23
+ return;
24
+ }
25
+ isShow.current = false;
26
+ timerRef.current && clearTimeout(timerRef.current);
17
27
  if (keyboardAvoid?.current) {
18
28
  keyboardAvoid.current = null;
19
29
  }
30
+ cancelAnimation(offset);
20
31
  offset.value = withTiming(0, { duration, easing });
21
32
  basic.value = 'auto';
22
33
  };
@@ -30,16 +41,20 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
30
41
  if (isIOS) {
31
42
  subscriptions = [
32
43
  Keyboard.addListener('keyboardWillShow', (evt) => {
33
- if (!keyboardAvoid?.current)
44
+ if (!keyboardAvoid?.current || isShow.current) {
34
45
  return;
46
+ }
47
+ isShow.current = true;
48
+ timerRef.current && clearTimeout(timerRef.current);
35
49
  const { endCoordinates } = evt;
36
50
  const { ref, cursorSpacing = 0 } = keyboardAvoid.current;
37
- setTimeout(() => {
51
+ timerRef.current = setTimeout(() => {
38
52
  ref?.current?.measure((x, y, width, height, pageX, pageY) => {
39
53
  const aboveOffset = offset.value + pageY + height - endCoordinates.screenY;
40
54
  const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing;
41
55
  const belowValue = Math.min(endCoordinates.height, aboveOffset + cursorSpacing);
42
56
  const value = aboveOffset > 0 ? belowValue : aboveValue;
57
+ cancelAnimation(offset);
43
58
  offset.value = withTiming(value, { duration, easing }, (finished) => {
44
59
  if (finished) {
45
60
  // Set flexBasic after animation to trigger re-layout and reset layout information
@@ -55,8 +70,10 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
55
70
  else {
56
71
  subscriptions = [
57
72
  Keyboard.addListener('keyboardDidShow', (evt) => {
58
- if (!keyboardAvoid?.current)
73
+ if (!keyboardAvoid?.current || isShow.current) {
59
74
  return;
75
+ }
76
+ isShow.current = true;
60
77
  const { endCoordinates } = evt;
61
78
  const { ref, cursorSpacing = 0 } = keyboardAvoid.current;
62
79
  ref?.current?.measure((x, y, width, height, pageX, pageY) => {
@@ -65,6 +82,7 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
65
82
  const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing;
66
83
  const belowValue = Math.min(belowOffset, cursorSpacing);
67
84
  const value = aboveOffset > 0 ? belowValue : aboveValue;
85
+ cancelAnimation(offset);
68
86
  offset.value = withTiming(value, { duration, easing }, (finished) => {
69
87
  if (finished) {
70
88
  // Set flexBasic after animation to trigger re-layout and reset layout information
@@ -78,6 +96,7 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
78
96
  }
79
97
  return () => {
80
98
  subscriptions.forEach(subscription => subscription.remove());
99
+ timerRef.current && clearTimeout(timerRef.current);
81
100
  };
82
101
  }, [keyboardAvoid]);
83
102
  return (<View style={style} onTouchEnd={onTouchEnd}>
@@ -1,6 +1,6 @@
1
- import React, { ReactNode, useContext, useEffect } from 'react'
1
+ import React, { ReactNode, useContext, useEffect, useRef } from 'react'
2
2
  import { DimensionValue, EmitterSubscription, Keyboard, View, ViewStyle, NativeSyntheticEvent, NativeTouchEvent } from 'react-native'
3
- import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing } from 'react-native-reanimated'
3
+ import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing, cancelAnimation } from 'react-native-reanimated'
4
4
  import { KeyboardAvoidContext } from './context'
5
5
  import { isIOS } from './utils'
6
6
 
@@ -18,15 +18,30 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
18
18
  const basic = useSharedValue('auto')
19
19
  const keyboardAvoid = useContext(KeyboardAvoidContext)
20
20
 
21
+ // fix: 某些特殊机型下隐藏键盘可能会先触发一次 keyboardWillShow,
22
+ // 比如机型 iPhone 11 Pro,可能会导致显隐动画冲突
23
+ // 因此增加状态标记 + clearTimeout + cancelAnimation 来优化
24
+ const isShow = useRef<boolean>(false)
25
+ const timerRef = useRef<NodeJS.Timeout | null>(null)
26
+
21
27
  const animatedStyle = useAnimatedStyle(() => ({
22
28
  transform: [{ translateY: -offset.value }],
23
29
  flexBasis: basic.value as DimensionValue
24
30
  }))
25
31
 
26
32
  const resetKeyboard = () => {
33
+ if (!isShow.current) {
34
+ return
35
+ }
36
+
37
+ isShow.current = false
38
+ timerRef.current && clearTimeout(timerRef.current)
39
+
27
40
  if (keyboardAvoid?.current) {
28
41
  keyboardAvoid.current = null
29
42
  }
43
+
44
+ cancelAnimation(offset)
30
45
  offset.value = withTiming(0, { duration, easing })
31
46
  basic.value = 'auto'
32
47
  }
@@ -43,15 +58,23 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
43
58
  if (isIOS) {
44
59
  subscriptions = [
45
60
  Keyboard.addListener('keyboardWillShow', (evt: any) => {
46
- if (!keyboardAvoid?.current) return
61
+ if (!keyboardAvoid?.current || isShow.current) {
62
+ return
63
+ }
64
+
65
+ isShow.current = true
66
+ timerRef.current && clearTimeout(timerRef.current)
67
+
47
68
  const { endCoordinates } = evt
48
69
  const { ref, cursorSpacing = 0 } = keyboardAvoid.current
49
- setTimeout(() => {
70
+
71
+ timerRef.current = setTimeout(() => {
50
72
  ref?.current?.measure((x: number, y: number, width: number, height: number, pageX: number, pageY: number) => {
51
73
  const aboveOffset = offset.value + pageY + height - endCoordinates.screenY
52
74
  const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing
53
75
  const belowValue = Math.min(endCoordinates.height, aboveOffset + cursorSpacing)
54
76
  const value = aboveOffset > 0 ? belowValue : aboveValue
77
+ cancelAnimation(offset)
55
78
  offset.value = withTiming(value, { duration, easing }, (finished) => {
56
79
  if (finished) {
57
80
  // Set flexBasic after animation to trigger re-layout and reset layout information
@@ -66,15 +89,22 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
66
89
  } else {
67
90
  subscriptions = [
68
91
  Keyboard.addListener('keyboardDidShow', (evt: any) => {
69
- if (!keyboardAvoid?.current) return
92
+ if (!keyboardAvoid?.current || isShow.current) {
93
+ return
94
+ }
95
+
96
+ isShow.current = true
97
+
70
98
  const { endCoordinates } = evt
71
99
  const { ref, cursorSpacing = 0 } = keyboardAvoid.current
100
+
72
101
  ref?.current?.measure((x: number, y: number, width: number, height: number, pageX: number, pageY: number) => {
73
102
  const aboveOffset = pageY + height - endCoordinates.screenY
74
103
  const belowOffset = endCoordinates.height - aboveOffset
75
104
  const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing
76
105
  const belowValue = Math.min(belowOffset, cursorSpacing)
77
106
  const value = aboveOffset > 0 ? belowValue : aboveValue
107
+ cancelAnimation(offset)
78
108
  offset.value = withTiming(value, { duration, easing }, (finished) => {
79
109
  if (finished) {
80
110
  // Set flexBasic after animation to trigger re-layout and reset layout information
@@ -89,6 +119,7 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
89
119
 
90
120
  return () => {
91
121
  subscriptions.forEach(subscription => subscription.remove())
122
+ timerRef.current && clearTimeout(timerRef.current)
92
123
  }
93
124
  }, [keyboardAvoid])
94
125
 
@@ -891,4 +891,4 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
891
891
  })
892
892
  SwiperWrapper.displayName = 'MpxSwiperWrapper'
893
893
 
894
- export default SwiperWrapper
894
+ export default SwiperWrapper
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.10.14-beta.2",
3
+ "version": "2.10.14-beta.4",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -1,50 +0,0 @@
1
- const ModuleDependency = require('webpack/lib/dependencies/ModuleDependency')
2
- const { RetryRuntimeGlobal } = require('../retry-runtime-module')
3
- const parseRequest = require('../utils/parse-request')
4
-
5
- class ImportDependencyTemplate extends (
6
- ModuleDependency.Template
7
- ) {
8
- /**
9
- * @param {Dependency} dependency the dependency for which the template should be applied
10
- * @param {ReplaceSource} source the current replace source which can be modified
11
- * @param {DependencyTemplateContext} templateContext the context object
12
- * @returns {void}
13
- */
14
- apply (
15
- dependency,
16
- source,
17
- { runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements }
18
- ) {
19
- const dep = /** @type {ImportDependency} */ (dependency)
20
- const block = /** @type {AsyncDependenciesBlock} */ (
21
- moduleGraph.getParentBlock(dep)
22
- )
23
- let content = runtimeTemplate.moduleNamespacePromise({
24
- chunkGraph,
25
- block: block,
26
- module: /** @type {Module} */ (moduleGraph.getModule(dep)),
27
- request: dep.request,
28
- strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule,
29
- message: 'import()',
30
- runtimeRequirements
31
- })
32
- // replace fakeType by 9 to fix require.async to commonjs2 module like 'module.exports = function(){...}'
33
- content = content.replace(/(__webpack_require__\.t\.bind\(.+,\s*)(\d+)(\s*\))/, (_, p1, p2, p3) => {
34
- return p1 + '9' + p3
35
- })
36
-
37
- const { queryObj } = parseRequest(dep.request)
38
- const retryRequireAsync = queryObj.retryRequireAsync && JSON.parse(queryObj.retryRequireAsync)
39
-
40
- // require.async 的场景且配置了重试次数才注入 RetryRuntimeModule
41
- if (queryObj.isRequireAsync && retryRequireAsync && retryRequireAsync.times > 0) {
42
- runtimeRequirements.add(RetryRuntimeGlobal)
43
- content = `${RetryRuntimeGlobal}(function() { return ${content} }, ${retryRequireAsync.times}, ${retryRequireAsync.interval})`
44
- }
45
-
46
- source.replace(dep.range[0], dep.range[1] - 1, content)
47
- }
48
- }
49
-
50
- module.exports = ImportDependencyTemplate