@mpxjs/webpack-plugin 2.10.5 → 2.10.6-beta.2

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 (92) hide show
  1. package/lib/dependencies/WriteVfsDependency.js +46 -0
  2. package/lib/index.js +22 -6
  3. package/lib/json-compiler/helper.js +1 -4
  4. package/lib/platform/index.js +4 -2
  5. package/lib/platform/json/wx/index.js +0 -1
  6. package/lib/platform/template/wx/component-config/button.js +1 -1
  7. package/lib/platform/template/wx/component-config/index.js +7 -3
  8. package/lib/platform/template/wx/component-config/input.js +1 -1
  9. package/lib/platform/template/wx/component-config/sticky-header.js +23 -0
  10. package/lib/platform/template/wx/component-config/sticky-section.js +23 -0
  11. package/lib/platform/template/wx/component-config/template.js +26 -1
  12. package/lib/platform/template/wx/index.js +31 -4
  13. package/lib/react/processJSON.js +7 -6
  14. package/lib/resolver/PackageEntryPlugin.js +3 -1
  15. package/lib/runtime/components/react/context.ts +12 -3
  16. package/lib/runtime/components/react/dist/context.js +4 -1
  17. package/lib/runtime/components/react/dist/mpx-button.jsx +9 -4
  18. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +2 -4
  19. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +20 -17
  20. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +7 -2
  21. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +7 -2
  22. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +7 -2
  23. package/lib/runtime/components/react/dist/mpx-image.jsx +9 -2
  24. package/lib/runtime/components/react/dist/mpx-input.jsx +7 -2
  25. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +1 -1
  26. package/lib/runtime/components/react/dist/mpx-label.jsx +7 -2
  27. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +8 -3
  28. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +100 -62
  29. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +11 -13
  30. package/lib/runtime/components/react/dist/mpx-picker-view/index.jsx +8 -7
  31. package/lib/runtime/components/react/dist/mpx-picker-view-column/index.jsx +26 -8
  32. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +9 -2
  33. package/lib/runtime/components/react/dist/mpx-radio.jsx +7 -2
  34. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +7 -2
  35. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +30 -10
  36. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +115 -0
  37. package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +45 -0
  38. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +11 -9
  39. package/lib/runtime/components/react/dist/mpx-swiper.jsx +82 -36
  40. package/lib/runtime/components/react/dist/mpx-switch.jsx +7 -2
  41. package/lib/runtime/components/react/dist/mpx-text.jsx +7 -2
  42. package/lib/runtime/components/react/dist/mpx-video.jsx +7 -2
  43. package/lib/runtime/components/react/dist/mpx-view.jsx +2 -4
  44. package/lib/runtime/components/react/dist/mpx-web-view.jsx +13 -13
  45. package/lib/runtime/components/react/dist/utils.jsx +14 -3
  46. package/lib/runtime/components/react/mpx-button.tsx +12 -3
  47. package/lib/runtime/components/react/mpx-canvas/Image.ts +4 -4
  48. package/lib/runtime/components/react/mpx-canvas/index.tsx +24 -17
  49. package/lib/runtime/components/react/mpx-checkbox-group.tsx +9 -1
  50. package/lib/runtime/components/react/mpx-checkbox.tsx +9 -1
  51. package/lib/runtime/components/react/mpx-icon/index.tsx +9 -1
  52. package/lib/runtime/components/react/mpx-image.tsx +38 -19
  53. package/lib/runtime/components/react/mpx-input.tsx +10 -1
  54. package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +1 -1
  55. package/lib/runtime/components/react/mpx-label.tsx +9 -1
  56. package/lib/runtime/components/react/mpx-movable-area.tsx +8 -2
  57. package/lib/runtime/components/react/mpx-movable-view.tsx +100 -62
  58. package/lib/runtime/components/react/mpx-picker/index.tsx +18 -16
  59. package/lib/runtime/components/react/mpx-picker-view/index.tsx +22 -8
  60. package/lib/runtime/components/react/mpx-picker-view-column/index.tsx +34 -30
  61. package/lib/runtime/components/react/mpx-radio-group.tsx +20 -9
  62. package/lib/runtime/components/react/mpx-radio.tsx +9 -1
  63. package/lib/runtime/components/react/mpx-rich-text/index.tsx +10 -2
  64. package/lib/runtime/components/react/mpx-scroll-view.tsx +82 -53
  65. package/lib/runtime/components/react/mpx-sticky-header.tsx +179 -0
  66. package/lib/runtime/components/react/mpx-sticky-section.tsx +96 -0
  67. package/lib/runtime/components/react/mpx-swiper-item.tsx +11 -19
  68. package/lib/runtime/components/react/mpx-swiper.tsx +95 -38
  69. package/lib/runtime/components/react/mpx-switch.tsx +10 -2
  70. package/lib/runtime/components/react/mpx-text.tsx +10 -2
  71. package/lib/runtime/components/react/mpx-video.tsx +7 -2
  72. package/lib/runtime/components/react/mpx-view.tsx +8 -4
  73. package/lib/runtime/components/react/mpx-web-view.tsx +12 -12
  74. package/lib/runtime/components/react/utils.tsx +16 -5
  75. package/lib/runtime/components/web/mpx-scroll-view.vue +21 -4
  76. package/lib/runtime/components/web/mpx-sticky-header.vue +91 -0
  77. package/lib/runtime/components/web/mpx-sticky-section.vue +15 -0
  78. package/lib/runtime/components/web/mpx-web-view.vue +1 -1
  79. package/lib/runtime/mpxGlobal.js +1 -0
  80. package/lib/runtime/optionProcessor.d.ts +5 -0
  81. package/lib/runtime/optionProcessor.js +2 -2
  82. package/lib/template-compiler/bind-this.js +8 -7
  83. package/lib/template-compiler/compiler.js +59 -9
  84. package/lib/utils/get-template-content.js +47 -0
  85. package/lib/web/index.js +2 -0
  86. package/lib/web/processScript.js +29 -7
  87. package/lib/web/processTemplate.js +10 -4
  88. package/lib/web/template2vue.js +280 -0
  89. package/lib/web/wxml-template-loader.js +29 -0
  90. package/lib/wxs/pre-loader.js +1 -0
  91. package/package.json +4 -4
  92. package/LICENSE +0 -433
@@ -0,0 +1,91 @@
1
+ <script>
2
+ import { warn } from '@mpxjs/utils'
3
+ import { getCustomEvent } from './getInnerListeners'
4
+
5
+ export default {
6
+ name: 'mpx-sticky-header',
7
+ inject: ['scrollOffset', 'refreshVersion'],
8
+ props: {
9
+ 'offsetTop': {
10
+ type: Number,
11
+ default: 0
12
+ }
13
+ },
14
+ data() {
15
+ return {
16
+ headerTop: 0,
17
+ isStickOnTop: false
18
+ }
19
+ },
20
+ computed: {
21
+ _scrollOffset() {
22
+ return -this.scrollOffset?.get() || 0
23
+ },
24
+ _refreshVersion() {
25
+ return this.refreshVersion?.get() || 0
26
+ }
27
+ },
28
+ watch: {
29
+ _scrollOffset: {
30
+ handler(newScrollOffset) {
31
+ const newIsStickOnTop = newScrollOffset > this.headerTop
32
+ if (newIsStickOnTop !== this.isStickOnTop) {
33
+ this.isStickOnTop = newIsStickOnTop
34
+ this.$emit('stickontopchange', getCustomEvent('stickontopchange', {
35
+ isStickOnTop: newIsStickOnTop
36
+ }, this))
37
+ }
38
+ const stickyHeader = this.$refs.stickyHeader
39
+ if (!stickyHeader) return
40
+ if (this.isStickOnTop) {
41
+ stickyHeader.style.transform = `translateY(${newScrollOffset - this.headerTop + this.offsetTop}px)`
42
+ } else {
43
+ stickyHeader.style.transform = 'none'
44
+ }
45
+ },
46
+ immediate: true
47
+ },
48
+ _refreshVersion: {
49
+ handler() {
50
+ const parentElement = this.$el.parentElement
51
+ if (!parentElement) return
52
+
53
+ const parentClass = parentElement.className || ''
54
+ const isStickySection = /mpx-sticky-section/.test(parentClass)
55
+ const isScrollViewWrapper = /mpx-inner-wrapper/.test(parentClass)
56
+
57
+ if (!isStickySection && !isScrollViewWrapper) {
58
+ warn('sticky-header only supports being a direct child of a scroll-view or sticky-section component.')
59
+ return
60
+ }
61
+
62
+ this.headerTop = isStickySection
63
+ ? this.$el.offsetTop + parentElement.offsetTop
64
+ : this.$el.offsetTop
65
+
66
+ const stickyHeader = this.$refs.stickyHeader
67
+ if (!stickyHeader) return
68
+
69
+ if (this._scrollOffset > this.headerTop) {
70
+ stickyHeader.style.transform = `translateY(${this._scrollOffset - this.headerTop + this.offsetTop}px)`
71
+ } else {
72
+ stickyHeader.style.transform = 'none'
73
+ }
74
+ },
75
+ }
76
+ },
77
+ render(h) {
78
+ const style = {
79
+ width: '100%',
80
+ boxSizing: 'border-box',
81
+ position: 'relative',
82
+ zIndex: 10
83
+ }
84
+
85
+ return h('div', {
86
+ style,
87
+ ref: 'stickyHeader'
88
+ }, this.$slots.default)
89
+ }
90
+ }
91
+ </script>
@@ -0,0 +1,15 @@
1
+ <script>
2
+ export default {
3
+ name: 'mpx-sticky-section',
4
+ render(h) {
5
+ const style = {
6
+ position: 'relative'
7
+ }
8
+
9
+ return h('div', {
10
+ style,
11
+ class: 'mpx-sticky-section'
12
+ }, this.$slots.default)
13
+ }
14
+ }
15
+ </script>
@@ -197,4 +197,4 @@ export default {
197
197
  right: 0;
198
198
  bottom: 0;
199
199
  }
200
- </style>
200
+ </style>
@@ -0,0 +1 @@
1
+ module.exports = Object.create(global)
@@ -4,8 +4,13 @@ declare global {
4
4
  [key: string]: any
5
5
  }
6
6
  }
7
+ interface Window {
8
+ mpxGlobal: Record<string, any>
9
+ }
7
10
  }
8
11
 
12
+ declare const mpxGlobal: Record<string, any>
13
+
9
14
  export function processComponentOption (...args: any): object
10
15
 
11
16
  export function getComponent (...args: any): object
@@ -79,7 +79,7 @@ registered in parent context!`)
79
79
  transitionName: ''
80
80
  }
81
81
  }
82
- if (!global.__mpx.config.webConfig.disablePageTransition) {
82
+ if (!global.__mpx.config.webConfig?.disablePageTransition) {
83
83
  option.watch = {
84
84
  $route: {
85
85
  handler () {
@@ -161,7 +161,7 @@ function createApp ({ componentsMap, Vue, pagesMap, firstPage, VueRouter, App, t
161
161
  redirect: '/' + firstPage
162
162
  })
163
163
  }
164
- const webRouteConfig = global.__mpx.config.webConfig.routeConfig || global.__mpx.config.webRouteConfig
164
+ const webRouteConfig = global.__mpx.config.webConfig?.routeConfig || global.__mpx.config.webRouteConfig
165
165
  global.__mpxRouter = option.router = new VueRouter(extend({ routes }, webRouteConfig))
166
166
  let mpxStackPath = []
167
167
  if (isBrowser) {
@@ -70,7 +70,7 @@ function getCollectPath (path) {
70
70
  function checkDelAndGetPath (path) {
71
71
  let current = path
72
72
  let delPath = path
73
- let canDel = true
73
+ let canDel = true // 是否可删除,优先级比replace高
74
74
  let ignore = false
75
75
  let replace = false
76
76
 
@@ -80,8 +80,13 @@ function checkDelAndGetPath (path) {
80
80
  if (t.isUnaryExpression(current.parent) && current.key === 'argument') {
81
81
  delPath = current.parentPath
82
82
  } else if (t.isCallExpression(current.parent)) {
83
- const args = current.node.arguments || current.parent.arguments || []
84
- if (args.length === 1) { // case: String(a) || this._p(a)
83
+ const args = current.parent.arguments || []
84
+ if (
85
+ // case: String(a) || this._p(a)
86
+ args.length === 1 ||
87
+ // 除了自身,参数列表里只能是数字或字符串才能删
88
+ (args.every(node => node === current.node || t.isNumericLiteral(node) || t.isStringLiteral(node)))
89
+ ) {
85
90
  delPath = current.parentPath
86
91
  } else {
87
92
  break
@@ -123,24 +128,20 @@ function checkDelAndGetPath (path) {
123
128
 
124
129
  if (t.isCallExpression(parent) && listKey === 'arguments') {
125
130
  canDel = false
126
- break
127
131
  }
128
132
 
129
133
  if (t.isMemberExpression(parent) && parent.computed) {
130
134
  canDel = false
131
- break
132
135
  }
133
136
 
134
137
  if (t.isLogicalExpression(parent)) { // case: a || ((b || c) && d)
135
138
  canDel = false
136
139
  ignore = true
137
- break
138
140
  }
139
141
 
140
142
  if (t.isConditionalExpression(parent)) {
141
143
  if (key === 'test') {
142
144
  canDel = false
143
- break
144
145
  } else {
145
146
  ignore = true
146
147
  replace = true // 继续往上找,判断是否存在if条件等
@@ -16,6 +16,7 @@ const setBaseWxml = require('../runtime-render/base-wxml')
16
16
  const { parseExp } = require('./parse-exps')
17
17
  const shallowStringify = require('../utils/shallow-stringify')
18
18
  const { isReact, isWeb } = require('../utils/env')
19
+ const getTemplateContent = require('../utils/get-template-content')
19
20
 
20
21
  const no = function () {
21
22
  return false
@@ -638,7 +639,7 @@ function parse (template, options) {
638
639
  componentGenerics = options.componentGenerics || {}
639
640
 
640
641
  if (typeof options.usingComponentsInfo === 'string') options.usingComponentsInfo = JSON.parse(options.usingComponentsInfo)
641
- usingComponents = Object.keys(options.usingComponentsInfo)
642
+ usingComponents = Object.keys(options.usingComponentsInfo || {})
642
643
  usingComponentsInfo = options.usingComponentsInfo
643
644
 
644
645
  const _warn = content => {
@@ -661,6 +662,7 @@ function parse (template, options) {
661
662
  srcMode,
662
663
  type: 'template',
663
664
  testKey: 'tag',
665
+ moduleId,
664
666
  data: {
665
667
  usingComponents
666
668
  },
@@ -689,6 +691,7 @@ function parse (template, options) {
689
691
  root = currentParent = getVirtualHostRoot(options, meta)
690
692
  stack.push(root)
691
693
  }
694
+ options.template = template // processTemplate时需要对template(只用于处理含name的情况)做截取
692
695
 
693
696
  parseHTML(template, {
694
697
  warn: warn$1,
@@ -721,6 +724,7 @@ function parse (template, options) {
721
724
 
722
725
  currentParent.children.push(element)
723
726
  element.parent = currentParent
727
+
724
728
  processElement(element, root, options, meta)
725
729
 
726
730
  tagNames.add(element.tag)
@@ -1426,7 +1430,6 @@ function processEvent (el, options) {
1426
1430
  }
1427
1431
  }
1428
1432
  })
1429
-
1430
1433
  addAttrs(el, [
1431
1434
  {
1432
1435
  name: resultName || config[mode].event.getEvent(type),
@@ -1462,6 +1465,13 @@ function wrapMustache (val) {
1462
1465
  return val && !tagRE.test(val) ? `{{${val}}}` : val
1463
1466
  }
1464
1467
 
1468
+ function vbindMustache (val) {
1469
+ const bindREG = /\{\{((?:.|\n|\r|\.{3})+?)\}\}(?!})/
1470
+ const match = bindREG.exec(val) || []
1471
+ const matchStr = match[1]?.trim()
1472
+ return matchStr ? `{${matchStr}}` : val
1473
+ }
1474
+
1465
1475
  function parseOptionalChaining (str) {
1466
1476
  const wxsName = `${optionalChainWxsName}.g`
1467
1477
  let optionsRes
@@ -2302,7 +2312,7 @@ function processExternalClasses (el, options) {
2302
2312
  let classNames = classLikeAttrValue.split(/\s+/)
2303
2313
  let hasExternalClass = false
2304
2314
  classNames = classNames.map((className) => {
2305
- if (options.externalClasses.includes(className)) {
2315
+ if (options.externalClasses?.includes(className)) {
2306
2316
  hasExternalClass = true
2307
2317
  return `($attrs[${stringify(className)}] || '')`
2308
2318
  }
@@ -2345,12 +2355,12 @@ function processExternalClasses (el, options) {
2345
2355
  }
2346
2356
 
2347
2357
  function processScoped (el) {
2348
- if (hasScoped && isRealNode(el)) {
2358
+ if (hasScoped && isRealNode(el) && (isWeb(mode) && el.tag !== 'component')) { // 处理web下 template第一个元素不设置mpx-app-scope
2349
2359
  const rootModuleId = ctorType === 'component' ? '' : MPX_APP_MODULE_ID // 处理app全局样式对页面的影响
2350
2360
  const staticClass = getAndRemoveAttr(el, 'class').val
2351
2361
  addAttrs(el, [{
2352
2362
  name: 'class',
2353
- value: `${staticClass || ''} ${moduleId} ${rootModuleId}`
2363
+ value: `${staticClass || ''} ${moduleId || ''} ${rootModuleId}`
2354
2364
  }])
2355
2365
  }
2356
2366
  }
@@ -2449,7 +2459,7 @@ function getVirtualHostRoot (options, meta) {
2449
2459
  const rootView = createASTElement('view', [
2450
2460
  {
2451
2461
  name: 'class',
2452
- value: `${MPX_ROOT_VIEW} host-${moduleId}`
2462
+ value: `${MPX_ROOT_VIEW} ${moduleId ? 'host-' + moduleId : ''}` // 解决template2vue中拿不到moduleId的情况
2453
2463
  },
2454
2464
  {
2455
2465
  name: 'v-on',
@@ -2528,8 +2538,33 @@ function processTemplate (el) {
2528
2538
  }
2529
2539
  }
2530
2540
 
2531
- function postProcessTemplate (el) {
2541
+ function processImport (el, meta) { // 收集import引用的地址
2542
+ if (el.tag === 'import' && el.attrsMap.src) {
2543
+ if (!meta.templateSrcList) {
2544
+ meta.templateSrcList = []
2545
+ }
2546
+ if (!meta.templateSrcList.includes(el.attrsMap.src)) {
2547
+ meta.templateSrcList.push(el.attrsMap.src)
2548
+ }
2549
+ }
2550
+ }
2551
+
2552
+ function postProcessTemplate (el, meta, options) {
2532
2553
  if (el.isTemplate) {
2554
+ if (mode === 'web') {
2555
+ if (!meta.inlineTemplateMap) {
2556
+ meta.inlineTemplateMap = {}
2557
+ }
2558
+ const name = el.attrsMap.name // 行内的template有name就收集template的内容和给内容生成一个地址
2559
+ if (name) {
2560
+ const content = getTemplateContent(options.template, name)
2561
+ const filePath = options.filePath.replace(/.mpx$/, `-${name}.wxml`)
2562
+ meta.inlineTemplateMap[name] = {
2563
+ filePath,
2564
+ content
2565
+ }
2566
+ }
2567
+ }
2533
2568
  processingTemplate = false
2534
2569
  return true
2535
2570
  }
@@ -2679,6 +2714,7 @@ function processMpxTagName (el) {
2679
2714
  }
2680
2715
 
2681
2716
  function processElement (el, root, options, meta) {
2717
+ const initialTag = el.tag // 预存,在这个阶段增加_fakeTemplate值会影响web小程序元素trans web元素
2682
2718
  processAtMode(el)
2683
2719
  // 如果已经标记了这个元素要被清除,直接return跳过后续处理步骤
2684
2720
  if (el._matchStatus === statusEnum.MISMATCH) {
@@ -2705,10 +2741,17 @@ function processElement (el, root, options, meta) {
2705
2741
  const transAli = mode === 'ali' && srcMode === 'wx'
2706
2742
 
2707
2743
  if (isWeb(mode)) {
2744
+ if (initialTag === 'block') {
2745
+ el._fakeTemplate = true // 该值是在template2vue中处理block转换的template的情况
2746
+ }
2708
2747
  // 收集内建组件
2709
2748
  processBuiltInComponents(el, meta)
2710
2749
  // 预处理代码维度条件编译
2711
2750
  processIfWeb(el)
2751
+ // 预处理template逻辑
2752
+ processTemplate(el)
2753
+ // 预处理import逻辑
2754
+ processImport(el, meta)
2712
2755
  processScoped(el)
2713
2756
  processEventWeb(el)
2714
2757
  // processWebExternalClassesHack(el, options)
@@ -2771,8 +2814,9 @@ function processElement (el, root, options, meta) {
2771
2814
  function closeElement (el, options, meta) {
2772
2815
  postProcessAtMode(el)
2773
2816
  postProcessWxs(el, meta)
2774
-
2775
2817
  if (isWeb(mode)) {
2818
+ // 处理web下template逻辑
2819
+ postProcessTemplate(el, meta, options)
2776
2820
  // 处理代码维度条件编译移除死分支
2777
2821
  postProcessIf(el)
2778
2822
  return
@@ -2783,7 +2827,7 @@ function closeElement (el, options, meta) {
2783
2827
  return
2784
2828
  }
2785
2829
 
2786
- const isTemplate = postProcessTemplate(el) || processingTemplate
2830
+ const isTemplate = postProcessTemplate(el, meta) || processingTemplate
2787
2831
  if (!isTemplate) {
2788
2832
  if (!isNative) {
2789
2833
  postProcessComponentIs(el, (child) => {
@@ -2905,6 +2949,11 @@ function serialize (root) {
2905
2949
  result += node.text
2906
2950
  }
2907
2951
  }
2952
+ if (mode === 'web') {
2953
+ if ((node.tag === 'template' && node.attrsMap && node.attrsMap.name) || node.tag === 'import') {
2954
+ return result
2955
+ }
2956
+ }
2908
2957
 
2909
2958
  if (node.type === 1) {
2910
2959
  if (node.tag !== 'temp-node') {
@@ -3209,6 +3258,7 @@ module.exports = {
3209
3258
  genNode,
3210
3259
  makeAttrsMap,
3211
3260
  stringifyAttr,
3261
+ vbindMustache,
3212
3262
  parseMustache,
3213
3263
  parseMustacheWithContext,
3214
3264
  stringifyWithResolveComputed,
@@ -0,0 +1,47 @@
1
+ /*
2
+ 对template.wxml文件做截取
3
+ @source原始小程序文件
4
+ @name 要匹配的该name的template
5
+ */
6
+ module.exports = function (source, name) {
7
+ // 使用正则表达式匹配具有 name 的 template 标签及其所有子元素
8
+ // 正则表达式使用非贪婪匹配来递归匹配嵌套的 template
9
+ const regex = new RegExp(`(<template[^>]*\\bname=["|']${name}["|'][^>]*>).*?`, 'g')
10
+
11
+ let startIndex = 0
12
+ let endIndex = 0
13
+ const match = regex.exec(source)
14
+ // 逐个处理匹配到的 template 标签及其内容
15
+ if (match) {
16
+ const matchRes = match[0]
17
+ const reg = /<\/?template\s*[^>]*>/g
18
+ let n = 0
19
+ startIndex = match.index
20
+ endIndex = startIndex + matchRes.length
21
+ let html = source.slice(endIndex)
22
+ while (html) {
23
+ const matchRes = html.match(reg)
24
+ if (matchRes.length) {
25
+ const matchTemp = matchRes[0]
26
+ const matchIndex = html.indexOf(matchTemp)
27
+ const matchLength = matchTemp.length
28
+ const cutLength = matchIndex + matchLength
29
+ if (matchTemp.startsWith('</template>')) {
30
+ if (n === 0) {
31
+ endIndex += cutLength
32
+ break
33
+ } else {
34
+ n--
35
+ }
36
+ } else {
37
+ n++
38
+ }
39
+ endIndex += cutLength
40
+ html = html.slice(cutLength)
41
+ }
42
+ }
43
+ } else {
44
+ return ''
45
+ }
46
+ return source.slice(startIndex, endIndex)
47
+ }
package/lib/web/index.js CHANGED
@@ -108,6 +108,8 @@ module.exports = function ({
108
108
  builtInComponentsMap: templateRes.builtInComponentsMap,
109
109
  genericsInfo: templateRes.genericsInfo,
110
110
  wxsModuleMap: templateRes.wxsModuleMap,
111
+ templateSrcList: templateRes.templateSrcList,
112
+ inlineTemplateMap: templateRes.inlineTemplateMap,
111
113
  localComponentsMap: jsonRes.localComponentsMap
112
114
  }, callback)
113
115
  }
@@ -3,6 +3,8 @@ const loaderUtils = require('loader-utils')
3
3
  const normalize = require('../utils/normalize')
4
4
  const shallowStringify = require('../utils/shallow-stringify')
5
5
  const optionProcessorPath = normalize.lib('runtime/optionProcessor')
6
+ const wxmlTemplateLoader = normalize.lib('web/wxml-template-loader')
7
+ const WriteVfsDependency = require('../dependencies/WriteVfsDependency')
6
8
  const {
7
9
  buildComponentsMap,
8
10
  getRequireScript,
@@ -22,18 +24,20 @@ module.exports = function (script, {
22
24
  builtInComponentsMap,
23
25
  genericsInfo,
24
26
  wxsModuleMap,
27
+ templateSrcList,
28
+ inlineTemplateMap,
25
29
  localComponentsMap
26
30
  }, callback) {
27
- const { projectRoot, appInfo, webConfig } = loaderContext.getMpx()
31
+ const { projectRoot, appInfo, webConfig, __vfs: vfs, parentLocalComponentsMap } = loaderContext.getMpx()
28
32
 
29
33
  let output = '/* script */\n'
30
-
31
34
  let scriptSrcMode = srcMode
32
35
  if (script) {
33
36
  scriptSrcMode = script.mode || scriptSrcMode
34
37
  } else {
35
38
  script = { tag: 'script' }
36
39
  }
40
+
37
41
  output += genComponentTag(script, {
38
42
  attrs (script) {
39
43
  const attrs = Object.assign({}, script.attrs)
@@ -58,17 +62,36 @@ module.exports = function (script, {
58
62
  content += ` wxsModules.${module} = ${expression}\n`
59
63
  })
60
64
  }
61
-
65
+ content += 'const templateModules = {}\n'
66
+ if (templateSrcList?.length) { // import标签处理
67
+ templateSrcList?.forEach((item) => {
68
+ content += `
69
+ const tempLoaderResult = require(${stringifyRequest(this, `!!${wxmlTemplateLoader}!${item}`)})\n
70
+ Object.assign(templateModules, tempLoaderResult)\n`
71
+ })
72
+ }
73
+ // 把wxml要的localComponentsMap merge到parentLocalComponentsMap中这样在 template2vue中就可以拿到对应的值
74
+ Object.assign(parentLocalComponentsMap, localComponentsMap)
62
75
  // 获取组件集合
63
76
  const componentsMap = buildComponentsMap({ localComponentsMap, builtInComponentsMap, loaderContext, jsonConfig })
64
-
65
77
  // 获取pageConfig
66
78
  const pageConfig = {}
67
79
  if (ctorType === 'page') {
68
80
  Object.assign(pageConfig, jsonConfig)
69
81
  delete pageConfig.usingComponents
70
82
  }
71
-
83
+ if (inlineTemplateMap) { // 处理行内template(只有属性为name的情况)
84
+ const inlineTemplateMapLists = Object.keys(inlineTemplateMap)
85
+ if (inlineTemplateMapLists.length) {
86
+ inlineTemplateMapLists.forEach((name) => {
87
+ const { filePath, content } = inlineTemplateMap[name]
88
+ loaderContext._module.addPresentationalDependency(new WriteVfsDependency(filePath, content)) // 处理缓存报错的情况
89
+ vfs.writeModule(filePath, content) // 截取template写入文件
90
+ const expression = `getComponent(require(${stringifyRequest(loaderContext, `${filePath}?is=${name}&localComponentsMap=${encodeURIComponent(JSON.stringify(localComponentsMap))}&isTemplate`)}))`
91
+ componentsMap[name] = expression
92
+ })
93
+ }
94
+ }
72
95
  content += buildGlobalParams({ moduleId, scriptSrcMode, loaderContext, isProduction, webConfig, hasApp })
73
96
  content += getRequireScript({ ctorType, script, loaderContext })
74
97
  content += `
@@ -78,7 +101,7 @@ module.exports = function (script, {
78
101
  outputPath: ${JSON.stringify(outputPath)},
79
102
  pageConfig: ${JSON.stringify(pageConfig)},
80
103
  // @ts-ignore
81
- componentsMap: ${shallowStringify(componentsMap)},
104
+ componentsMap: Object.assign(${shallowStringify(componentsMap)}, templateModules),
82
105
  componentGenerics: ${JSON.stringify(componentGenerics)},
83
106
  genericsInfo: ${JSON.stringify(genericsInfo)},
84
107
  wxsMixin: getWxsMixin(wxsModules),
@@ -87,7 +110,6 @@ module.exports = function (script, {
87
110
  return content
88
111
  }
89
112
  })
90
-
91
113
  callback(null, {
92
114
  output
93
115
  })
@@ -31,7 +31,7 @@ module.exports = function (template, {
31
31
  const { resourcePath, rawResourcePath } = parseRequest(loaderContext.resource)
32
32
  const builtInComponentsMap = {}
33
33
 
34
- let wxsModuleMap, genericsInfo
34
+ let wxsModuleMap, genericsInfo, inlineTemplateMap, templateSrcList
35
35
  let output = '/* template */\n'
36
36
 
37
37
  if (ctorType === 'app') {
@@ -54,7 +54,6 @@ module.exports = function (template, {
54
54
  if (template.lang) {
55
55
  return callback(new Error('[mpx loader][' + loaderContext.resource + ']: ' + 'template lang is not supported in trans web mode temporarily, we will support it in the future!'))
56
56
  }
57
-
58
57
  output += genComponentTag(template, (template) => {
59
58
  if (ctorType === 'app') {
60
59
  return template.content
@@ -104,6 +103,12 @@ module.exports = function (template, {
104
103
  wxsContentMap[`${rawResourcePath}~${module}`] = meta.wxsContentMap[module]
105
104
  }
106
105
  }
106
+ if (meta.inlineTemplateMap) {
107
+ inlineTemplateMap = meta.inlineTemplateMap
108
+ }
109
+ if (meta.templateSrcList?.length) {
110
+ templateSrcList = meta.templateSrcList
111
+ }
107
112
  if (meta.builtInComponentsMap) {
108
113
  Object.keys(meta.builtInComponentsMap).forEach((name) => {
109
114
  builtInComponentsMap[name] = {
@@ -114,15 +119,16 @@ module.exports = function (template, {
114
119
  if (meta.genericsInfo) {
115
120
  genericsInfo = meta.genericsInfo
116
121
  }
117
- return templateCompiler.serialize(root)
122
+ return templateCompiler.serialize(root, moduleId) // 增加moduleId给到template2vue拿到正确的scopedId
118
123
  }
119
124
  })
120
125
  output += '\n'
121
126
  }
122
-
123
127
  callback(null, {
124
128
  output,
125
129
  builtInComponentsMap,
130
+ inlineTemplateMap,
131
+ templateSrcList,
126
132
  genericsInfo,
127
133
  wxsModuleMap
128
134
  })