@mpxjs/webpack-plugin 2.10.15 → 2.10.16-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.
- package/lib/dependencies/AppEntryDependency.js +2 -2
- package/lib/dependencies/DynamicEntryDependency.js +1 -1
- package/lib/dependencies/ImportDependency.js +102 -0
- package/lib/dependencies/RecordModuleIdMapDependency.js +49 -0
- package/lib/dependencies/ResolveDependency.js +1 -1
- package/lib/{retry-runtime-module.js → dependencies/RetryRuntimeModule.js} +1 -1
- package/lib/helpers.js +2 -0
- package/lib/index.js +51 -25
- package/lib/json-compiler/helper.js +72 -2
- package/lib/json-compiler/index.js +14 -54
- package/lib/json-compiler/plugin.js +2 -2
- package/lib/loader.js +6 -2
- package/lib/native-loader.js +6 -3
- package/lib/platform/json/wx/index.js +24 -29
- package/lib/platform/style/wx/index.js +8 -1
- package/lib/platform/template/wx/component-config/button.js +12 -3
- package/lib/platform/template/wx/component-config/camera.js +12 -0
- package/lib/platform/template/wx/component-config/component.js +31 -33
- package/lib/platform/template/wx/component-config/slider.js +12 -0
- package/lib/platform/template/wx/component-config/unsupported.js +1 -1
- package/lib/react/processJSON.js +39 -71
- package/lib/react/processStyles.js +3 -2
- package/lib/react/processTemplate.js +6 -6
- package/lib/react/script-helper.js +6 -16
- package/lib/react/style-helper.js +10 -2
- package/lib/resolver/AddEnvPlugin.js +13 -0
- package/lib/resolver/AddModePlugin.js +18 -0
- package/lib/runtime/components/react/context.ts +2 -0
- package/lib/runtime/components/react/dist/context.js +1 -0
- package/lib/runtime/components/react/dist/mpx-camera.jsx +102 -0
- package/lib/runtime/components/react/dist/mpx-image.jsx +81 -37
- package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +19 -4
- package/lib/runtime/components/react/dist/mpx-picker-view/index.jsx +3 -2
- package/lib/runtime/components/react/dist/mpx-picker-view-column/index.jsx +9 -6
- package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItem.jsx +8 -11
- package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItemLite.jsx +20 -0
- package/lib/runtime/components/react/dist/mpx-portal/index.jsx +5 -1
- package/lib/runtime/components/react/dist/mpx-progress.jsx +26 -22
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +6 -14
- package/lib/runtime/components/react/dist/mpx-slider.jsx +321 -0
- package/lib/runtime/components/react/dist/mpx-text.jsx +33 -5
- package/lib/runtime/components/react/dist/mpx-view.jsx +8 -11
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +1 -1
- package/lib/runtime/components/react/dist/utils.jsx +16 -6
- package/lib/runtime/components/react/mpx-camera.tsx +167 -0
- package/lib/runtime/components/react/mpx-image.tsx +89 -42
- package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +31 -4
- package/lib/runtime/components/react/mpx-picker-view/index.tsx +4 -1
- package/lib/runtime/components/react/mpx-picker-view-column/index.tsx +19 -8
- package/lib/runtime/components/react/mpx-picker-view-column/pickerViewColumnItem.tsx +8 -12
- package/lib/runtime/components/react/mpx-picker-view-column/pickerViewColumnItemLite.tsx +55 -0
- package/lib/runtime/components/react/mpx-portal/index.tsx +8 -2
- package/lib/runtime/components/react/mpx-progress.tsx +26 -24
- package/lib/runtime/components/react/mpx-scroll-view.tsx +6 -17
- package/lib/runtime/components/react/mpx-slider.tsx +444 -0
- package/lib/runtime/components/react/mpx-text.tsx +38 -5
- package/lib/runtime/components/react/mpx-view.tsx +8 -11
- package/lib/runtime/components/react/mpx-web-view.tsx +1 -1
- package/lib/runtime/components/react/utils.tsx +15 -6
- package/lib/runtime/components/web/mpx-input.vue +1 -1
- package/lib/runtime/components/web/mpx-scroll-view.vue +7 -1
- package/lib/runtime/components/web/mpx-video.vue +12 -1
- package/lib/runtime/optionProcessor.js +3 -1
- package/lib/runtime/optionProcessorReact.js +4 -2
- package/lib/script-setup-compiler/index.js +2 -2
- package/lib/style-compiler/index.js +3 -2
- package/lib/style-compiler/load-postcss-config.js +1 -1
- package/lib/style-compiler/plugins/trans-special.js +10 -2
- package/lib/style-compiler/strip-conditional-loader.js +155 -15
- package/lib/template-compiler/compiler.js +262 -61
- package/lib/template-compiler/gen-node-react.js +18 -6
- package/lib/template-compiler/index.js +6 -4
- package/lib/template-compiler/parse-exps.js +1 -1
- package/lib/utils/chain-assign.js +47 -0
- package/lib/utils/check-core-version-match.js +75 -15
- package/lib/utils/const.js +2 -1
- package/lib/utils/dom-tag-config.js +1 -1
- package/lib/utils/env.js +6 -1
- package/lib/utils/get-build-tag-component.js +35 -0
- package/lib/utils/pre-process-json.js +5 -0
- package/lib/web/processJSON.js +44 -16
- package/lib/web/processScript.js +1 -1
- package/lib/web/processTemplate.js +4 -4
- package/lib/web/script-helper.js +19 -9
- package/lib/wxs/pre-loader.js +5 -5
- package/lib/wxss/loader.js +1 -9
- package/package.json +14 -5
- package/LICENSE +0 -433
- package/lib/dependencies/ImportDependencyTemplate.js +0 -50
|
@@ -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 } = require('../utils/const')
|
|
4
|
+
const { MPX_ROOT_VIEW, MPX_APP_MODULE_ID, PARENT_MODULE_ID, MPX_TAG_PAGE_SELECTOR } = 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')
|
|
@@ -15,7 +15,8 @@ const { isNonPhrasingTag } = require('../utils/dom-tag-config')
|
|
|
15
15
|
const setBaseWxml = require('../runtime-render/base-wxml')
|
|
16
16
|
const { parseExp } = require('./parse-exps')
|
|
17
17
|
const shallowStringify = require('../utils/shallow-stringify')
|
|
18
|
-
const { isReact, isWeb } = require('../utils/env')
|
|
18
|
+
const { isReact, isWeb, isNoMode } = require('../utils/env')
|
|
19
|
+
const { capitalToHyphen } = require('../utils/string')
|
|
19
20
|
|
|
20
21
|
const no = function () {
|
|
21
22
|
return false
|
|
@@ -119,6 +120,8 @@ const rulesResultMap = new Map()
|
|
|
119
120
|
let usingComponents = []
|
|
120
121
|
let usingComponentsInfo = {}
|
|
121
122
|
let componentGenerics = {}
|
|
123
|
+
// 跨平台语法检测的配置,在模块加载时初始化一次
|
|
124
|
+
let crossPlatformConfig = null
|
|
122
125
|
|
|
123
126
|
function updateForScopesMap () {
|
|
124
127
|
forScopesMap = {}
|
|
@@ -147,11 +150,11 @@ const deleteErrorInResultMap = (node) => {
|
|
|
147
150
|
}
|
|
148
151
|
|
|
149
152
|
function baseWarn (msg) {
|
|
150
|
-
console.warn(('[template
|
|
153
|
+
console.warn(('[Mpx template warning]: ' + msg))
|
|
151
154
|
}
|
|
152
155
|
|
|
153
156
|
function baseError (msg) {
|
|
154
|
-
console.error(('[template
|
|
157
|
+
console.error(('[Mpx template error]: ' + msg))
|
|
155
158
|
}
|
|
156
159
|
|
|
157
160
|
const decodeMap = {
|
|
@@ -176,11 +179,11 @@ const i18nWxsPath = normalize.lib('runtime/i18n.wxs')
|
|
|
176
179
|
const i18nWxsLoaderPath = normalize.lib('wxs/i18n-loader.js')
|
|
177
180
|
// 添加~前缀避免wxs绝对路径在存在projectRoot时被拼接为错误路径
|
|
178
181
|
const i18nWxsRequest = '~' + i18nWxsLoaderPath + '!' + i18nWxsPath
|
|
179
|
-
const i18nModuleName = '
|
|
182
|
+
const i18nModuleName = '_i_'
|
|
180
183
|
const stringifyWxsPath = '~' + normalize.lib('runtime/stringify.wxs')
|
|
181
|
-
const stringifyModuleName = '
|
|
184
|
+
const stringifyModuleName = '_s_'
|
|
182
185
|
const optionalChainWxsPath = '~' + normalize.lib('runtime/oc.wxs')
|
|
183
|
-
const optionalChainWxsName = '
|
|
186
|
+
const optionalChainWxsName = '_oc_' // 改成_oc解决web下_o重名问题
|
|
184
187
|
|
|
185
188
|
const tagRES = /(\{\{(?:.|\n|\r)+?\}\})(?!})/
|
|
186
189
|
const tagRE = /\{\{((?:.|\n|\r)+?)\}\}(?!})/
|
|
@@ -637,8 +640,9 @@ function parse (template, options) {
|
|
|
637
640
|
processingTemplate = false
|
|
638
641
|
rulesResultMap.clear()
|
|
639
642
|
componentGenerics = options.componentGenerics || {}
|
|
643
|
+
// 初始化跨平台语法检测配置(每次解析时只初始化一次)
|
|
644
|
+
crossPlatformConfig = initCrossPlatformConfig()
|
|
640
645
|
|
|
641
|
-
if (typeof options.usingComponentsInfo === 'string') options.usingComponentsInfo = JSON.parse(options.usingComponentsInfo)
|
|
642
646
|
usingComponents = Object.keys(options.usingComponentsInfo)
|
|
643
647
|
usingComponentsInfo = options.usingComponentsInfo
|
|
644
648
|
|
|
@@ -681,7 +685,6 @@ function parse (template, options) {
|
|
|
681
685
|
meta.options.virtualHost = true
|
|
682
686
|
}
|
|
683
687
|
let currentParent
|
|
684
|
-
let multiRootError
|
|
685
688
|
// 用于记录模板用到的组件,匹配引用组件,看是否有冗余
|
|
686
689
|
const tagNames = new Set()
|
|
687
690
|
|
|
@@ -760,7 +763,10 @@ function parse (template, options) {
|
|
|
760
763
|
if (!currentParent) genTempRoot()
|
|
761
764
|
|
|
762
765
|
const children = currentParent.children
|
|
763
|
-
|
|
766
|
+
|
|
767
|
+
const isTextLikeParent = currentParent.tag === 'text' || currentParent.tag === 'mpx-text' || currentParent.tag === 'Text' || currentParent.tag === 'mpx-simple-text'
|
|
768
|
+
|
|
769
|
+
if (!isTextLikeParent) {
|
|
764
770
|
text = text.trim()
|
|
765
771
|
} else {
|
|
766
772
|
text = text.trim() ? text : ''
|
|
@@ -793,9 +799,10 @@ function parse (template, options) {
|
|
|
793
799
|
}
|
|
794
800
|
})
|
|
795
801
|
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
802
|
+
// multiRoot
|
|
803
|
+
// if (root.tag === 'temp-node' && root.children && root.children.filter(node => node.tag !== 'temp-node').length > 1) {
|
|
804
|
+
// error$1('Template fields should has one single root, considering wrapping your template content with <view> or <text> tag!')
|
|
805
|
+
// }
|
|
799
806
|
|
|
800
807
|
if (hasI18n) {
|
|
801
808
|
if (i18nInjectableComputed.length) {
|
|
@@ -1000,12 +1007,34 @@ function processComponentIs (el, options) {
|
|
|
1000
1007
|
}
|
|
1001
1008
|
|
|
1002
1009
|
const range = getAndRemoveAttr(el, 'range').val
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1010
|
+
|
|
1011
|
+
// Map<CurrentName, SourceName>
|
|
1012
|
+
let ranges
|
|
1013
|
+
if (range) {
|
|
1014
|
+
ranges = range.split(',').map(i => i.trim()).filter(i => i)
|
|
1015
|
+
} else {
|
|
1016
|
+
// 根据原始用户写的usingComponents字段生成ranges
|
|
1017
|
+
ranges = options.originalUsingComponents
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
const rangeMap = new Map()
|
|
1021
|
+
ranges.forEach(name => {
|
|
1022
|
+
rangeMap.set(['ali', 'swan'].includes(mode) ? capitalToHyphen(name) : name, name)
|
|
1007
1023
|
})
|
|
1008
|
-
|
|
1024
|
+
|
|
1025
|
+
// Map<CurrentName, SourceName>
|
|
1026
|
+
el.componentMap = new Map()
|
|
1027
|
+
usingComponents.forEach((name) => {
|
|
1028
|
+
if (rangeMap.size === 0) {
|
|
1029
|
+
el.componentMap.set(name, name)
|
|
1030
|
+
} else {
|
|
1031
|
+
if (rangeMap.has(name)) {
|
|
1032
|
+
el.componentMap.set(name, rangeMap.get(name))
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
})
|
|
1036
|
+
|
|
1037
|
+
if (el.componentMap.size === 0) {
|
|
1009
1038
|
warn$1('Component in which <component> tag is used must have a non blank usingComponents field')
|
|
1010
1039
|
}
|
|
1011
1040
|
|
|
@@ -1383,7 +1412,11 @@ function processEvent (el, options) {
|
|
|
1383
1412
|
const targetConfigs = isCapture ? eventConfigMap[type].captureConfigs : eventConfigMap[type].configs
|
|
1384
1413
|
targetConfigs.push(Object.assign({ name }, parsedFunc))
|
|
1385
1414
|
if (modifiers.indexOf('proxy') > -1 || options.forceProxyEvent) {
|
|
1386
|
-
|
|
1415
|
+
if (isCapture) {
|
|
1416
|
+
eventConfigMap[type].captureProxy = true
|
|
1417
|
+
} else {
|
|
1418
|
+
eventConfigMap[type].proxy = true
|
|
1419
|
+
}
|
|
1387
1420
|
}
|
|
1388
1421
|
}
|
|
1389
1422
|
}
|
|
@@ -1423,10 +1456,10 @@ function processEvent (el, options) {
|
|
|
1423
1456
|
}
|
|
1424
1457
|
|
|
1425
1458
|
for (const type in eventConfigMap) {
|
|
1426
|
-
const { configs = [], captureConfigs = [], proxy } = eventConfigMap[type]
|
|
1459
|
+
const { configs = [], captureConfigs = [], proxy, captureProxy } = eventConfigMap[type]
|
|
1427
1460
|
|
|
1428
1461
|
let needBubblingBind = isNeedBind(configs, proxy)
|
|
1429
|
-
let needCaptureBind = isNeedBind(captureConfigs,
|
|
1462
|
+
let needCaptureBind = isNeedBind(captureConfigs, captureProxy)
|
|
1430
1463
|
|
|
1431
1464
|
const escapedType = dash2hump(type)
|
|
1432
1465
|
// 排除特殊情况
|
|
@@ -1588,7 +1621,7 @@ function parseOptionalChaining (str) {
|
|
|
1588
1621
|
}
|
|
1589
1622
|
if (grammarMap.checkState() && haveNotGetValue) {
|
|
1590
1623
|
// 值查找结束但是语法未闭合或者处理到边界还未结束,抛异常
|
|
1591
|
-
throw new Error('[
|
|
1624
|
+
throw new Error('[Mpx template error]: optionChain option value illegal!!!')
|
|
1592
1625
|
}
|
|
1593
1626
|
haveNotGetValue = true
|
|
1594
1627
|
let keyValue = ''
|
|
@@ -1638,7 +1671,7 @@ function parseOptionalChaining (str) {
|
|
|
1638
1671
|
}
|
|
1639
1672
|
if (grammarMap.checkState() && haveNotGetValue) {
|
|
1640
1673
|
// key值查找结束但是语法未闭合或者处理到边界还未结束,抛异常
|
|
1641
|
-
throw new Error('[
|
|
1674
|
+
throw new Error('[Mpx template error]: optionChain option key illegal!!!')
|
|
1642
1675
|
}
|
|
1643
1676
|
if (keyValue) {
|
|
1644
1677
|
chainKey += `,'${keyValue}'`
|
|
@@ -2080,13 +2113,24 @@ function postProcessIf (el) {
|
|
|
2080
2113
|
replaceNode(el, getTempNode())._if = false
|
|
2081
2114
|
}
|
|
2082
2115
|
} else {
|
|
2116
|
+
el._if = null
|
|
2083
2117
|
attrs = [{
|
|
2084
2118
|
name: config[mode].directive.if,
|
|
2085
2119
|
value: el.if.raw
|
|
2086
2120
|
}]
|
|
2087
2121
|
}
|
|
2088
2122
|
} else if (el.elseif) {
|
|
2123
|
+
if (el.for) {
|
|
2124
|
+
error$1(`wx:elif (wx:elif="${el.elseif.raw}") invalidly used on the for-list <"${el.tag}"> which has a wx:for directive, please create a block element to wrap the for-list and move the elif-directive to it`)
|
|
2125
|
+
return
|
|
2126
|
+
}
|
|
2127
|
+
|
|
2089
2128
|
prevNode = findPrevNode(el)
|
|
2129
|
+
if (!prevNode || prevNode._if === undefined) {
|
|
2130
|
+
error$1(`wx:elif="${el.elseif.raw}" used on element [${el.tag}] without corresponding wx:if or wx:elif.`)
|
|
2131
|
+
return
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2090
2134
|
if (prevNode._if === true) {
|
|
2091
2135
|
removeNode(el)
|
|
2092
2136
|
} else if (prevNode._if === false) {
|
|
@@ -2106,6 +2150,7 @@ function postProcessIf (el) {
|
|
|
2106
2150
|
removeNode(el)
|
|
2107
2151
|
}
|
|
2108
2152
|
} else {
|
|
2153
|
+
el._if = null
|
|
2109
2154
|
attrs = [{
|
|
2110
2155
|
name: config[mode].directive.elseif,
|
|
2111
2156
|
value: el.elseif.raw
|
|
@@ -2113,7 +2158,17 @@ function postProcessIf (el) {
|
|
|
2113
2158
|
}
|
|
2114
2159
|
}
|
|
2115
2160
|
} else if (el.else) {
|
|
2161
|
+
if (el.for) {
|
|
2162
|
+
error$1(`wx:else invalidly used on the for-list <"${el.tag}"> which has a wx:for directive, please create a block element to wrap the for-list and move the else-directive to it`)
|
|
2163
|
+
return
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2116
2166
|
prevNode = findPrevNode(el)
|
|
2167
|
+
if (!prevNode || prevNode._if === undefined) {
|
|
2168
|
+
error$1(`wx:else used on element [${el.tag}] without corresponding wx:if or wx:elif.`)
|
|
2169
|
+
return
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2117
2172
|
if (prevNode._if === true) {
|
|
2118
2173
|
removeNode(el)
|
|
2119
2174
|
} else if (prevNode._if === false) {
|
|
@@ -2137,23 +2192,100 @@ function addIfCondition (el, condition) {
|
|
|
2137
2192
|
el.ifConditions.push(condition)
|
|
2138
2193
|
}
|
|
2139
2194
|
|
|
2195
|
+
function getIfConditions (el) {
|
|
2196
|
+
return el?.ifConditions || []
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2140
2199
|
function postProcessIfReact (el) {
|
|
2141
|
-
let prevNode
|
|
2200
|
+
let prevNode, ifNode, result, ifConditions
|
|
2142
2201
|
if (el.if) {
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2202
|
+
// 取值
|
|
2203
|
+
// false -> 节点变为temp-node,并添加_if=false
|
|
2204
|
+
// true -> 添加_if=true,移除if
|
|
2205
|
+
// dynamic -> addIfCondition
|
|
2206
|
+
result = evalExp(el.if.exp)
|
|
2207
|
+
if (result.success) {
|
|
2208
|
+
if (result.result) {
|
|
2209
|
+
el._if = true
|
|
2210
|
+
delete el.if
|
|
2211
|
+
} else {
|
|
2212
|
+
replaceNode(el, getTempNode())._if = false
|
|
2213
|
+
}
|
|
2214
|
+
} else {
|
|
2215
|
+
el._if = null
|
|
2216
|
+
addIfCondition(el, {
|
|
2217
|
+
exp: el.if.exp,
|
|
2152
2218
|
block: el
|
|
2153
2219
|
})
|
|
2154
|
-
|
|
2220
|
+
}
|
|
2221
|
+
} else if (el.elseif) {
|
|
2222
|
+
if (el.for) {
|
|
2223
|
+
error$1(`wx:elif (wx:elif="${el.elseif.raw}") invalidly used on the for-list <"${el.tag}"> which has a wx:for directive, please create a block element to wrap the for-list and move the elif-directive to it`)
|
|
2224
|
+
return
|
|
2225
|
+
}
|
|
2226
|
+
|
|
2227
|
+
ifNode = findPrevNode(el)
|
|
2228
|
+
ifConditions = getIfConditions(ifNode)
|
|
2229
|
+
prevNode = ifConditions.length > 0 ? ifConditions[ifConditions.length - 1].block : ifNode
|
|
2230
|
+
|
|
2231
|
+
if (!prevNode || prevNode._if === undefined) {
|
|
2232
|
+
error$1(`wx:elif="${el.elseif.raw}" used on element [${el.tag}] without corresponding wx:if or wx:elif.`)
|
|
2233
|
+
return
|
|
2234
|
+
}
|
|
2235
|
+
|
|
2236
|
+
if (prevNode._if === true) {
|
|
2237
|
+
removeNode(el)
|
|
2238
|
+
} else if (prevNode._if === false) {
|
|
2239
|
+
el.if = el.elseif
|
|
2240
|
+
delete el.elseif
|
|
2241
|
+
postProcessIfReact(el)
|
|
2155
2242
|
} else {
|
|
2156
|
-
|
|
2243
|
+
result = evalExp(el.elseif.exp)
|
|
2244
|
+
if (result.success) {
|
|
2245
|
+
if (result.result) {
|
|
2246
|
+
delete el.elseif
|
|
2247
|
+
el._if = true
|
|
2248
|
+
addIfCondition(ifNode, {
|
|
2249
|
+
exp: el.elseif.exp,
|
|
2250
|
+
block: el
|
|
2251
|
+
})
|
|
2252
|
+
removeNode(el, true)
|
|
2253
|
+
} else {
|
|
2254
|
+
removeNode(el)
|
|
2255
|
+
}
|
|
2256
|
+
} else {
|
|
2257
|
+
el._if = null
|
|
2258
|
+
addIfCondition(ifNode, {
|
|
2259
|
+
exp: el.elseif.exp,
|
|
2260
|
+
block: el
|
|
2261
|
+
})
|
|
2262
|
+
removeNode(el, true)
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
} else if (el.else) {
|
|
2266
|
+
if (el.for) {
|
|
2267
|
+
error$1(`wx:else invalidly used on the for-list <"${el.tag}"> which has a wx:for directive, please create a block element to wrap the for-list and move the else-directive to it`)
|
|
2268
|
+
return
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
ifNode = findPrevNode(el)
|
|
2272
|
+
ifConditions = getIfConditions(ifNode)
|
|
2273
|
+
prevNode = ifConditions.length > 0 ? ifConditions[ifConditions.length - 1].block : ifNode
|
|
2274
|
+
|
|
2275
|
+
if (!prevNode || prevNode._if === undefined) {
|
|
2276
|
+
error$1(`wx:else used on element [${el.tag}] without corresponding wx:if or wx:elif.`)
|
|
2277
|
+
return
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
if (prevNode._if === true) {
|
|
2281
|
+
removeNode(el)
|
|
2282
|
+
} else if (prevNode._if === false) {
|
|
2283
|
+
delete el.else
|
|
2284
|
+
} else {
|
|
2285
|
+
addIfCondition(ifNode, {
|
|
2286
|
+
block: el
|
|
2287
|
+
})
|
|
2288
|
+
removeNode(el, true)
|
|
2157
2289
|
}
|
|
2158
2290
|
}
|
|
2159
2291
|
}
|
|
@@ -2520,6 +2652,16 @@ function getVirtualHostRoot (options, meta) {
|
|
|
2520
2652
|
if (isWeb(mode) && ctorType === 'page') {
|
|
2521
2653
|
return createASTElement('page')
|
|
2522
2654
|
}
|
|
2655
|
+
if (isReact(mode) && ctorType === 'page') {
|
|
2656
|
+
const rootView = createASTElement('view', [
|
|
2657
|
+
{
|
|
2658
|
+
name: 'class',
|
|
2659
|
+
value: MPX_TAG_PAGE_SELECTOR
|
|
2660
|
+
}
|
|
2661
|
+
])
|
|
2662
|
+
processElement(rootView, rootView, options, meta)
|
|
2663
|
+
return rootView
|
|
2664
|
+
}
|
|
2523
2665
|
}
|
|
2524
2666
|
return getTempNode()
|
|
2525
2667
|
}
|
|
@@ -2713,6 +2855,78 @@ function processNoTransAttrs (el) {
|
|
|
2713
2855
|
}
|
|
2714
2856
|
}
|
|
2715
2857
|
|
|
2858
|
+
function initCrossPlatformConfig () {
|
|
2859
|
+
// 定义平台与前缀的双向映射关系
|
|
2860
|
+
const platformPrefixMap = {
|
|
2861
|
+
wx: 'wx:',
|
|
2862
|
+
ali: 'a:',
|
|
2863
|
+
swan: 's-',
|
|
2864
|
+
qq: 'qq:',
|
|
2865
|
+
tt: 'tt:',
|
|
2866
|
+
dd: 'dd:',
|
|
2867
|
+
jd: 'jd:',
|
|
2868
|
+
qa: 'qa:',
|
|
2869
|
+
web: 'v-'
|
|
2870
|
+
}
|
|
2871
|
+
|
|
2872
|
+
if (isNoMode(mode)) {
|
|
2873
|
+
return null
|
|
2874
|
+
}
|
|
2875
|
+
|
|
2876
|
+
return {
|
|
2877
|
+
currentPrefix: platformPrefixMap[mode] || 'wx:',
|
|
2878
|
+
platformPrefixMap
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2882
|
+
// 检测跨平台语法使用情况并给出警告
|
|
2883
|
+
function processCrossPlatformSyntaxWarning (el) {
|
|
2884
|
+
// 使用转换后的属性列表进行检查
|
|
2885
|
+
if (!el.attrsList || el.attrsList.length === 0) {
|
|
2886
|
+
return
|
|
2887
|
+
}
|
|
2888
|
+
|
|
2889
|
+
// 如果配置为空,说明不需要检测
|
|
2890
|
+
if (!crossPlatformConfig) {
|
|
2891
|
+
return
|
|
2892
|
+
}
|
|
2893
|
+
|
|
2894
|
+
const { currentPrefix, platformPrefixMap } = crossPlatformConfig
|
|
2895
|
+
|
|
2896
|
+
// 检查转换后的属性列表
|
|
2897
|
+
el.attrsList.forEach(attr => {
|
|
2898
|
+
const attrName = attr.name
|
|
2899
|
+
|
|
2900
|
+
// 检查是否使用了平台前缀
|
|
2901
|
+
for (const [platformName, prefix] of Object.entries(platformPrefixMap)) {
|
|
2902
|
+
if (attrName.startsWith(prefix)) {
|
|
2903
|
+
if (isReact(mode)) {
|
|
2904
|
+
// React Native 平台:只允许使用 wx: 前缀,其他前缀报错
|
|
2905
|
+
if (prefix !== 'wx:') {
|
|
2906
|
+
error$1(
|
|
2907
|
+
`React Native mode "${mode}" does not support "${prefix}" prefix. ` +
|
|
2908
|
+
`Use "wx:" prefix instead. Found: "${attrName}"`
|
|
2909
|
+
)
|
|
2910
|
+
}
|
|
2911
|
+
} else {
|
|
2912
|
+
// 小程序平台:检测跨平台语法使用
|
|
2913
|
+
if (platformName !== mode) {
|
|
2914
|
+
// 构建建议的正确属性名
|
|
2915
|
+
const suffixPart = attrName.substring(prefix.length)
|
|
2916
|
+
const suggestedAttr = currentPrefix + suffixPart
|
|
2917
|
+
|
|
2918
|
+
warn$1(
|
|
2919
|
+
`Your target mode is "${mode}", but used "${attrName}". ` +
|
|
2920
|
+
`Did you mean "${suggestedAttr}"?`
|
|
2921
|
+
)
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
break
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
})
|
|
2928
|
+
}
|
|
2929
|
+
|
|
2716
2930
|
function processMpxTagName (el) {
|
|
2717
2931
|
const mpxTagName = getAndRemoveAttr(el, 'mpxTagName').val
|
|
2718
2932
|
if (mpxTagName) {
|
|
@@ -2742,6 +2956,9 @@ function processElement (el, root, options, meta) {
|
|
|
2742
2956
|
|
|
2743
2957
|
processDuplicateAttrsList(el)
|
|
2744
2958
|
|
|
2959
|
+
// 检测跨平台语法使用情况并给出警告
|
|
2960
|
+
processCrossPlatformSyntaxWarning(el)
|
|
2961
|
+
|
|
2745
2962
|
processInjectWxs(el, meta, options)
|
|
2746
2963
|
|
|
2747
2964
|
const transAli = mode === 'ali' && srcMode === 'wx'
|
|
@@ -2886,7 +3103,7 @@ function cloneAttrsList (attrsList) {
|
|
|
2886
3103
|
}
|
|
2887
3104
|
|
|
2888
3105
|
function postProcessComponentIs (el, postProcessChild) {
|
|
2889
|
-
if (el.is && el.
|
|
3106
|
+
if (el.is && el.componentMap && el.componentMap.size > 0) {
|
|
2890
3107
|
let tempNode
|
|
2891
3108
|
if (el.for || el.if || el.elseif || el.else) {
|
|
2892
3109
|
tempNode = createASTElement('block')
|
|
@@ -2896,11 +3113,12 @@ function postProcessComponentIs (el, postProcessChild) {
|
|
|
2896
3113
|
replaceNode(el, tempNode, true)
|
|
2897
3114
|
postMoveBaseDirective(tempNode, el)
|
|
2898
3115
|
|
|
2899
|
-
|
|
2900
|
-
|
|
3116
|
+
// Map<CurrentName, SourceName>
|
|
3117
|
+
el.componentMap.forEach((source, name) => {
|
|
3118
|
+
const newChild = createASTElement(name, cloneAttrsList(el.attrsList), tempNode)
|
|
2901
3119
|
newChild.if = {
|
|
2902
|
-
raw: `{{${el.is} === ${stringify(
|
|
2903
|
-
exp: `${el.is} === ${stringify(
|
|
3120
|
+
raw: `{{${el.is} === ${stringify(source)}}}`,
|
|
3121
|
+
exp: `${el.is} === ${stringify(source)}`
|
|
2904
3122
|
}
|
|
2905
3123
|
el.children.forEach((child) => {
|
|
2906
3124
|
addChild(newChild, cloneNode(child))
|
|
@@ -3025,30 +3243,12 @@ function genIf (node) {
|
|
|
3025
3243
|
|
|
3026
3244
|
function genElseif (node) {
|
|
3027
3245
|
node.elseifProcessed = true
|
|
3028
|
-
if
|
|
3029
|
-
error$1(`wx:elif (wx:elif="${node.elseif.raw}") invalidly used on the for-list <"${node.tag}"> which has a wx:for directive, please create a block element to wrap the for-list and move the if-directive to it`)
|
|
3030
|
-
return
|
|
3031
|
-
}
|
|
3032
|
-
const preNode = findPrevNode(node)
|
|
3033
|
-
if (preNode && (preNode.if || preNode.elseif)) {
|
|
3034
|
-
return `else if(${node.elseif.exp}){\n${genNode(node)}}\n`
|
|
3035
|
-
} else {
|
|
3036
|
-
error$1(`wx:elif (wx:elif="${node.elseif.raw}") invalidly used on the element <"${node.tag}"> without corresponding wx:if or wx:elif.`)
|
|
3037
|
-
}
|
|
3246
|
+
return `else if(${node.elseif.exp}){\n${genNode(node)}}\n`
|
|
3038
3247
|
}
|
|
3039
3248
|
|
|
3040
3249
|
function genElse (node) {
|
|
3041
3250
|
node.elseProcessed = true
|
|
3042
|
-
|
|
3043
|
-
error$1(`wx:else invalidly used on the for-list <"${node.tag}"> which has a wx:for directive, please create a block element to wrap the for-list and move the if-directive to it`)
|
|
3044
|
-
return
|
|
3045
|
-
}
|
|
3046
|
-
const preNode = findPrevNode(node)
|
|
3047
|
-
if (preNode && (preNode.if || preNode.elseif)) {
|
|
3048
|
-
return `else{\n${genNode(node)}}\n`
|
|
3049
|
-
} else {
|
|
3050
|
-
error$1(`wx:else invalidly used on the element <"${node.tag}"> without corresponding wx:if or wx:elif.`)
|
|
3051
|
-
}
|
|
3251
|
+
return `else{\n${genNode(node)}}\n`
|
|
3052
3252
|
}
|
|
3053
3253
|
|
|
3054
3254
|
function genExps (node) {
|
|
@@ -3259,5 +3459,6 @@ module.exports = {
|
|
|
3259
3459
|
findPrevNode,
|
|
3260
3460
|
removeNode,
|
|
3261
3461
|
replaceNode,
|
|
3262
|
-
createASTElement
|
|
3462
|
+
createASTElement,
|
|
3463
|
+
evalExp
|
|
3263
3464
|
}
|
|
@@ -9,7 +9,8 @@ function genIfConditions (conditions) {
|
|
|
9
9
|
if (!conditions.length) return 'null'
|
|
10
10
|
const condition = conditions.shift()
|
|
11
11
|
if (condition.exp) {
|
|
12
|
-
|
|
12
|
+
// 此处 condition.exp 无需括号包裹,condition.exp本身已经包含括号
|
|
13
|
+
return `${condition.exp}?${genNode(condition.block)}:${genIfConditions(conditions)}`
|
|
13
14
|
} else {
|
|
14
15
|
return genNode(condition.block)
|
|
15
16
|
}
|
|
@@ -30,7 +31,7 @@ function mapAttrName (name) {
|
|
|
30
31
|
return name
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
function genNode (node) {
|
|
34
|
+
function genNode (node, isRoot = false) {
|
|
34
35
|
let exp = ''
|
|
35
36
|
if (node) {
|
|
36
37
|
if (node.type === 3) {
|
|
@@ -72,18 +73,29 @@ function genNode (node) {
|
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
if (!node.unary && node.children.length) {
|
|
75
|
-
|
|
76
|
-
exp += node.children.map((child) => {
|
|
76
|
+
const childNode = node.children.map((child) => {
|
|
77
77
|
return genNode(child)
|
|
78
78
|
}).filter(fragment => fragment).join(',')
|
|
79
|
+
|
|
80
|
+
// child可能为temp-node等无效节点,所以增加判断确保存在childNode再添加逗号
|
|
81
|
+
if (childNode) {
|
|
82
|
+
exp += ','
|
|
83
|
+
exp += childNode
|
|
84
|
+
}
|
|
79
85
|
}
|
|
80
86
|
exp += ')'
|
|
81
87
|
}
|
|
82
88
|
}
|
|
83
89
|
} else {
|
|
84
|
-
|
|
90
|
+
const nodes = node.children.map((child) => {
|
|
85
91
|
return genNode(child)
|
|
86
|
-
}).filter(fragment => fragment
|
|
92
|
+
}).filter(fragment => fragment && fragment !== 'null')
|
|
93
|
+
if (isRoot && nodes.length > 1) {
|
|
94
|
+
// 如果存在多个根节点,使用 block 包裹
|
|
95
|
+
exp = `createElement(getComponent("block"), null, ${nodes.join(',')})`
|
|
96
|
+
} else {
|
|
97
|
+
exp += nodes.join(',')
|
|
98
|
+
}
|
|
87
99
|
}
|
|
88
100
|
}
|
|
89
101
|
}
|
|
@@ -24,14 +24,15 @@ module.exports = function (raw) {
|
|
|
24
24
|
const packageName = queryObj.packageRoot || mpx.currentPackageRoot || 'main'
|
|
25
25
|
const wxsContentMap = mpx.wxsContentMap
|
|
26
26
|
const optimizeRenderRules = mpx.optimizeRenderRules
|
|
27
|
-
const usingComponentsInfo = queryObj.usingComponentsInfo
|
|
27
|
+
const usingComponentsInfo = queryObj.usingComponentsInfo ? JSON.parse(queryObj.usingComponentsInfo) : {}
|
|
28
|
+
const originalUsingComponents = queryObj.originalUsingComponents ? JSON.parse(queryObj.originalUsingComponents) : []
|
|
28
29
|
const componentPlaceholder = queryObj.componentPlaceholder || []
|
|
29
30
|
const hasComment = queryObj.hasComment
|
|
30
31
|
const isNative = queryObj.isNative
|
|
31
32
|
const ctorType = queryObj.ctorType
|
|
32
33
|
const hasScoped = queryObj.hasScoped
|
|
33
34
|
const runtimeCompile = queryObj.isDynamic
|
|
34
|
-
const moduleId = queryObj.moduleId || mpx.getModuleId(resourcePath)
|
|
35
|
+
const moduleId = queryObj.moduleId || mpx.getModuleId(resourcePath, false, queryObj.moduleId ? null : this)
|
|
35
36
|
|
|
36
37
|
let optimizeRenderLevel = 0
|
|
37
38
|
for (const rule of optimizeRenderRules) {
|
|
@@ -43,13 +44,13 @@ module.exports = function (raw) {
|
|
|
43
44
|
|
|
44
45
|
const warn = (msg) => {
|
|
45
46
|
this.emitWarning(
|
|
46
|
-
new Error('[template
|
|
47
|
+
new Error('[Mpx template warning][' + this.resource + ']: ' + msg)
|
|
47
48
|
)
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
const error = (msg) => {
|
|
51
52
|
this.emitError(
|
|
52
|
-
new Error('[template
|
|
53
|
+
new Error('[Mpx template error][' + this.resource + ']: ' + msg)
|
|
53
54
|
)
|
|
54
55
|
}
|
|
55
56
|
|
|
@@ -70,6 +71,7 @@ module.exports = function (raw) {
|
|
|
70
71
|
hasScoped,
|
|
71
72
|
moduleId,
|
|
72
73
|
usingComponentsInfo,
|
|
74
|
+
originalUsingComponents,
|
|
73
75
|
// 这里需传递rawResourcePath和wxsContentMap保持一致
|
|
74
76
|
filePath: rawResourcePath,
|
|
75
77
|
i18n,
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 链式合并方法的工具函数
|
|
3
|
+
*
|
|
4
|
+
* 在多条件分支下使用 Object.assign 会导致同名方法被覆盖,
|
|
5
|
+
* 这个函数通过创建组合函数来确保所有方法都能按顺序执行。
|
|
6
|
+
*
|
|
7
|
+
* @param {Object} target - 目标 visitor 对象
|
|
8
|
+
* @param {Object} source - 要链式分配的 visitor 方法对象
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const visitor = {}
|
|
12
|
+
*
|
|
13
|
+
* // 第一次合并
|
|
14
|
+
* chainAssign(visitor, {
|
|
15
|
+
* CallExpression(path) {
|
|
16
|
+
* console.log('第一个处理器')
|
|
17
|
+
* }
|
|
18
|
+
* })
|
|
19
|
+
*
|
|
20
|
+
* // 第二次合并 - 不会覆盖,而是组合执行
|
|
21
|
+
* chainAssign(visitor, {
|
|
22
|
+
* CallExpression(path) {
|
|
23
|
+
* console.log('第二个处理器')
|
|
24
|
+
* }
|
|
25
|
+
* })
|
|
26
|
+
*
|
|
27
|
+
* // 执行时会依次输出:
|
|
28
|
+
* // 第一个处理器
|
|
29
|
+
* // 第二个处理器
|
|
30
|
+
*/
|
|
31
|
+
module.exports = function chainAssign (target, source) {
|
|
32
|
+
for (const [key, value] of Object.entries(source)) {
|
|
33
|
+
if (target[key]) {
|
|
34
|
+
// 如果已存在同名方法,创建组合函数依次执行
|
|
35
|
+
const originalMethod = target[key]
|
|
36
|
+
target[key] = function (path) {
|
|
37
|
+
originalMethod.call(this, path)
|
|
38
|
+
// 只有当节点没有停止遍历或被移除时才继续执行
|
|
39
|
+
if (!path.removed && !path.shouldStop) {
|
|
40
|
+
value.call(this, path)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
target[key] = value
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|