@mpxjs/webpack-plugin 2.10.15 → 2.10.16

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.
@@ -6,7 +6,7 @@ const toPosix = require('../utils/to-posix')
6
6
  const async = require('async')
7
7
  const parseRequest = require('../utils/parse-request')
8
8
  const hasOwn = require('../utils/has-own')
9
- const { RetryRuntimeGlobal } = require('../retry-runtime-module')
9
+ const { RetryRuntimeGlobal } = require('./RetryRuntimeModule')
10
10
 
11
11
  class DynamicEntryDependency extends NullDependency {
12
12
  constructor (range, request, entryType, outputPath = '', packageRoot = '', relativePath = '', context = '', extraOptions = {}) {
@@ -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('./RetryRuntimeModule')
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
@@ -1,7 +1,7 @@
1
1
  const Template = require('webpack/lib/Template')
2
2
  const RuntimeModule = require('webpack/lib/RuntimeModule')
3
3
 
4
- const RetryRuntimeGlobal = '__webpack_require__.__retry'
4
+ const RetryRuntimeGlobal = '__webpack_require__.mpxR'
5
5
 
6
6
  class RetryRuntimeModule extends RuntimeModule {
7
7
  constructor () {
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')
@@ -77,8 +76,10 @@ const VirtualModulesPlugin = require('webpack-virtual-modules')
77
76
  const RuntimeGlobals = require('webpack/lib/RuntimeGlobals')
78
77
  const LoadAsyncChunkModule = require('./react/LoadAsyncChunkModule')
79
78
  const ExternalModule = require('webpack/lib/ExternalModule')
80
- const { RetryRuntimeModule, RetryRuntimeGlobal } = require('./retry-runtime-module')
81
- require('./utils/check-core-version-match')
79
+ const { RetryRuntimeModule, RetryRuntimeGlobal } = require('./dependencies/RetryRuntimeModule')
80
+ const checkVersionCompatibility = require('./utils/check-core-version-match')
81
+
82
+ checkVersionCompatibility()
82
83
 
83
84
  const isProductionLikeMode = options => {
84
85
  return options.mode === 'production' || !options.mode
@@ -696,7 +697,8 @@ class MpxWebpackPlugin {
696
697
  compilation.dependencyFactories.set(RequireExternalDependency, new NullFactory())
697
698
  compilation.dependencyTemplates.set(RequireExternalDependency, new RequireExternalDependency.Template())
698
699
 
699
- compilation.dependencyTemplates.set(ImportDependency, new ImportDependencyTemplate())
700
+ compilation.dependencyFactories.set(ImportDependency, normalModuleFactory)
701
+ compilation.dependencyTemplates.set(ImportDependency, new ImportDependency.Template())
700
702
  })
701
703
 
702
704
  compiler.hooks.thisCompilation.tap('MpxWebpackPlugin', (compilation, { normalModuleFactory }) => {
@@ -1451,10 +1453,6 @@ class MpxWebpackPlugin {
1451
1453
  if (mpx.supportRequireAsync) {
1452
1454
  if (isWeb(mpx.mode) || isReact(mpx.mode)) {
1453
1455
  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
1456
  const depBlock = new AsyncDependenciesBlock(
1459
1457
  {
1460
1458
  name: tarRoot + '/index'
@@ -1462,7 +1460,10 @@ class MpxWebpackPlugin {
1462
1460
  expr.loc,
1463
1461
  request
1464
1462
  )
1465
- const dep = new ImportDependency(request, expr.range)
1463
+ const dep = new ImportDependency(request, expr.range, undefined, {
1464
+ isRequireAsync: true,
1465
+ retryRequireAsync: this.options.retryRequireAsync
1466
+ })
1466
1467
  dep.loc = expr.loc
1467
1468
  depBlock.addDependency(dep)
1468
1469
  parser.state.current.addBlock(depBlock)
@@ -8,6 +8,18 @@ module.exports = function ({ print }) {
8
8
  el.isBuiltIn = true
9
9
  return 'mpx-slider'
10
10
  },
11
+ android (tag, { el }) {
12
+ el.isBuiltIn = true
13
+ return 'mpx-slider'
14
+ },
15
+ harmony (tag, { el }) {
16
+ el.isBuiltIn = true
17
+ return 'mpx-slider'
18
+ },
19
+ ios (tag, { el }) {
20
+ el.isBuiltIn = true
21
+ return 'mpx-slider'
22
+ },
11
23
  props: [
12
24
  {
13
25
  test: /^color$/,
@@ -11,7 +11,7 @@ const JD_UNSUPPORTED_TAG_NAME_ARR = ['functional-page-navigator', 'live-pusher',
11
11
  // 快应用不支持的标签集合
12
12
  const QA_UNSUPPORTED_TAG_NAME_ARR = ['movable-view', 'movable-area', 'open-data', 'official-account', 'editor', 'functional-page-navigator', 'live-player', 'live-pusher', 'ad', 'cover-image']
13
13
  // RN不支持的标签集合
14
- const RN_UNSUPPORTED_TAG_NAME_ARR = ['open-data', 'official-account', 'editor', 'functional-page-navigator', 'live-player', 'live-pusher', 'ad', 'slider', 'audio', 'camera', 'match-media', 'page-container', 'editor', 'keyboard-accessory', 'map']
14
+ const RN_UNSUPPORTED_TAG_NAME_ARR = ['open-data', 'official-account', 'editor', 'functional-page-navigator', 'live-player', 'live-pusher', 'ad', 'audio', 'camera', 'match-media', 'page-container', 'editor', 'keyboard-accessory', 'map']
15
15
 
16
16
  /**
17
17
  * @param {function(object): function} print
@@ -16,6 +16,8 @@ module.exports = class AddEnvPlugin {
16
16
  apply (resolver) {
17
17
  const target = resolver.ensureHook(this.target)
18
18
  const env = this.env
19
+ const envPattern = new RegExp(`\\.${env}(\\.|$)`)
20
+
19
21
  resolver.getHook(this.source).tapAsync('AddEnvPlugin', (request, resolveContext, callback) => {
20
22
  if (request.env) {
21
23
  return callback()
@@ -32,11 +34,22 @@ module.exports = class AddEnvPlugin {
32
34
  }
33
35
  // 当前资源没有后缀名或者路径不符合fileConditionRules规则时,直接返回
34
36
  if (!extname || !matchCondition(resourcePath, this.fileConditionRules)) return callback()
37
+
35
38
  const queryObj = parseQuery(request.query || '?')
36
39
  queryObj.infix = `${queryObj.infix || ''}.${env}`
40
+
41
+ const resourceBasename = path.basename(resourcePath)
42
+ // 如果 infix 与 resourcePath 无法匹配,则认为未命中env
43
+ if (envPattern.test(resourceBasename) && resourceBasename.includes(queryObj.infix)) {
44
+ request.query = stringifyQuery(queryObj)
45
+ request.env = obj.env
46
+ return callback()
47
+ }
48
+
37
49
  obj.query = stringifyQuery(queryObj)
38
50
  obj.path = addInfix(resourcePath, env, extname)
39
51
  obj.relativePath = request.relativePath && addInfix(request.relativePath, env, extname)
52
+
40
53
  resolver.doResolve(target, Object.assign({}, request, obj), 'add env: ' + env, resolveContext, callback)
41
54
  })
42
55
  }
@@ -17,6 +17,9 @@ module.exports = class AddModePlugin {
17
17
  const target = resolver.ensureHook(this.target)
18
18
  const { options = {}, mode } = this
19
19
  const { defaultMode, fileConditionRules, implicitMode } = options
20
+ const modePattern = new RegExp(`\\.${mode}(\\.|$)`)
21
+ const defaultModePattern = new RegExp(`\\.${defaultMode}(\\.|$)`)
22
+
20
23
  resolver.getHook(this.source).tapAsync('AddModePlugin', (request, resolveContext, callback) => {
21
24
  if (request.mode || request.env) {
22
25
  return callback()
@@ -33,13 +36,28 @@ module.exports = class AddModePlugin {
33
36
  }
34
37
  // 当前资源没有后缀名或者路径不符合fileConditionRules规则时,直接返回
35
38
  if (!extname || !matchCondition(resourcePath, fileConditionRules)) return callback()
39
+
36
40
  const queryObj = parseQuery(request.query || '?')
37
41
  const queryInfix = queryObj.infix
38
42
  if (!implicitMode) queryObj.mode = mode
39
43
  queryObj.infix = `${queryInfix || ''}.${mode}`
44
+
45
+ // 如果已经确认是mode后缀的文件,添加query与mode后直接返回
46
+ if (modePattern.test(path.basename(resourcePath))) {
47
+ request.query = stringifyQuery(queryObj)
48
+ request.mode = obj.mode
49
+ return callback()
50
+ } else if (defaultMode && defaultModePattern.test(path.basename(resourcePath))) {
51
+ queryObj.infix = `${queryInfix || ''}.${defaultMode}`
52
+ request.query = stringifyQuery(queryObj)
53
+ request.mode = obj.mode
54
+ return callback()
55
+ }
56
+
40
57
  obj.query = stringifyQuery(queryObj)
41
58
  obj.path = addInfix(resourcePath, mode, extname)
42
59
  obj.relativePath = request.relativePath && addInfix(request.relativePath, mode, extname)
60
+
43
61
  resolver.doResolve(target, Object.assign({}, request, obj), 'add mode: ' + mode, resolveContext, (err, result) => {
44
62
  if (defaultMode && !result) {
45
63
  queryObj.infix = `${queryInfix || ''}.${defaultMode}`
@@ -17,12 +17,12 @@ import { View } from 'react-native';
17
17
  import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing, runOnJS } from 'react-native-reanimated';
18
18
  import useInnerProps from './getInnerListeners';
19
19
  import useNodesRef from './useNodesRef';
20
- import { useLayout, useTransformStyle, extendObject } from './utils';
20
+ import { useLayout, useTransformStyle, extendObject, useRunOnJSCallback } from './utils';
21
21
  import Portal from './mpx-portal';
22
22
  const Progress = forwardRef((props, ref) => {
23
- const { percent = 0, 'stroke-width': strokeWidth = 6, color, activeColor = color || '#09BB07', backgroundColor = '#EBEBEB', active = false, 'active-mode': activeMode = 'backwards', duration = 30, bindactiveend, style = {}, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
23
+ const { percent = 0, 'stroke-width': strokeWidth = 6, color, activeColor = color || '#09BB07', backgroundColor = '#EBEBEB', active = false, 'active-mode': activeMode = 'backwards', duration = 30, style = {}, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
24
24
  const nodeRef = useRef(null);
25
- const propsRef = useRef({});
25
+ const propsRef = useRef(props);
26
26
  propsRef.current = props;
27
27
  // 进度值状态
28
28
  const [lastPercent, setLastPercent] = useState(0);
@@ -44,6 +44,21 @@ const Progress = forwardRef((props, ref) => {
44
44
  useNodesRef(props, ref, nodeRef, {
45
45
  style: normalStyle
46
46
  });
47
+ // 使用 useRunOnJSCallback 处理动画回调
48
+ const runOnJSCallbackRef = useRef({
49
+ triggerActiveEnd: (percent) => {
50
+ const currentProps = propsRef.current;
51
+ if (currentProps.bindactiveend) {
52
+ currentProps.bindactiveend({
53
+ type: 'activeend',
54
+ detail: {
55
+ percent: percent
56
+ }
57
+ });
58
+ }
59
+ }
60
+ });
61
+ const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef);
47
62
  // 进度条动画函数
48
63
  const startProgressAnimation = (targetPercent, startPercent, animationDuration, onFinished) => {
49
64
  // 根据 active-mode 设置起始位置
@@ -53,22 +68,11 @@ const Progress = forwardRef((props, ref) => {
53
68
  easing: Easing.linear
54
69
  }, (finished) => {
55
70
  if (finished && onFinished) {
56
- // 在动画回调中,需要使用runOnJS回到主线程
57
- runOnJS(onFinished)();
71
+ // 在动画回调中,执行传入的worklet函数
72
+ onFinished();
58
73
  }
59
74
  });
60
75
  };
61
- // 创建在主线程执行的事件回调函数
62
- const triggerActiveEnd = (percent) => {
63
- if (bindactiveend) {
64
- bindactiveend({
65
- type: 'activeend',
66
- detail: {
67
- percent: percent
68
- }
69
- });
70
- }
71
- };
72
76
  // 进度变化时的动画效果
73
77
  useEffect(() => {
74
78
  const targetPercent = Math.max(0, Math.min(100, percent));
@@ -85,18 +89,18 @@ const Progress = forwardRef((props, ref) => {
85
89
  // 计算动画持续时间
86
90
  const percentDiff = Math.abs(targetPercent - startPercent);
87
91
  const animationDuration = percentDiff * duration;
88
- // 创建动画完成回调
89
- const onAnimationFinished = () => {
90
- triggerActiveEnd(targetPercent);
91
- };
92
92
  // 执行动画
93
- startProgressAnimation(targetPercent, startPercent, animationDuration, onAnimationFinished);
93
+ startProgressAnimation(targetPercent, startPercent, animationDuration, () => {
94
+ 'worklet';
95
+ // 在worklet函数内部执行runOnJS调用runOnJSCallback
96
+ runOnJS(runOnJSCallback)('triggerActiveEnd', targetPercent);
97
+ });
94
98
  }
95
99
  else {
96
100
  progressWidth.value = targetPercent;
97
101
  }
98
102
  setLastPercent(targetPercent);
99
- }, [percent, active, activeMode, duration, bindactiveend]);
103
+ }, [percent, active, activeMode, duration]);
100
104
  // 初始化时设置进度值
101
105
  useEffect(() => {
102
106
  if (!active) {