@mpxjs/webpack-plugin 2.10.7 → 2.10.8

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.
Files changed (43) hide show
  1. package/lib/dependencies/RecordPageConfigsMapDependency.js +1 -1
  2. package/lib/dependencies/RequireExternalDependency.js +61 -0
  3. package/lib/file-loader.js +3 -2
  4. package/lib/index.js +55 -9
  5. package/lib/json-compiler/index.js +1 -0
  6. package/lib/parser.js +1 -1
  7. package/lib/platform/json/wx/index.js +43 -25
  8. package/lib/platform/style/wx/index.js +7 -0
  9. package/lib/platform/template/wx/component-config/fix-component-name.js +2 -2
  10. package/lib/platform/template/wx/component-config/index.js +5 -1
  11. package/lib/platform/template/wx/component-config/sticky-header.js +23 -0
  12. package/lib/platform/template/wx/component-config/sticky-section.js +23 -0
  13. package/lib/react/LoadAsyncChunkModule.js +74 -0
  14. package/lib/react/index.js +3 -1
  15. package/lib/react/processJSON.js +74 -13
  16. package/lib/react/processScript.js +6 -6
  17. package/lib/react/script-helper.js +100 -41
  18. package/lib/runtime/components/react/context.ts +12 -3
  19. package/lib/runtime/components/react/dist/context.js +4 -1
  20. package/lib/runtime/components/react/dist/mpx-async-suspense.jsx +135 -0
  21. package/lib/runtime/components/react/dist/mpx-button.jsx +2 -2
  22. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +8 -6
  23. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +31 -15
  24. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +117 -0
  25. package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +45 -0
  26. package/lib/runtime/components/react/mpx-async-suspense.tsx +180 -0
  27. package/lib/runtime/components/react/mpx-button.tsx +3 -2
  28. package/lib/runtime/components/react/mpx-movable-view.tsx +8 -4
  29. package/lib/runtime/components/react/mpx-scroll-view.tsx +84 -59
  30. package/lib/runtime/components/react/mpx-sticky-header.tsx +181 -0
  31. package/lib/runtime/components/react/mpx-sticky-section.tsx +96 -0
  32. package/lib/runtime/components/web/mpx-scroll-view.vue +18 -4
  33. package/lib/runtime/components/web/mpx-sticky-header.vue +99 -0
  34. package/lib/runtime/components/web/mpx-sticky-section.vue +15 -0
  35. package/lib/runtime/optionProcessorReact.d.ts +18 -0
  36. package/lib/runtime/optionProcessorReact.js +30 -0
  37. package/lib/script-setup-compiler/index.js +27 -5
  38. package/lib/template-compiler/bind-this.js +2 -1
  39. package/lib/template-compiler/compiler.js +4 -3
  40. package/lib/utils/dom-tag-config.js +17 -3
  41. package/lib/utils/trans-async-sub-rules.js +19 -0
  42. package/lib/web/script-helper.js +1 -1
  43. package/package.json +4 -4
@@ -29,7 +29,7 @@ class RecordPageConfigMapDependency extends NullDependency {
29
29
 
30
30
  deserialize (context) {
31
31
  const { read } = context
32
- this.pagePath = read()
32
+ this.resourcePath = read()
33
33
  this.jsonObj = read()
34
34
  super.deserialize(context)
35
35
  }
@@ -0,0 +1,61 @@
1
+ const path = require('path')
2
+ const NullDependency = require('webpack/lib/dependencies/NullDependency')
3
+ const makeSerializable = require('webpack/lib/util/makeSerializable')
4
+
5
+ class RequireExternalDependency extends NullDependency {
6
+ constructor (range, url) {
7
+ super()
8
+ this.range = range
9
+ this.url = url
10
+ }
11
+
12
+ get type () {
13
+ return 'mpx require external'
14
+ }
15
+
16
+ updateHash (hash, context) {
17
+ hash.update('' + (+new Date()) + Math.random())
18
+ super.updateHash(hash, context)
19
+ }
20
+
21
+ serialize (context) {
22
+ const { write } = context
23
+ write(this.url)
24
+ write(this.range)
25
+ super.serialize(context)
26
+ }
27
+
28
+ deserialize (context) {
29
+ const { read } = context
30
+ this.url = read()
31
+ this.range = read()
32
+ super.deserialize(context)
33
+ }
34
+ }
35
+
36
+ RequireExternalDependency.Template = class RequireExternalDependencyTemplate {
37
+ apply (dependency, source, { module, chunkGraph, runtimeTemplate }) {
38
+ const { range } = dependency
39
+ const compliation = runtimeTemplate.compilation
40
+ const publicPath = compliation.outputOptions.publicPath
41
+ const chunks = chunkGraph.getModuleChunks(module)
42
+ const chunk = chunks[0]
43
+ const chunkPath = path.dirname(publicPath + chunk.name)
44
+ const imgPath = publicPath + dependency.url
45
+ let relativePath = path.relative(chunkPath, imgPath)
46
+ if (!relativePath.startsWith('.')) {
47
+ relativePath = './' + relativePath
48
+ }
49
+
50
+ if (!compliation.__mpx__.externalRequestsMap.has(chunk.name)) {
51
+ compliation.__mpx__.externalRequestsMap.set(chunk.name, new Set())
52
+ }
53
+ compliation.__mpx__.externalRequestsMap.get(chunk.name).add(relativePath)
54
+
55
+ source.replace(range[0], range[1] - 1, `require(${JSON.stringify(relativePath)})`)
56
+ }
57
+ }
58
+
59
+ makeSerializable(RequireExternalDependency, '@mpxjs/webpack-plugin/lib/dependencies/RequireExternalDependency')
60
+
61
+ module.exports = RequireExternalDependency
@@ -35,8 +35,9 @@ module.exports = function loader (content, prevOptions) {
35
35
 
36
36
  let publicPath = `__webpack_public_path__ + ${JSON.stringify(url)}`
37
37
 
38
- // todo 未来添加分包处理后相对地址不一定是./开头的,需要考虑通过dependency的方式在sourceModule时通过最终的chunkName得到准确的相对路径
39
- if (isRN) publicPath = `__non_webpack_require__(${JSON.stringify(`./${url}`)})`
38
+ if (isRN) {
39
+ publicPath = `__mpx_require_external__(${JSON.stringify(url)})`
40
+ }
40
41
 
41
42
  if (options.publicPath) {
42
43
  if (typeof options.publicPath === 'function') {
package/lib/index.js CHANGED
@@ -44,9 +44,11 @@ const FlagPluginDependency = require('./dependencies/FlagPluginDependency')
44
44
  const RemoveEntryDependency = require('./dependencies/RemoveEntryDependency')
45
45
  const RecordLoaderContentDependency = require('./dependencies/RecordLoaderContentDependency')
46
46
  const RecordRuntimeInfoDependency = require('./dependencies/RecordRuntimeInfoDependency')
47
+ const RequireExternalDependency = require('./dependencies/RequireExternalDependency')
47
48
  const SplitChunksPlugin = require('webpack/lib/optimize/SplitChunksPlugin')
48
49
  const fixRelative = require('./utils/fix-relative')
49
50
  const parseRequest = require('./utils/parse-request')
51
+ const { transSubpackage } = require('./utils/trans-async-sub-rules')
50
52
  const { matchCondition } = require('./utils/match-condition')
51
53
  const processDefs = require('./utils/process-defs')
52
54
  const config = require('./config')
@@ -72,6 +74,9 @@ const isEmptyObject = require('./utils/is-empty-object')
72
74
  const DynamicPlugin = require('./resolver/DynamicPlugin')
73
75
  const { isReact, isWeb } = require('./utils/env')
74
76
  const VirtualModulesPlugin = require('webpack-virtual-modules')
77
+ const RuntimeGlobals = require('webpack/lib/RuntimeGlobals')
78
+ const LoadAsyncChunkModule = require('./react/LoadAsyncChunkModule')
79
+ const ExternalModule = require('webpack/lib/ExternalModule')
75
80
  require('./utils/check-core-version-match')
76
81
 
77
82
  const isProductionLikeMode = options => {
@@ -138,6 +143,9 @@ class MpxWebpackPlugin {
138
143
  if (options.dynamicComponentRules && !options.dynamicRuntime) {
139
144
  errors.push('Please make sure you have set dynamicRuntime true in mpx webpack plugin config because you have use the dynamic runtime feature.')
140
145
  }
146
+ if (options.transSubpackageRules && !isReact(options.mode)) {
147
+ warnings.push('MpxWebpackPlugin transSubpackageRules option only supports "ios", "android", or "harmony" mode')
148
+ }
141
149
  options.externalClasses = options.externalClasses || ['custom-class', 'i-class']
142
150
  options.resolveMode = options.resolveMode || 'webpack'
143
151
  options.writeMode = options.writeMode || 'changed'
@@ -408,7 +416,7 @@ class MpxWebpackPlugin {
408
416
  let splitChunksOptions = null
409
417
  let splitChunksPlugin = null
410
418
  // 输出web ssr需要将optimization.splitChunks设置为false以关闭splitChunks
411
- if (optimization.splitChunks !== false && !isReact(this.options.mode)) {
419
+ if (optimization.splitChunks !== false) {
412
420
  splitChunksOptions = Object.assign({
413
421
  chunks: 'all',
414
422
  usedExports: optimization.usedExports === true,
@@ -606,6 +614,22 @@ class MpxWebpackPlugin {
606
614
  return mpx
607
615
  }
608
616
  })
617
+
618
+ if (isReact(this.options.mode)) {
619
+ compilation.hooks.runtimeRequirementInTree
620
+ .for(RuntimeGlobals.loadScript)
621
+ .tap({
622
+ stage: -1000,
623
+ name: 'LoadAsyncChunk'
624
+ }, (chunk, set) => {
625
+ compilation.addRuntimeModule(
626
+ chunk,
627
+ new LoadAsyncChunkModule(this.options.rnConfig && this.options.rnConfig.asyncChunk && this.options.rnConfig.asyncChunk.timeout)
628
+ )
629
+ return true
630
+ })
631
+ }
632
+
609
633
  compilation.dependencyFactories.set(ResolveDependency, new NullFactory())
610
634
  compilation.dependencyTemplates.set(ResolveDependency, new ResolveDependency.Template())
611
635
 
@@ -654,6 +678,9 @@ class MpxWebpackPlugin {
654
678
  compilation.dependencyFactories.set(RecordRuntimeInfoDependency, new NullFactory())
655
679
  compilation.dependencyTemplates.set(RecordRuntimeInfoDependency, new RecordRuntimeInfoDependency.Template())
656
680
 
681
+ compilation.dependencyFactories.set(RequireExternalDependency, new NullFactory())
682
+ compilation.dependencyTemplates.set(RequireExternalDependency, new RequireExternalDependency.Template())
683
+
657
684
  compilation.dependencyTemplates.set(ImportDependency, new ImportDependencyTemplate())
658
685
  })
659
686
 
@@ -701,6 +728,8 @@ class MpxWebpackPlugin {
701
728
  assetsModulesMap: new Map(),
702
729
  // 记录与asset相关联的ast,用于体积分析和esCheck,避免重复parse
703
730
  assetsASTsMap: new Map(),
731
+ // 记录RequireExternalDependency相关资源路径
732
+ externalRequestsMap: new Map(),
704
733
  globalComponents: {},
705
734
  globalComponentsInfo: {},
706
735
  // todo es6 map读写性能高于object,之后会逐步替换
@@ -740,7 +769,7 @@ class MpxWebpackPlugin {
740
769
  removedChunks: [],
741
770
  forceProxyEventRules: this.options.forceProxyEventRules,
742
771
  // 若配置disableRequireAsync=true, 则全平台构建不支持异步分包
743
- supportRequireAsync: !this.options.disableRequireAsync && (this.options.mode === 'wx' || this.options.mode === 'ali' || this.options.mode === 'tt' || isWeb(this.options.mode)),
772
+ supportRequireAsync: !this.options.disableRequireAsync && (this.options.mode === 'wx' || this.options.mode === 'ali' || this.options.mode === 'tt' || isWeb(this.options.mode) || isReact(this.options.mode)),
744
773
  partialCompileRules: this.options.partialCompileRules,
745
774
  collectDynamicEntryInfo: ({ resource, packageName, filename, entryType, hasAsync }) => {
746
775
  const curInfo = mpx.dynamicEntryInfo[packageName] = mpx.dynamicEntryInfo[packageName] || {
@@ -756,6 +785,7 @@ class MpxWebpackPlugin {
756
785
  })
757
786
  },
758
787
  asyncSubpackageRules: this.options.asyncSubpackageRules,
788
+ transSubpackageRules: this.options.transSubpackageRules,
759
789
  optimizeRenderRules: this.options.optimizeRenderRules,
760
790
  pathHash: (resourcePath) => {
761
791
  if (this.options.pathHashMode === 'relative' && this.options.projectRoot) {
@@ -1151,6 +1181,11 @@ class MpxWebpackPlugin {
1151
1181
  return rawCallback(null, module)
1152
1182
  }
1153
1183
  }
1184
+
1185
+ if (isReact(mpx.mode) && module instanceof ExternalModule) {
1186
+ module.hasChunkCondition = () => false // 跳过 EnsureChunkConditionsPlugin 的过滤,避免被输出到包含 entry module 的 chunk 当中
1187
+ module.chunkCondition = () => true // 可以正常被 SplitChunkPlugin 处理
1188
+ }
1154
1189
  return rawAddModule.call(compilation, module, callback)
1155
1190
  }
1156
1191
 
@@ -1199,12 +1234,12 @@ class MpxWebpackPlugin {
1199
1234
  // 自动使用分包配置修改splitChunksPlugin配置
1200
1235
  if (splitChunksPlugin) {
1201
1236
  let needInit = false
1202
- if (isWeb(mpx.mode)) {
1237
+ if (isWeb(mpx.mode) || isReact(mpx.mode)) {
1203
1238
  // web独立处理splitChunk
1204
- if (!hasOwn(splitChunksOptions.cacheGroups, 'main')) {
1239
+ if (isWeb(mpx.mode) && !hasOwn(splitChunksOptions.cacheGroups, 'main')) {
1205
1240
  splitChunksOptions.cacheGroups.main = {
1206
1241
  chunks: 'initial',
1207
- name: 'bundle',
1242
+ name: 'lib/index', // web 输出 chunk 路径和 rn 输出分包格式拉齐
1208
1243
  test: /[\\/]node_modules[\\/]/
1209
1244
  }
1210
1245
  needInit = true
@@ -1212,8 +1247,9 @@ class MpxWebpackPlugin {
1212
1247
  if (!hasOwn(splitChunksOptions.cacheGroups, 'async')) {
1213
1248
  splitChunksOptions.cacheGroups.async = {
1214
1249
  chunks: 'async',
1215
- name: 'async',
1216
- minChunks: 2
1250
+ name: 'async-common/index',
1251
+ minChunks: 2,
1252
+ minSize: 1
1217
1253
  }
1218
1254
  needInit = true
1219
1255
  }
@@ -1360,6 +1396,15 @@ class MpxWebpackPlugin {
1360
1396
  }
1361
1397
  })
1362
1398
 
1399
+ parser.hooks.call.for('__mpx_require_external__').tap('MpxWebpackPlugin', (expr) => {
1400
+ const args = expr.arguments.map((i) => i.value)
1401
+ args.unshift(expr.range)
1402
+
1403
+ const dep = new RequireExternalDependency(...args)
1404
+ parser.state.current.addPresentationalDependency(dep)
1405
+ return true
1406
+ })
1407
+
1363
1408
  parser.hooks.call.for('__mpx_dynamic_entry__').tap('MpxWebpackPlugin', (expr) => {
1364
1409
  const args = expr.arguments.map((i) => i.value)
1365
1410
  args.unshift(expr.range)
@@ -1389,10 +1434,11 @@ class MpxWebpackPlugin {
1389
1434
  if (queryObj.root) request = addQuery(request, {}, false, ['root'])
1390
1435
  // wx、ali和web平台支持require.async,其余平台使用CommonJsAsyncDependency进行模拟抹平
1391
1436
  if (mpx.supportRequireAsync) {
1392
- if (isWeb(mpx.mode)) {
1437
+ if (isWeb(mpx.mode) || isReact(mpx.mode)) {
1438
+ if (isReact(mpx.mode)) tarRoot = transSubpackage(mpx.transSubpackageRules, tarRoot)
1393
1439
  const depBlock = new AsyncDependenciesBlock(
1394
1440
  {
1395
- name: tarRoot
1441
+ name: tarRoot + '/index'
1396
1442
  },
1397
1443
  expr.loc,
1398
1444
  request
@@ -623,6 +623,7 @@ module.exports = function (content) {
623
623
  }
624
624
  if (err) return callback(err)
625
625
  genericComponents[name] = entry
626
+ callback()
626
627
  })
627
628
  }, callback)
628
629
  }, callback)
package/lib/parser.js CHANGED
@@ -14,7 +14,7 @@ module.exports = (content, { filePath, needMap, mode, env }) => {
14
14
  output = compiler.parseComponent(content, {
15
15
  mode,
16
16
  filePath,
17
- // pad: 'line', // stylus编译遇到大量空行时会出现栈溢出,故注释掉
17
+ pad: 'line',
18
18
  env
19
19
  })
20
20
  if (needMap) {
@@ -3,7 +3,7 @@ const normalizeTest = require('../normalize-test')
3
3
  const changeKey = require('../change-key')
4
4
  const normalize = require('../../../utils/normalize')
5
5
  const { capitalToHyphen } = require('../../../utils/string')
6
- const { isOriginTag, isBuildInTag } = require('../../../utils/dom-tag-config')
6
+ const { isOriginTag, isBuildInWebTag, isBuildInReactTag } = require('../../../utils/dom-tag-config')
7
7
 
8
8
  const mpxViewPath = normalize.lib('runtime/components/ali/mpx-view.mpx')
9
9
  const mpxTextPath = normalize.lib('runtime/components/ali/mpx-text.mpx')
@@ -128,19 +128,41 @@ module.exports = function getSpec ({ warn, error }) {
128
128
  /**
129
129
  * 将小程序代码中使用的与原生 HTML tag 或 内建组件 同名的组件进行转化,以解决与原生tag命名冲突问题。
130
130
  */
131
- function fixComponentName (type) {
132
- return function (input) {
133
- const usingComponents = input[type]
134
- if (usingComponents) {
135
- Object.keys(usingComponents).forEach(tag => {
136
- if (isOriginTag(tag) || isBuildInTag(tag)) {
137
- usingComponents[`mpx-com-${tag}`] = usingComponents[tag]
138
- delete usingComponents[tag]
131
+ function fixComponentName (input, { mode }) {
132
+ const isNeedFixTag = (tag) => {
133
+ switch (mode) {
134
+ case 'web': return isOriginTag(tag) || isBuildInWebTag(tag)
135
+ case 'ios':
136
+ case 'android':
137
+ case 'harmony': return isOriginTag(tag) || isBuildInReactTag(tag)
138
+ }
139
+ }
140
+
141
+ const usingComponents = input.usingComponents
142
+ const componentPlaceholder = input.componentPlaceholder
143
+ if (usingComponents) {
144
+ const transfromKeys = []
145
+ Object.keys(usingComponents).forEach(tag => {
146
+ if (isNeedFixTag(tag)) {
147
+ usingComponents[`mpx-com-${tag}`] = usingComponents[tag]
148
+ delete usingComponents[tag]
149
+ transfromKeys.push(tag)
150
+ }
151
+ })
152
+
153
+ if (transfromKeys.length && componentPlaceholder) {
154
+ Object.keys(componentPlaceholder).forEach(key => {
155
+ if (transfromKeys.includes(componentPlaceholder[key])) {
156
+ componentPlaceholder[key] = `mpx-com-${componentPlaceholder[key]}`
157
+ }
158
+ if (transfromKeys.includes(key)) {
159
+ componentPlaceholder[`mpx-com-${key}`] = componentPlaceholder[key]
160
+ delete componentPlaceholder[key]
139
161
  }
140
162
  })
141
163
  }
142
- return input
143
164
  }
165
+ return input
144
166
  }
145
167
 
146
168
  const componentRules = [
@@ -154,13 +176,6 @@ module.exports = function getSpec ({ warn, error }) {
154
176
  swan: deletePath(),
155
177
  jd: deletePath()
156
178
  },
157
- {
158
- test: 'usingComponents',
159
- web: fixComponentName('usingComponents'),
160
- ios: fixComponentName('usingComponents'),
161
- android: fixComponentName('usingComponents'),
162
- harmony: fixComponentName('usingComponents')
163
- },
164
179
  {
165
180
  test: 'usingComponents',
166
181
  ali: componentNameCapitalToHyphen('usingComponents'),
@@ -170,7 +185,11 @@ module.exports = function getSpec ({ warn, error }) {
170
185
  swan: addGlobalComponents,
171
186
  qq: addGlobalComponents,
172
187
  tt: addGlobalComponents,
173
- jd: addGlobalComponents
188
+ jd: addGlobalComponents,
189
+ web: fixComponentName,
190
+ ios: fixComponentName,
191
+ android: fixComponentName,
192
+ harmony: fixComponentName
174
193
  }
175
194
  ]
176
195
 
@@ -371,13 +390,6 @@ module.exports = function getSpec ({ warn, error }) {
371
390
  tt: deletePath(),
372
391
  jd: deletePath(true)
373
392
  },
374
- {
375
- test: 'usingComponents',
376
- web: fixComponentName('usingComponents'),
377
- ios: fixComponentName('usingComponents'),
378
- android: fixComponentName('usingComponents'),
379
- harmony: fixComponentName('usingComponents')
380
- },
381
393
  {
382
394
  test: 'usingComponents',
383
395
  ali: componentNameCapitalToHyphen('usingComponents'),
@@ -442,6 +454,12 @@ module.exports = function getSpec ({ warn, error }) {
442
454
  swan: getWindowRule(),
443
455
  tt: getWindowRule(),
444
456
  jd: getWindowRule()
457
+ },
458
+ {
459
+ web: fixComponentName,
460
+ ios: fixComponentName,
461
+ android: fixComponentName,
462
+ harmony: fixComponentName
445
463
  }
446
464
  ]
447
465
  }
@@ -285,6 +285,13 @@ module.exports = function getSpec ({ warn, error }) {
285
285
 
286
286
  // line-height
287
287
  const formatLineHeight = ({ prop, value, selector }) => {
288
+ // line-height 0 直接返回
289
+ if (+value === 0) {
290
+ return {
291
+ prop,
292
+ value
293
+ }
294
+ }
288
295
  return verifyValues({ prop, value, selector }) && ({
289
296
  prop,
290
297
  value: /^\s*(-?(\d+(\.\d+)?|\.\d+))\s*$/.test(value) ? `${Math.round(value * 100)}%` : value
@@ -1,4 +1,4 @@
1
- const { isOriginTag, isBuildInTag } = require('../../../../utils/dom-tag-config')
1
+ const { isOriginTag, isBuildInWebTag } = require('../../../../utils/dom-tag-config')
2
2
 
3
3
  module.exports = function () {
4
4
  const handleComponentTag = (el, data) => {
@@ -16,7 +16,7 @@ module.exports = function () {
16
16
  waterfall: true,
17
17
  skipNormalize: true,
18
18
  supportedModes: ['web', 'ios', 'android', 'harmony'],
19
- test: (input) => isOriginTag(input) || isBuildInTag(input),
19
+ test: (input) => isOriginTag(input) || isBuildInWebTag(input),
20
20
  web: handleComponentTag,
21
21
  ios: handleComponentTag,
22
22
  android: handleComponentTag,
@@ -42,6 +42,8 @@ const wxs = require('./wxs')
42
42
  const component = require('./component')
43
43
  const fixComponentName = require('./fix-component-name')
44
44
  const rootPortal = require('./root-portal')
45
+ const stickyHeader = require('./sticky-header')
46
+ const stickySection = require('./sticky-section')
45
47
 
46
48
  module.exports = function getComponentConfigs ({ warn, error }) {
47
49
  /**
@@ -125,6 +127,8 @@ module.exports = function getComponentConfigs ({ warn, error }) {
125
127
  hyphenTagName({ print }),
126
128
  label({ print }),
127
129
  component(),
128
- rootPortal({ print })
130
+ rootPortal({ print }),
131
+ stickyHeader({ print }),
132
+ stickySection({ print })
129
133
  ]
130
134
  }
@@ -0,0 +1,23 @@
1
+ const TAG_NAME = 'sticky-header'
2
+
3
+ module.exports = function ({ print }) {
4
+ return {
5
+ test: TAG_NAME,
6
+ android (tag, { el }) {
7
+ el.isBuiltIn = true
8
+ return 'mpx-sticky-header'
9
+ },
10
+ ios (tag, { el }) {
11
+ el.isBuiltIn = true
12
+ return 'mpx-sticky-header'
13
+ },
14
+ harmony (tag, { el }) {
15
+ el.isBuiltIn = true
16
+ return 'mpx-sticky-header'
17
+ },
18
+ web (tag, { el }) {
19
+ el.isBuiltIn = true
20
+ return 'mpx-sticky-header'
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,23 @@
1
+ const TAG_NAME = 'sticky-section'
2
+
3
+ module.exports = function ({ print }) {
4
+ return {
5
+ test: TAG_NAME,
6
+ android (tag, { el }) {
7
+ el.isBuiltIn = true
8
+ return 'mpx-sticky-section'
9
+ },
10
+ ios (tag, { el }) {
11
+ el.isBuiltIn = true
12
+ return 'mpx-sticky-section'
13
+ },
14
+ harmony (tag, { el }) {
15
+ el.isBuiltIn = true
16
+ return 'mpx-sticky-section'
17
+ },
18
+ web (tag, { el }) {
19
+ el.isBuiltIn = true
20
+ return 'mpx-sticky-section'
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,74 @@
1
+ const RuntimeGlobals = require('webpack/lib/RuntimeGlobals')
2
+ const Template = require('webpack/lib/Template')
3
+ const HelperRuntimeModule = require('webpack/lib/runtime/HelperRuntimeModule')
4
+
5
+ class LoadAsyncChunkRuntimeModule extends HelperRuntimeModule {
6
+ constructor (timeout) {
7
+ super('load async chunk')
8
+ this.timeout = timeout || 5000
9
+ }
10
+
11
+ generate () {
12
+ const { compilation } = this
13
+ const { runtimeTemplate } = compilation
14
+ const loadScriptFn = RuntimeGlobals.loadScript
15
+ return Template.asString([
16
+ 'var inProgress = {}',
17
+ `${loadScriptFn} = ${runtimeTemplate.basicFunction(
18
+ 'url, done, key, chunkId',
19
+ [
20
+ `var packageName = ${RuntimeGlobals.getChunkScriptFilename}(chunkId) || ''`,
21
+ 'packageName = packageName.split(\'/\').slice(0, -1).join(\'/\')',
22
+ 'var config = {',
23
+ Template.indent([
24
+ 'url: url,',
25
+ 'package: packageName'
26
+ ]),
27
+ '}',
28
+ 'if(inProgress[url]) {',
29
+ Template.indent([
30
+ 'inProgress[url].push(done)',
31
+ 'return'
32
+ ]),
33
+ '}',
34
+ 'inProgress[url] = [done]',
35
+ 'var callback = function (type, result) {',
36
+ Template.indent([
37
+ 'var event = {',
38
+ Template.indent([
39
+ 'type: type || \'fail\',',
40
+ 'target: {',
41
+ Template.indent(['src: url']),
42
+ '}'
43
+ ]),
44
+ '}'
45
+ ]),
46
+ Template.indent([
47
+ 'var doneFns = inProgress[url]',
48
+ 'clearTimeout(timeout)',
49
+ 'delete inProgress[url]',
50
+ `doneFns && doneFns.forEach(${runtimeTemplate.returningFunction(
51
+ 'fn(event)',
52
+ 'fn'
53
+ )})`
54
+ ]),
55
+ '}',
56
+ `var timeout = setTimeout(callback.bind(null, 'timeout'), ${this.timeout})`,
57
+ 'var loadChunkAsyncFn = global.__mpx.config.rnConfig && global.__mpx.config.rnConfig.loadChunkAsync',
58
+ 'try {',
59
+ Template.indent([
60
+ 'loadChunkAsyncFn(config).then(callback).catch(callback)'
61
+ ]),
62
+ '} catch (e) {',
63
+ Template.indent([
64
+ 'console.error(\'[Mpx runtime error]: please provide correct mpx.config.rnConfig.loadChunkAsync implemention!\', e)',
65
+ 'Promise.resolve().then(callback)'
66
+ ]),
67
+ '}'
68
+ ]
69
+ )}`
70
+ ])
71
+ }
72
+ }
73
+
74
+ module.exports = LoadAsyncChunkRuntimeModule
@@ -35,6 +35,7 @@ module.exports = function ({
35
35
  })
36
36
  }
37
37
  const mpx = loaderContext.getMpx()
38
+ const rnConfig = mpx.rnConfig
38
39
  // 通过RecordLoaderContentDependency和loaderContentCache确保子request不再重复生成loaderContent
39
40
  const cacheContent = mpx.loaderContentCache.get(loaderContext.resourcePath)
40
41
  if (cacheContent) return callback(null, cacheContent)
@@ -91,7 +92,8 @@ module.exports = function ({
91
92
  genericsInfo: templateRes.genericsInfo,
92
93
  wxsModuleMap: templateRes.wxsModuleMap,
93
94
  localComponentsMap: jsonRes.localComponentsMap,
94
- localPagesMap: jsonRes.localPagesMap
95
+ localPagesMap: jsonRes.localPagesMap,
96
+ rnConfig
95
97
  }, callback)
96
98
  }
97
99
  ], (err, scriptRes) => {