@mpxjs/webpack-plugin 2.10.17-beta.7 → 2.10.17-beta.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.
@@ -0,0 +1,193 @@
1
+ <template>
2
+ <scroll-view wx:ref="recycleViewRef" class="mpx-recycle-view" scroll-y wx:style="{{ scrollViewStyle }}" type="custom"
3
+ enhanced="{{ enhanced }}" scroll-with-animation="{{ scrollWithAnimation }}" bounces="{{ bounces }}"
4
+ show-scrollbar="{{ showScrollbar }}" refresher-enabled="{{ refresherEnabled }}"
5
+ refresher-triggered="{{ refresherTriggered }}" bindscroll="onScroll" bindrefresherrefresh="onRefresh"
6
+ scroll-into-view="{{ scrollIntoViewId }}" scroll-into-view-alignment="{{ viewPosition }}">
7
+ <block wx:if="{{ useListHeader }}">
8
+ <list-header listHeaderData="{{ listHeaderData }}"></list-header>
9
+ </block>
10
+ <block wx:for="{{ convertedListData }}" wx:key="index">
11
+ <sticky-section>
12
+ <!-- section header -->
13
+ <block wx:if="{{ item.hasSectionHeader }}">
14
+ <block wx:if="{{ enableSticky }}">
15
+ <sticky-header>
16
+ <section-header itemData="{{ item.headerData }}" id="{{ item._domId }}"></section-header>
17
+ </sticky-header>
18
+ </block>
19
+ <block wx:else>
20
+ <section-header itemData="{{ item.headerData }}" id="{{ item._domId }}"></section-header>
21
+ </block>
22
+
23
+ </block>
24
+ <block wx:for="{{ item.data }}" wx:for-item="subItem" wx:key="subIndex">
25
+ <!-- section items -->
26
+ <recycle-item itemData="{{ subItem.itemData }}" id="{{ subItem._domId }}"></recycle-item>
27
+ </block>
28
+ </sticky-section>
29
+ </block>
30
+ </scroll-view>
31
+ </template>
32
+
33
+ <script>
34
+ import { createComponent } from '@mpxjs/core'
35
+
36
+ createComponent({
37
+ properties: {
38
+ height: {
39
+ type: Number,
40
+ value: null
41
+ },
42
+ width: {
43
+ type: Number,
44
+ value: null
45
+ },
46
+ listData: {
47
+ type: Array,
48
+ value: []
49
+ },
50
+ enableSticky: {
51
+ type: Boolean,
52
+ value: false
53
+ },
54
+ showScrollbar: {
55
+ type: Boolean,
56
+ value: false
57
+ },
58
+ enhanced: {
59
+ type: Boolean,
60
+ value: false
61
+ },
62
+ bounces: {
63
+ type: Boolean,
64
+ value: false
65
+ },
66
+ refresherEnabled: {
67
+ type: Boolean,
68
+ value: false
69
+ },
70
+ refresherTriggered: {
71
+ type: Boolean,
72
+ value: false
73
+ },
74
+ listHeaderData: {
75
+ type: Object,
76
+ value: null
77
+ },
78
+ scrollWithAnimation: {
79
+ type: Boolean,
80
+ value: false
81
+ },
82
+ useListHeader: {
83
+ type: Boolean,
84
+ value: false
85
+ }
86
+ },
87
+ data: {
88
+ convertedListData: [],
89
+ scrollIntoViewId: '',
90
+ viewPosition: 'start'
91
+ },
92
+ computed: {
93
+ scrollViewStyle() {
94
+ return `height: ${this.formatDimension(this.height)};width: ${this.formatDimension(this.width)}`
95
+ }
96
+ },
97
+ watch: {
98
+ listData: {
99
+ handler(newVal) {
100
+ this.convertedListData = this.convertToSectionListData(newVal)
101
+ },
102
+ immediate: true
103
+ }
104
+ },
105
+ methods: {
106
+ formatDimension(value) {
107
+ return typeof value === 'number' ? `${value}px` : value || '100%'
108
+ },
109
+ onScroll(e) {
110
+ this.triggerEvent('scroll', e)
111
+ },
112
+ onRefresh(e) {
113
+ this.triggerEvent('refresh', e)
114
+ },
115
+ scrollToIndex({ index, animated, viewPosition = 0 }) {
116
+ if (index >= 0) {
117
+ this.scrollIntoViewId = `mpx-recycle-item-${index}`
118
+ switch (viewPosition) {
119
+ case 0:
120
+ this.viewPosition = 'start'
121
+ break
122
+ case 0.5:
123
+ this.viewPosition = 'center'
124
+ break
125
+ case 1:
126
+ this.viewPosition = 'end'
127
+ break
128
+ default:
129
+ this.viewPosition = 'start'
130
+ }
131
+ }
132
+ },
133
+ convertToSectionListData(data) {
134
+ const sections = []
135
+ let currentSection = null
136
+
137
+ data.forEach((item, index) => {
138
+ if (item.isSectionHeader) {
139
+ // 如果已经存在一个 section,先把它添加到 sections 中
140
+ if (currentSection) {
141
+ sections.push(currentSection)
142
+ }
143
+ // 创建新的 section
144
+ currentSection = {
145
+ headerData: item,
146
+ data: [],
147
+ hasSectionHeader: true,
148
+ _domId: `mpx-recycle-item-${index}`
149
+ }
150
+ } else {
151
+ // 如果没有当前 section,创建一个默认的
152
+ if (!currentSection) {
153
+ // 创建默认section (无header的section)
154
+ currentSection = {
155
+ headerData: null,
156
+ data: [],
157
+ hasSectionHeader: false
158
+ }
159
+ }
160
+ currentSection.data.push({
161
+ itemData: item,
162
+ _domId: `mpx-recycle-item-${index}`
163
+ })
164
+ }
165
+ })
166
+
167
+ // 添加最后一个 section
168
+ if (currentSection) {
169
+ sections.push(currentSection)
170
+ }
171
+
172
+ return sections
173
+ }
174
+ }
175
+ })
176
+ </script>
177
+
178
+ <script type="application/json">
179
+ {
180
+ "component": true,
181
+ "componentGenerics": {
182
+ "recycle-item": {
183
+ "default": "./mpx-recycle-item-default"
184
+ },
185
+ "section-header": {
186
+ "default": "./mpx-section-header-default"
187
+ },
188
+ "list-header": {
189
+ "default": "./mpx-list-header-default"
190
+ }
191
+ }
192
+ }
193
+ </script>
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <view class="mpx-section-header-default">
3
+ <view class="mpx-default-content">section-header-default</view>
4
+ </view>
5
+ </template>
6
+
7
+ <style lang="stylus" scoped>
8
+ .mpx-section-header-default
9
+ margin 4px 16px
10
+ padding 16px
11
+ background #fff
12
+ border-radius 8px
13
+ box-shadow 0 2px 4px rgba(0,0,0,0.1)
14
+
15
+ .mpx-default-content
16
+ display flex
17
+ flex-direction column
18
+ font-size 14px
19
+ color #666
20
+
21
+ </style>
@@ -1,7 +1,7 @@
1
1
  const JSON5 = require('json5')
2
2
  const he = require('he')
3
3
  const config = require('../config')
4
- const { MPX_ROOT_VIEW, MPX_APP_MODULE_ID, PARENT_MODULE_ID, MPX_TAG_PAGE_SELECTOR } = require('../utils/const')
4
+ const { MPX_ROOT_VIEW, MPX_APP_MODULE_ID, PARENT_MODULE_ID, MPX_TAG_PAGE_SELECTOR, EXTEND_COMPONENT_CONFIG } = require('../utils/const')
5
5
  const normalize = require('../utils/normalize')
6
6
  const { normalizeCondition } = require('../utils/match-condition')
7
7
  const isValidIdentifierStr = require('../utils/is-valid-identifier-str')
@@ -728,6 +728,7 @@ function parse (template, options) {
728
728
  processElement(element, root, options, meta)
729
729
 
730
730
  tagNames.add(element.tag)
731
+
731
732
  // 统计通过抽象节点方式使用的组件
732
733
  element.attrsList.forEach((attr) => {
733
734
  if (genericRE.test(attr.name)) {
@@ -2432,7 +2433,11 @@ function isRealNode (el) {
2432
2433
  }
2433
2434
 
2434
2435
  function isComponentNode (el) {
2435
- return usingComponents.indexOf(el.tag) !== -1 || el.tag === 'component' || componentGenerics[el.tag]
2436
+ return usingComponents.indexOf(el.tag) !== -1 || el.tag === 'component' || componentGenerics[el.tag] || isExtendComponentNode(el)
2437
+ }
2438
+
2439
+ function isExtendComponentNode (el) {
2440
+ return EXTEND_COMPONENT_CONFIG[el.tag]?.[mode]
2436
2441
  }
2437
2442
 
2438
2443
  function getComponentInfo (el) {
@@ -2440,7 +2445,7 @@ function getComponentInfo (el) {
2440
2445
  }
2441
2446
 
2442
2447
  function isReactComponent (el) {
2443
- return !isComponentNode(el) && isRealNode(el) && !el.isBuiltIn
2448
+ return !isComponentNode(el) && isRealNode(el) && !el.isBuiltIn && !isExtendComponentNode(el)
2444
2449
  }
2445
2450
 
2446
2451
  function processExternalClasses (el, options) {
@@ -7,5 +7,22 @@ module.exports = {
7
7
  MPX_ROOT_VIEW: 'mpx-root-view', // 根节点类名
8
8
  MPX_APP_MODULE_ID: 'mpx-app-scope', // app文件moduleId
9
9
  PARENT_MODULE_ID: '__pid',
10
+ // 扩展组件的平台配置:声明哪些组件在哪些平台有专用实现,哪些使用公共组件
11
+ EXTEND_COMPONENT_CONFIG: {
12
+ 'recycle-view': {
13
+ wx: 'runtime/components/wx/mpx-recycle-view.mpx',
14
+ ali: 'runtime/components/ali/mpx-recycle-view.mpx',
15
+ web: 'runtime/components/web/mpx-recycle-view.vue',
16
+ ios: 'runtime/components/react/dist/mpx-recycle-view.jsx',
17
+ android: 'runtime/components/react/dist/mpx-recycle-view.jsx',
18
+ harmony: 'runtime/components/react/dist/mpx-recycle-view.jsx'
19
+ },
20
+ 'sticky-header': {
21
+ ali: 'runtime/components/ali/mpx-sticky-header.mpx'
22
+ },
23
+ 'sticky-section': {
24
+ ali: 'runtime/components/ali/mpx-sticky-section.mpx'
25
+ }
26
+ },
10
27
  MPX_TAG_PAGE_SELECTOR: 'mpx-page'
11
28
  }
@@ -0,0 +1,43 @@
1
+ const { EXTEND_COMPONENT_CONFIG } = require('./const')
2
+ const normalize = require('./normalize')
3
+
4
+ /**
5
+ * 处理扩展组件的公共方法
6
+ * @param {Object} options 配置选项
7
+ * @param {Object} options.useExtendComponents 使用的扩展组件配置
8
+ * @param {string} options.mode 当前模式 (wx, ali, web, rn 等)
9
+ * @param {Function} options.emitWarning 警告函数
10
+ * @returns {Object} 扩展组件映射对象
11
+ */
12
+ function processExtendComponents (options) {
13
+ const {
14
+ useExtendComponents = {},
15
+ mode,
16
+ emitWarning
17
+ } = options
18
+
19
+ if (!useExtendComponents[mode]) {
20
+ return {}
21
+ }
22
+
23
+ const extendComponents = {}
24
+
25
+ useExtendComponents[mode].forEach((name) => {
26
+ // 从配置中获取该组件在当前平台的具体路径
27
+ const componentConfig = EXTEND_COMPONENT_CONFIG[name]
28
+
29
+ if (componentConfig && componentConfig[mode]) {
30
+ extendComponents[name] = normalize.lib(componentConfig[mode])
31
+ } else if (componentConfig) {
32
+ emitWarning('extend component ' + name + ' is not configured for ' + mode + ' environment!')
33
+ } else {
34
+ emitWarning('extend component ' + name + ' is not supported in any environment!')
35
+ }
36
+ })
37
+
38
+ return extendComponents
39
+ }
40
+
41
+ module.exports = {
42
+ processExtendComponents
43
+ }
@@ -11,6 +11,7 @@ const resolve = require('../utils/resolve')
11
11
  const createJSONHelper = require('../json-compiler/helper')
12
12
  const getRulesRunner = require('../platform/index')
13
13
  const { RESOLVE_IGNORED_ERR } = require('../utils/const')
14
+ const { processExtendComponents } = require('../utils/process-extend-components')
14
15
  const RecordResourceMapDependency = require('../dependencies/RecordResourceMapDependency')
15
16
 
16
17
  module.exports = function (jsonContent, {
@@ -30,11 +31,19 @@ module.exports = function (jsonContent, {
30
31
  mode,
31
32
  srcMode,
32
33
  env,
33
- projectRoot
34
+ projectRoot,
35
+ useExtendComponents = {},
36
+ appInfo
34
37
  } = mpx
35
38
 
36
39
  const context = loaderContext.context
37
40
 
41
+ let hasApp = true
42
+
43
+ if (!appInfo.name) {
44
+ hasApp = false
45
+ }
46
+
38
47
  const emitWarning = (msg) => {
39
48
  loaderContext.emitWarning(
40
49
  new Error('[Mpx json warning][' + loaderContext.resource + ']: ' + msg)
@@ -116,7 +125,16 @@ module.exports = function (jsonContent, {
116
125
  if (ctorType !== 'app') {
117
126
  rulesRunnerOptions.mainKey = ctorType
118
127
  }
119
-
128
+ if (!hasApp || ctorType === 'app') {
129
+ if (useExtendComponents[mode]) {
130
+ const extendComponents = processExtendComponents({
131
+ useExtendComponents,
132
+ mode,
133
+ emitWarning
134
+ })
135
+ jsonObj.usingComponents = Object.assign({}, extendComponents, jsonObj.usingComponents)
136
+ }
137
+ }
120
138
  const rulesRunner = getRulesRunner(rulesRunnerOptions)
121
139
 
122
140
  if (rulesRunner) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.10.17-beta.7",
3
+ "version": "2.10.17-beta.8",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"