@mpxjs/webpack-plugin 2.10.12 → 2.10.13-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.
@@ -6,6 +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
10
 
10
11
  class DynamicEntryDependency extends NullDependency {
11
12
  constructor (range, request, entryType, outputPath = '', packageRoot = '', relativePath = '', context = '', extraOptions = {}) {
@@ -201,9 +202,11 @@ class DynamicEntryDependency extends NullDependency {
201
202
  DynamicEntryDependency.Template = class DynamicEntryDependencyTemplate {
202
203
  apply (dep, source, {
203
204
  module,
204
- chunkGraph
205
+ chunkGraph,
206
+ runtimeRequirements
205
207
  }) {
206
- const { resultPath, range, key, publicPath, extraOptions } = dep
208
+ const { resultPath, key, publicPath, extraOptions } = dep
209
+ let range = dep.range
207
210
 
208
211
  let replaceContent = ''
209
212
 
@@ -214,10 +217,10 @@ DynamicEntryDependency.Template = class DynamicEntryDependencyTemplate {
214
217
  let relativePath = toPosix(path.relative(publicPath + path.dirname(chunkGraph.getModuleChunks(module)[0].name), resultPath))
215
218
  if (!relativePath.startsWith('.')) relativePath = './' + relativePath
216
219
  replaceContent = JSON.stringify(relativePath)
217
- if (extraOptions.retryRequireAsync) {
218
- replaceContent += `).catch(function (e) {
219
- return require.async(${JSON.stringify(relativePath)});
220
- }`
220
+ if (extraOptions.retryRequireAsync && extraOptions.retryRequireAsync.times > 0) {
221
+ range = extraOptions.requireAsyncRange
222
+ runtimeRequirements.add(RetryRuntimeGlobal)
223
+ replaceContent = `${RetryRuntimeGlobal}(function() { return require.async(${JSON.stringify(relativePath)}) }, ${extraOptions.retryRequireAsync.times}, ${extraOptions.retryRequireAsync.interval})`
221
224
  }
222
225
  } else {
223
226
  replaceContent = JSON.stringify(resultPath)
@@ -1,4 +1,6 @@
1
1
  const ModuleDependency = require('webpack/lib/dependencies/ModuleDependency')
2
+ const { RetryRuntimeGlobal } = require('../retry-runtime-module')
3
+ const parseRequest = require('../utils/parse-request')
2
4
 
3
5
  class ImportDependencyTemplate extends (
4
6
  ModuleDependency.Template
@@ -31,6 +33,16 @@ class ImportDependencyTemplate extends (
31
33
  content = content.replace(/(__webpack_require__\.t\.bind\(.+,\s*)(\d+)(\s*\))/, (_, p1, p2, p3) => {
32
34
  return p1 + '9' + p3
33
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
+
34
46
  source.replace(dep.range[0], dep.range[1] - 1, content)
35
47
  }
36
48
  }
package/lib/index.js CHANGED
@@ -77,6 +77,7 @@ const VirtualModulesPlugin = require('webpack-virtual-modules')
77
77
  const RuntimeGlobals = require('webpack/lib/RuntimeGlobals')
78
78
  const LoadAsyncChunkModule = require('./react/LoadAsyncChunkModule')
79
79
  const ExternalModule = require('webpack/lib/ExternalModule')
80
+ const { RetryRuntimeModule, RetryRuntimeGlobal } = require('./retry-runtime-module')
80
81
  require('./utils/check-core-version-match')
81
82
 
82
83
  const isProductionLikeMode = options => {
@@ -202,6 +203,12 @@ class MpxWebpackPlugin {
202
203
  options.asyncSubpackageRules = options.asyncSubpackageRules || []
203
204
  options.optimizeRenderRules = options.optimizeRenderRules ? (Array.isArray(options.optimizeRenderRules) ? options.optimizeRenderRules : [options.optimizeRenderRules]) : []
204
205
  options.retryRequireAsync = options.retryRequireAsync || false
206
+ if (options.retryRequireAsync === true) {
207
+ options.retryRequireAsync = {
208
+ times: 1,
209
+ interval: 0
210
+ }
211
+ }
205
212
  options.optimizeSize = options.optimizeSize || false
206
213
  options.dynamicComponentRules = options.dynamicComponentRules || {}// 运行时组件配置
207
214
  this.options = options
@@ -615,6 +622,13 @@ class MpxWebpackPlugin {
615
622
  }
616
623
  })
617
624
 
625
+ compilation.hooks.runtimeRequirementInTree
626
+ .for(RetryRuntimeGlobal)
627
+ .tap('MpxWebpackPlugin', (chunk) => {
628
+ compilation.addRuntimeModule(chunk, new RetryRuntimeModule())
629
+ return true
630
+ })
631
+
618
632
  if (isReact(this.options.mode)) {
619
633
  compilation.hooks.runtimeRequirementInTree
620
634
  .for(RuntimeGlobals.loadScript)
@@ -1436,6 +1450,10 @@ class MpxWebpackPlugin {
1436
1450
  if (mpx.supportRequireAsync) {
1437
1451
  if (isWeb(mpx.mode) || isReact(mpx.mode)) {
1438
1452
  if (isReact(mpx.mode)) tarRoot = transSubpackage(mpx.transSubpackageRules, tarRoot)
1453
+ request = addQuery(request, {
1454
+ isRequireAsync: true,
1455
+ retryRequireAsync: JSON.stringify(this.options.retryRequireAsync)
1456
+ })
1439
1457
  const depBlock = new AsyncDependenciesBlock(
1440
1458
  {
1441
1459
  name: tarRoot + '/index'
@@ -1451,7 +1469,8 @@ class MpxWebpackPlugin {
1451
1469
  const dep = new DynamicEntryDependency(range, request, 'export', '', tarRoot, '', context, {
1452
1470
  isAsync: true,
1453
1471
  isRequireAsync: true,
1454
- retryRequireAsync: !!this.options.retryRequireAsync
1472
+ retryRequireAsync: this.options.retryRequireAsync,
1473
+ requireAsyncRange: expr.range
1455
1474
  })
1456
1475
 
1457
1476
  parser.state.current.addPresentationalDependency(dep)
@@ -1606,7 +1625,7 @@ class MpxWebpackPlugin {
1606
1625
  target = expr.object
1607
1626
  }
1608
1627
 
1609
- if (!matchCondition(resourcePath, this.options.transMpxRules) || resourcePath.indexOf('node_modules/@mpxjs') !== -1 || !target || mode === srcMode) return
1628
+ if (!matchCondition(resourcePath, this.options.transMpxRules) || toPosix(resourcePath).indexOf('node_modules/@mpxjs') !== -1 || !target || mode === srcMode) return
1610
1629
 
1611
1630
  const type = target.name
1612
1631
  const name = type === 'wx' ? 'mpx' : 'createFactory'
@@ -1861,72 +1880,92 @@ try {
1861
1880
  normalModuleFactory.hooks.afterResolve.tap('MpxWebpackPlugin', ({ createData }) => {
1862
1881
  const { queryObj } = parseRequest(createData.request)
1863
1882
  const loaders = createData.loaders
1864
- if (queryObj.mpx && queryObj.mpx !== MPX_PROCESSED_FLAG) {
1865
- const type = queryObj.type
1883
+ const type = queryObj.type
1884
+ const mpxProcessFlag = queryObj.mpx && queryObj.mpx !== MPX_PROCESSED_FLAG
1885
+ const vueProcessFlag = queryObj.vue && queryObj.mpx !== MPX_PROCESSED_FLAG
1886
+ if (mpxProcessFlag || vueProcessFlag) {
1866
1887
  const extract = queryObj.extract
1867
-
1868
- if (type === 'styles') {
1869
- let insertBeforeIndex = -1
1870
- // 单次遍历收集所有索引
1888
+ if (type === 'styles' || type === 'style') {
1889
+ const loaderTypes = {
1890
+ 'node_modules/stylus-loader': -1,
1891
+ 'node_modules/sass-loader': -1,
1892
+ 'node_modules/less-loader': -1,
1893
+ 'node_modules/css-loader': -1
1894
+ }
1871
1895
  loaders.forEach((loader, index) => {
1872
1896
  const currentLoader = toPosix(loader.loader)
1873
- if (currentLoader.includes('node_modules/stylus-loader') || currentLoader.includes('node_modules/sass-loader') || currentLoader.includes('node_modules/less-loader')) {
1874
- insertBeforeIndex = index
1897
+ for (const key in loaderTypes) {
1898
+ if (currentLoader.includes(key)) {
1899
+ loaderTypes[key] = index
1900
+ break
1901
+ }
1875
1902
  }
1876
1903
  })
1904
+ const insertStripLoaders = (index) => {
1905
+ if (index !== -1) {
1906
+ loaders.splice(index, 0, { loader: styleStripConditionalPath, options: {id: 0} })
1907
+ loaders.splice(index + 2, 0, { loader: styleStripConditionalPath, options: {id: 1} })
1908
+ return true
1909
+ }
1910
+ return false
1911
+ }
1877
1912
 
1878
- if (insertBeforeIndex !== -1) {
1879
- loaders.splice(insertBeforeIndex, 0, { loader: styleStripConditionalPath })
1913
+ const priorities = ['node_modules/stylus-loader', 'node_modules/less-loader', 'node_modules/sass-loader', 'node_modules/css-loader']
1914
+ for (const loaderKey of priorities) {
1915
+ if (insertStripLoaders(loaderTypes[loaderKey])) {
1916
+ break
1917
+ }
1880
1918
  }
1881
- loaders.push({ loader: styleStripConditionalPath })
1882
1919
  }
1883
1920
 
1884
- switch (type) {
1885
- case 'styles':
1886
- case 'template': {
1887
- let insertBeforeIndex = -1
1888
- const info = typeLoaderProcessInfo[type]
1889
- loaders.forEach((loader, index) => {
1890
- const currentLoader = toPosix(loader.loader)
1891
- if (currentLoader.includes(info[0])) {
1892
- loader.loader = info[1]
1893
- insertBeforeIndex = index
1894
- } else if (currentLoader.includes(info[1])) {
1895
- insertBeforeIndex = index
1896
- }
1897
- })
1898
- if (insertBeforeIndex > -1) {
1899
- loaders.splice(insertBeforeIndex + 1, 0, {
1900
- loader: info[2]
1921
+ if (mpxProcessFlag) {
1922
+ switch (type) {
1923
+ case 'styles':
1924
+ case 'template': {
1925
+ let insertBeforeIndex = -1
1926
+ const info = typeLoaderProcessInfo[type]
1927
+ loaders.forEach((loader, index) => {
1928
+ const currentLoader = toPosix(loader.loader)
1929
+ if (currentLoader.includes(info[0])) {
1930
+ loader.loader = info[1]
1931
+ insertBeforeIndex = index
1932
+ } else if (currentLoader.includes(info[1])) {
1933
+ insertBeforeIndex = index
1934
+ }
1901
1935
  })
1936
+ if (insertBeforeIndex > -1) {
1937
+ loaders.splice(insertBeforeIndex + 1, 0, {
1938
+ loader: info[2]
1939
+ })
1940
+ }
1941
+ break
1902
1942
  }
1903
- break
1904
- }
1905
- case 'json':
1906
- if (queryObj.isTheme) {
1907
- loaders.unshift({
1908
- loader: jsonThemeCompilerPath
1909
- })
1910
- } else if (queryObj.isPlugin) {
1911
- loaders.unshift({
1912
- loader: jsonPluginCompilerPath
1913
- })
1914
- } else {
1943
+ case 'json':
1944
+ if (queryObj.isTheme) {
1945
+ loaders.unshift({
1946
+ loader: jsonThemeCompilerPath
1947
+ })
1948
+ } else if (queryObj.isPlugin) {
1949
+ loaders.unshift({
1950
+ loader: jsonPluginCompilerPath
1951
+ })
1952
+ } else {
1953
+ loaders.unshift({
1954
+ loader: jsonCompilerPath
1955
+ })
1956
+ }
1957
+ break
1958
+ case 'wxs':
1915
1959
  loaders.unshift({
1916
- loader: jsonCompilerPath
1960
+ loader: wxsLoaderPath
1917
1961
  })
1918
- }
1919
- break
1920
- case 'wxs':
1962
+ break
1963
+ }
1964
+ if (extract) {
1921
1965
  loaders.unshift({
1922
- loader: wxsLoaderPath
1966
+ loader: extractorPath
1923
1967
  })
1924
- break
1925
- }
1926
- if (extract) {
1927
- loaders.unshift({
1928
- loader: extractorPath
1929
- })
1968
+ }
1930
1969
  }
1931
1970
  createData.resource = addQuery(createData.resource, { mpx: MPX_PROCESSED_FLAG }, true)
1932
1971
  }
@@ -5,7 +5,7 @@ const HelperRuntimeModule = require('webpack/lib/runtime/HelperRuntimeModule')
5
5
  class LoadAsyncChunkRuntimeModule extends HelperRuntimeModule {
6
6
  constructor (timeout) {
7
7
  super('load async chunk')
8
- this.timeout = timeout || 5000
8
+ this.timeout = timeout || 10000
9
9
  }
10
10
 
11
11
  generate () {
@@ -1,6 +1,6 @@
1
1
  const normalize = require('../utils/normalize')
2
2
  const optionProcessorPath = normalize.lib('runtime/optionProcessorReact')
3
- const { buildPagesMap, buildComponentsMap, getRequireScript, buildGlobalParams, stringifyRequest } = require('./script-helper')
3
+ const { buildPagesMap, buildComponentsMap, getRequireScript, buildGlobalParams, stringifyRequest, buildI18n } = require('./script-helper')
4
4
 
5
5
  module.exports = function (script, {
6
6
  loaderContext,
@@ -17,7 +17,7 @@ module.exports = function (script, {
17
17
  componentGenerics,
18
18
  genericsInfo
19
19
  }, callback) {
20
- const { appInfo } = loaderContext.getMpx()
20
+ const { appInfo, i18n } = loaderContext.getMpx()
21
21
 
22
22
  let scriptSrcMode = srcMode
23
23
  if (script) {
@@ -62,6 +62,9 @@ import { getComponent, getAsyncSuspense } from ${stringifyRequest(loaderContext,
62
62
  })
63
63
 
64
64
  output += buildGlobalParams({ moduleId, scriptSrcMode, loaderContext, isProduction, ctorType, jsonConfig, componentsMap, outputPath, genericsInfo, componentGenerics, hasApp })
65
+ if (!hasApp && i18n) {
66
+ output += buildI18n({ loaderContext })
67
+ }
65
68
  output += getRequireScript({ ctorType, script, loaderContext })
66
69
  output += `export default global.__mpxOptionsMap[${JSON.stringify(moduleId)}]\n`
67
70
  }
@@ -0,0 +1,56 @@
1
+ const Template = require('webpack/lib/Template')
2
+ const RuntimeModule = require('webpack/lib/RuntimeModule')
3
+
4
+ const RetryRuntimeGlobal = '__webpack_require__.__retry'
5
+
6
+ class RetryRuntimeModule extends RuntimeModule {
7
+ constructor () {
8
+ super('mpx retry module')
9
+ }
10
+
11
+ generate () {
12
+ const { compilation } = this
13
+ const { runtimeTemplate } = compilation
14
+ return Template.asString([
15
+ `${RetryRuntimeGlobal} = ${runtimeTemplate.basicFunction(
16
+ 'fn, times, interval',
17
+ [
18
+ 'times = times || 1;',
19
+ 'interval = interval || 0;',
20
+ `return new Promise(${runtimeTemplate.basicFunction(
21
+ 'resolve, reject',
22
+ [
23
+ Template.indent([
24
+ 'var _t = 0;',
25
+ `var _retry = ${runtimeTemplate.basicFunction('', [
26
+ Template.indent([
27
+ `fn().then(resolve).catch(${runtimeTemplate.basicFunction('err', [
28
+ Template.indent([
29
+ 'if (_t < times) {',
30
+ Template.indent([
31
+ '++_t;',
32
+ 'interval > 0 ? setTimeout(_retry, interval) : _retry()'
33
+ ]),
34
+ '} else {',
35
+ Template.indent([
36
+ 'reject(err);'
37
+ ]),
38
+ '}'
39
+ ])
40
+ ])})`
41
+ ])
42
+ ])};`,
43
+ '_retry();'
44
+ ])
45
+ ]
46
+ )})`
47
+ ]
48
+ )}`
49
+ ])
50
+ }
51
+ }
52
+
53
+ module.exports = {
54
+ RetryRuntimeModule,
55
+ RetryRuntimeGlobal
56
+ }
@@ -91,10 +91,19 @@ const AsyncSuspense = ({ type, chunkName, moduleId, innerProps, getLoading, getF
91
91
  if (cancelled)
92
92
  return;
93
93
  if (type === 'component') {
94
- global.onLazyLoadError({
95
- type: 'subpackage',
96
- subpackage: [chunkName],
97
- errMsg: `loadSubpackage: ${e.type}`
94
+ global.__mpxAppCbs.lazyLoad.forEach((cb) => {
95
+ // eslint-disable-next-line node/no-callback-literal
96
+ cb({
97
+ type: 'subpackage',
98
+ subpackage: [chunkName],
99
+ errMsg: `loadSubpackage: ${e.type}`
100
+ });
101
+ });
102
+ }
103
+ if (type === 'page' && typeof mpxGlobal.__mpx.config?.rnConfig?.lazyLoadPageErrorHandler === 'function') {
104
+ mpxGlobal.__mpx.config.rnConfig.lazyLoadPageErrorHandler({
105
+ subpackage: chunkName,
106
+ errType: e.type
98
107
  });
99
108
  }
100
109
  loadChunkPromise.current = null;