@mpxjs/webpack-plugin 2.10.19 → 2.10.20
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/ResolveDependency.js +2 -2
- package/lib/index.js +25 -6
- package/lib/json-compiler/helper.js +11 -10
- package/lib/json-compiler/index.js +7 -4
- package/lib/json-compiler/plugin.js +4 -4
- package/lib/loader.js +4 -4
- package/lib/native-loader.js +4 -4
- package/lib/platform/create-diagnostic.js +168 -0
- package/lib/platform/index.js +16 -3
- package/lib/platform/json/wx/index.js +66 -17
- package/lib/platform/run-rules.js +9 -5
- package/lib/platform/style/wx/index.js +4 -3
- package/lib/platform/template/normalize-component-rules.js +7 -9
- package/lib/platform/template/wx/component-config/custom-built-in-component.js +34 -0
- package/lib/platform/template/wx/component-config/index.js +18 -3
- package/lib/platform/template/wx/component-config/input.js +1 -7
- package/lib/platform/template/wx/component-config/movable-view.js +1 -7
- package/lib/platform/template/wx/component-config/text.js +1 -1
- package/lib/platform/template/wx/component-config/textarea.js +1 -25
- package/lib/platform/template/wx/index.js +48 -34
- package/lib/react/processJSON.js +7 -4
- package/lib/react/processStyles.js +22 -8
- package/lib/react/processTemplate.js +85 -41
- package/lib/react/style-helper.js +120 -85
- package/lib/react/template-loader.js +148 -0
- package/lib/runtime/components/react/dist/mpx-async-suspense.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-image.d.ts +0 -1
- package/lib/runtime/components/react/dist/mpx-image.jsx +1 -2
- package/lib/runtime/components/react/dist/mpx-picker/type.d.ts +1 -1
- package/lib/runtime/components/react/dist/utils.jsx +3 -2
- package/lib/runtime/components/react/mpx-async-suspense.tsx +2 -1
- package/lib/runtime/components/react/mpx-image.tsx +1 -3
- package/lib/runtime/components/react/mpx-picker/type.ts +1 -1
- package/lib/runtime/components/react/utils.tsx +3 -2
- package/lib/runtime/components/wx/default-component.mpx +9 -0
- package/lib/runtime/components/wx/default-page.mpx +3 -11
- package/lib/runtime/optionProcessor.d.ts +2 -0
- package/lib/runtime/optionProcessor.js +77 -1
- package/lib/style-compiler/index.js +2 -0
- package/lib/style-compiler/plugins/remove-strip-conditional-comments.js +14 -0
- package/lib/style-compiler/strip-conditional.js +40 -26
- package/lib/template-compiler/compiler.js +274 -116
- package/lib/template-compiler/gen-node-react.js +35 -7
- package/lib/template-compiler/index.js +9 -7
- package/lib/utils/const.js +4 -1
- package/lib/utils/partial-compile-rules.js +27 -0
- package/lib/utils/pre-process-json.js +3 -0
- package/lib/utils/source-location.js +96 -0
- package/lib/web/compile-wx-template-fragment.js +68 -0
- package/lib/web/index.js +2 -0
- package/lib/web/processJSON.js +7 -4
- package/lib/web/processScript.js +41 -3
- package/lib/web/processTemplate.js +61 -19
- package/lib/web/template-loader.js +123 -0
- package/lib/web/template-shared.js +48 -0
- package/lib/wxml/loader.js +3 -2
- package/lib/wxss/loader.js +1 -1
- package/lib/wxss/utils.js +6 -4
- package/package.json +11 -4
- package/lib/platform/template/wx/component-config/component.js +0 -41
|
@@ -1,16 +1,35 @@
|
|
|
1
|
-
const
|
|
1
|
+
const normalize = require('../utils/normalize')
|
|
2
2
|
const parseRequest = require('../utils/parse-request')
|
|
3
3
|
const { matchCondition } = require('../utils/match-condition')
|
|
4
4
|
const loaderUtils = require('loader-utils')
|
|
5
5
|
const templateCompiler = require('../template-compiler/compiler')
|
|
6
|
-
const genNode = require('../template-compiler/gen-node-react')
|
|
6
|
+
const { genNode, genTemplate } = require('../template-compiler/gen-node-react')
|
|
7
7
|
const bindThis = require('../template-compiler/bind-this')
|
|
8
8
|
const isEmptyObject = require('../utils/is-empty-object')
|
|
9
9
|
const dash2hump = require('../utils/hump-dash').dash2hump
|
|
10
|
+
const addQuery = require('../utils/add-query')
|
|
11
|
+
|
|
12
|
+
function transformCode (code, wxsModuleMap, error) {
|
|
13
|
+
try {
|
|
14
|
+
const ignoreMap = Object.assign({
|
|
15
|
+
createElement: true,
|
|
16
|
+
getComponent: true,
|
|
17
|
+
getTemplate: true
|
|
18
|
+
}, wxsModuleMap)
|
|
19
|
+
|
|
20
|
+
const bindResult = bindThis.transform(code, {
|
|
21
|
+
ignoreMap
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
return bindResult.code
|
|
25
|
+
} catch (e) {
|
|
26
|
+
error(`[Mpx template error]: Invalid render function generated by the template, please check!\n Error code:\n ${code}\n Error Detail:\n ${e.stack}`)
|
|
27
|
+
return null
|
|
28
|
+
}
|
|
29
|
+
}
|
|
10
30
|
|
|
11
31
|
module.exports = function (template, {
|
|
12
32
|
loaderContext,
|
|
13
|
-
// hasScoped,
|
|
14
33
|
hasComment,
|
|
15
34
|
isNative,
|
|
16
35
|
srcMode,
|
|
@@ -29,10 +48,12 @@ module.exports = function (template, {
|
|
|
29
48
|
wxsContentMap,
|
|
30
49
|
decodeHTMLText,
|
|
31
50
|
externalClasses,
|
|
32
|
-
checkUsingComponents,
|
|
33
51
|
autoVirtualHostRules,
|
|
34
52
|
forceProxyEventRules,
|
|
35
|
-
|
|
53
|
+
checkUsingComponentsRules,
|
|
54
|
+
globalComponents,
|
|
55
|
+
customTextRules,
|
|
56
|
+
rnConfig
|
|
36
57
|
} = mpx
|
|
37
58
|
const { resourcePath, rawResourcePath } = parseRequest(loaderContext.resource)
|
|
38
59
|
const builtInComponentsMap = {}
|
|
@@ -55,20 +76,20 @@ module.exports = function (template, {
|
|
|
55
76
|
|
|
56
77
|
if (template.content) {
|
|
57
78
|
const templateSrcMode = template.mode || srcMode
|
|
58
|
-
const warn = (msg) => {
|
|
79
|
+
const warn = (msg, loc) => {
|
|
59
80
|
loaderContext.emitWarning(
|
|
60
|
-
new Error('[Mpx template warning][' + loaderContext.
|
|
81
|
+
new Error('[Mpx template warning][' + (loc || loaderContext.resourcePath) + ']: ' + msg)
|
|
61
82
|
)
|
|
62
83
|
}
|
|
63
|
-
const error = (msg) => {
|
|
84
|
+
const error = (msg, loc) => {
|
|
64
85
|
loaderContext.emitError(
|
|
65
|
-
new Error('[
|
|
86
|
+
new Error('[Mpx template error][' + (loc || loaderContext.resourcePath) + ']: ' + msg)
|
|
66
87
|
)
|
|
67
88
|
}
|
|
68
|
-
const
|
|
89
|
+
const parseOptions = {
|
|
69
90
|
warn,
|
|
70
91
|
error,
|
|
71
|
-
usingComponentsInfo,
|
|
92
|
+
usingComponentsInfo,
|
|
72
93
|
originalUsingComponents,
|
|
73
94
|
hasComment,
|
|
74
95
|
isNative,
|
|
@@ -84,59 +105,82 @@ module.exports = function (template, {
|
|
|
84
105
|
filePath: rawResourcePath,
|
|
85
106
|
// react中模版i18n不需要特殊处理
|
|
86
107
|
i18n: null,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
globalComponents: [],
|
|
108
|
+
// 与 template-compiler/index 一致:usingComponentsInfo 已合并 globalComponentsInfo,此处白名单避免对仅 app 注册的组件误报「未使用」
|
|
109
|
+
globalComponents: Object.keys(globalComponents || {}),
|
|
90
110
|
// rn模式下实现抽象组件
|
|
91
111
|
componentGenerics,
|
|
92
112
|
hasVirtualHost: matchCondition(resourcePath, autoVirtualHostRules),
|
|
93
113
|
forceProxyEvent: matchCondition(resourcePath, forceProxyEventRules),
|
|
94
|
-
|
|
95
|
-
|
|
114
|
+
checkUsingComponents: matchCondition(resourcePath, checkUsingComponentsRules),
|
|
115
|
+
isCustomText: matchCondition(resourcePath, customTextRules),
|
|
116
|
+
customBuiltInComponents: rnConfig && rnConfig.customBuiltInComponents
|
|
117
|
+
}
|
|
118
|
+
const { root, meta } = templateCompiler.parse(template.content, parseOptions)
|
|
96
119
|
|
|
97
120
|
if (meta.wxsContentMap) {
|
|
98
121
|
for (const module in meta.wxsContentMap) {
|
|
99
122
|
wxsContentMap[`${rawResourcePath}~${module}`] = meta.wxsContentMap[module]
|
|
100
123
|
}
|
|
101
124
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
125
|
+
|
|
126
|
+
const templates = []
|
|
127
|
+
if (meta.imports) {
|
|
128
|
+
const reactTemplateLoaderPath = normalize.lib('react/template-loader')
|
|
129
|
+
meta.imports.forEach((importSrc) => {
|
|
130
|
+
const request = loaderUtils.urlToRequest(importSrc, projectRoot)
|
|
131
|
+
templates.push(`require(${loaderUtils.stringifyRequest(loaderContext, `!!${reactTemplateLoaderPath}!${request}`)})`)
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (meta.templates) {
|
|
136
|
+
let localTemplatesCode = 'var localTemplates = {\n'
|
|
137
|
+
Object.keys(meta.templates).forEach((name) => {
|
|
138
|
+
const template = meta.templates[name]
|
|
139
|
+
const templateCode = genTemplate(template)
|
|
140
|
+
if (templateCode) {
|
|
141
|
+
localTemplatesCode += `${JSON.stringify(name)}: ${templateCode},\n`
|
|
106
142
|
}
|
|
107
143
|
})
|
|
144
|
+
localTemplatesCode += '};'
|
|
145
|
+
const transformedCode = transformCode(localTemplatesCode, meta.wxsModuleMap, error)
|
|
146
|
+
if (transformedCode) {
|
|
147
|
+
output += transformedCode + '\n'
|
|
148
|
+
templates.push('localTemplates')
|
|
149
|
+
}
|
|
108
150
|
}
|
|
151
|
+
|
|
152
|
+
const builtInPaths = meta.builtInComponentsMap || {}
|
|
153
|
+
Object.keys(builtInPaths).forEach((name) => {
|
|
154
|
+
builtInComponentsMap[name] = {
|
|
155
|
+
resource: addQuery(builtInPaths[name], { isComponent: true })
|
|
156
|
+
}
|
|
157
|
+
})
|
|
109
158
|
if (meta.genericsInfo) {
|
|
110
159
|
genericsInfo = meta.genericsInfo
|
|
111
160
|
}
|
|
112
161
|
|
|
113
162
|
for (const module in meta.wxsModuleMap) {
|
|
114
163
|
const src = loaderUtils.urlToRequest(meta.wxsModuleMap[module], projectRoot)
|
|
115
|
-
output += `var ${module} = require(${loaderUtils.stringifyRequest(
|
|
164
|
+
output += `var ${module} = require(${loaderUtils.stringifyRequest(loaderContext, src)});\n`
|
|
116
165
|
}
|
|
117
166
|
|
|
167
|
+
const templateHelpersCode = templates.length
|
|
168
|
+
? `var templates = Object.assign({}, ${templates.join(', ')});
|
|
169
|
+
function getTemplate(name) {
|
|
170
|
+
return templates[name] || function(){};
|
|
171
|
+
}
|
|
172
|
+
`
|
|
173
|
+
: ''
|
|
174
|
+
output += templateHelpersCode
|
|
175
|
+
|
|
118
176
|
const rawCode = genNode(root, true)
|
|
119
177
|
if (rawCode) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
createElement: true,
|
|
123
|
-
getComponent: true
|
|
124
|
-
}, meta.wxsModuleMap)
|
|
125
|
-
const bindResult = bindThis.transform(rawCode, {
|
|
126
|
-
ignoreMap
|
|
127
|
-
// customBindThis (path, t) {
|
|
128
|
-
// path.replaceWith(t.callExpression(t.identifier('getValue'), [t.stringLiteral(path.node.name)]))
|
|
129
|
-
// }
|
|
130
|
-
})
|
|
178
|
+
const transformedCode = transformCode(rawCode, meta.wxsModuleMap, error)
|
|
179
|
+
if (transformedCode) {
|
|
131
180
|
output += `global.currentInject.render = function (createElement, getComponent) {
|
|
132
|
-
return ${
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
error(`[Mpx template error]: Invalid render function generated by the template, please check!
|
|
136
|
-
Error code:
|
|
137
|
-
${rawCode}
|
|
138
|
-
Error Detail:
|
|
139
|
-
${e.stack}`)
|
|
181
|
+
return ${transformedCode}
|
|
182
|
+
};
|
|
183
|
+
`
|
|
140
184
|
}
|
|
141
185
|
}
|
|
142
186
|
|
|
@@ -160,7 +204,7 @@ ${e.stack}`)
|
|
|
160
204
|
if (defaultValue) {
|
|
161
205
|
output += ` generic${dash2hump(genericName)}: { type: String, value: '${genericName}default' },\n`
|
|
162
206
|
} else {
|
|
163
|
-
|
|
207
|
+
output += ` generic${dash2hump(genericName)}: String,\n`
|
|
164
208
|
}
|
|
165
209
|
})
|
|
166
210
|
output += '}\n'
|
|
@@ -2,20 +2,24 @@ const postcss = require('postcss')
|
|
|
2
2
|
const selectorParser = require('postcss-selector-parser')
|
|
3
3
|
const { MPX_TAG_PAGE_SELECTOR } = require('../utils/const')
|
|
4
4
|
const getRulesRunner = require('../platform/index')
|
|
5
|
+
const createDiagnostic = require('../platform/create-diagnostic')
|
|
5
6
|
const dash2hump = require('../utils/hump-dash').dash2hump
|
|
6
7
|
const parseValues = require('../utils/string').parseValues
|
|
7
8
|
const unitRegExp = /^\s*(-?\d+(?:\.\d+)?)(rpx|vw|vh|px)?\s*$/
|
|
8
9
|
const hairlineRegExp = /^\s*hairlineWidth\s*$/
|
|
9
10
|
const varRegExp = /^--/
|
|
10
11
|
const cssPrefixExp = /^-(webkit|moz|ms|o)-/
|
|
11
|
-
function getClassMap ({ content, filename, mode, srcMode, ctorType, formatValueName, warn, error }) {
|
|
12
|
+
function getClassMap ({ content, styles, filename, inputFileSystem, mode, srcMode, ctorType, formatValueName, warn, error }) {
|
|
12
13
|
const classMap = ctorType === 'page'
|
|
13
14
|
? { [MPX_TAG_PAGE_SELECTOR]: { flex: 1, height: "'100%'" } }
|
|
14
15
|
: {}
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
styles = styles && styles.length
|
|
18
|
+
? styles
|
|
19
|
+
: [{
|
|
20
|
+
content,
|
|
21
|
+
filename
|
|
22
|
+
}]
|
|
19
23
|
|
|
20
24
|
function formatValue (value) {
|
|
21
25
|
let needStringify = true
|
|
@@ -67,99 +71,130 @@ function getClassMap ({ content, filename, mode, srcMode, ctorType, formatValueN
|
|
|
67
71
|
}, {})
|
|
68
72
|
}
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
root.walkAtRules(rule => {
|
|
81
|
-
if (rule.name !== 'media') {
|
|
82
|
-
warn(`Only @media rule is supported in react native mode temporarily, but got @${rule.name}`)
|
|
83
|
-
// 删除不支持的 AtRule,防止其影响后续解析
|
|
84
|
-
rule.remove()
|
|
74
|
+
styles.forEach((style) => {
|
|
75
|
+
const styleContent = style.content || ''
|
|
76
|
+
if (!styleContent.trim()) return
|
|
77
|
+
const styleFilename = style.filename || filename
|
|
78
|
+
const sourceMap = style.map
|
|
79
|
+
const diagnostic = {
|
|
80
|
+
file: styleFilename,
|
|
81
|
+
source: styleContent,
|
|
82
|
+
sourceMap,
|
|
83
|
+
inputFileSystem
|
|
85
84
|
}
|
|
86
|
-
|
|
85
|
+
const reporter = createDiagnostic({
|
|
86
|
+
type: 'style',
|
|
87
|
+
mode,
|
|
88
|
+
srcMode,
|
|
89
|
+
warn,
|
|
90
|
+
error,
|
|
91
|
+
diagnostic
|
|
92
|
+
})
|
|
93
|
+
const root = postcss.parse(styleContent, {
|
|
94
|
+
from: styleFilename
|
|
95
|
+
})
|
|
96
|
+
const rulesRunner = getRulesRunner({
|
|
97
|
+
mode,
|
|
98
|
+
srcMode,
|
|
99
|
+
type: 'style',
|
|
100
|
+
testKey: 'prop',
|
|
101
|
+
warn,
|
|
102
|
+
error,
|
|
103
|
+
diagnostic
|
|
104
|
+
})
|
|
87
105
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
prop = varRegExp.test(item.prop) ? item.prop : dash2hump(item.prop)
|
|
99
|
-
value = item.value
|
|
100
|
-
if (Array.isArray(value)) {
|
|
101
|
-
value = value.map(val => {
|
|
102
|
-
if (typeof val === 'object') {
|
|
103
|
-
for (const key in val) {
|
|
104
|
-
val[key] = formatValue(val[key])
|
|
105
|
-
}
|
|
106
|
-
return val
|
|
107
|
-
} else {
|
|
108
|
-
return formatValue(val)
|
|
109
|
-
}
|
|
110
|
-
})
|
|
111
|
-
} else if (typeof value === 'object') {
|
|
112
|
-
for (const key in value) {
|
|
113
|
-
value[key] = formatValue(value[key])
|
|
106
|
+
// 目前所有 AtRule 只支持 @media,其他全部给出错误提示
|
|
107
|
+
root.walkAtRules(rule => {
|
|
108
|
+
if (rule.name !== 'media') {
|
|
109
|
+
reporter.warn(`Only @media rule is supported in react native mode temporarily, but got @${rule.name}`, {
|
|
110
|
+
node: rule,
|
|
111
|
+
sourceMap,
|
|
112
|
+
target: {
|
|
113
|
+
kind: 'css-atrule',
|
|
114
|
+
name: rule.name,
|
|
115
|
+
params: rule.params
|
|
114
116
|
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
})
|
|
117
|
+
})
|
|
118
|
+
// 删除不支持的 AtRule,防止其影响后续解析
|
|
119
|
+
rule.remove()
|
|
120
|
+
}
|
|
120
121
|
})
|
|
121
122
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
root.walkRules(rule => {
|
|
124
|
+
const classMapValue = {}
|
|
125
|
+
rule.walkDecls((decl) => {
|
|
126
|
+
let { prop, value } = decl
|
|
127
|
+
if (value === 'undefined' || cssPrefixExp.test(prop) || cssPrefixExp.test(value)) return
|
|
128
|
+
let newData = rulesRunner && rulesRunner({ prop, value, selector: rule.selector, decl, rule, sourceMap })
|
|
129
|
+
if (!newData) return
|
|
130
|
+
if (!Array.isArray(newData)) {
|
|
131
|
+
newData = [newData]
|
|
131
132
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
options,
|
|
146
|
-
value: classMapValue
|
|
133
|
+
newData.forEach(item => {
|
|
134
|
+
prop = varRegExp.test(item.prop) ? item.prop : dash2hump(item.prop)
|
|
135
|
+
value = item.value
|
|
136
|
+
if (Array.isArray(value)) {
|
|
137
|
+
value = value.map(val => {
|
|
138
|
+
if (typeof val === 'object') {
|
|
139
|
+
for (const key in val) {
|
|
140
|
+
val[key] = formatValue(val[key])
|
|
141
|
+
}
|
|
142
|
+
return val
|
|
143
|
+
} else {
|
|
144
|
+
return formatValue(val)
|
|
145
|
+
}
|
|
147
146
|
})
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
147
|
+
} else if (typeof value === 'object') {
|
|
148
|
+
for (const key in value) {
|
|
149
|
+
value[key] = formatValue(value[key])
|
|
151
150
|
}
|
|
152
|
-
} else if (_default) {
|
|
153
|
-
// 已有媒体查询数据,此次非媒体查询
|
|
154
|
-
Object.assign(_default, classMapValue)
|
|
155
151
|
} else {
|
|
156
|
-
|
|
152
|
+
value = formatValue(value)
|
|
153
|
+
}
|
|
154
|
+
classMapValue[prop] = value
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
const classMapKeys = []
|
|
159
|
+
const options = getMediaOptions(rule.parent.params || '')
|
|
160
|
+
const isMedia = options.maxWidth || options.minWidth
|
|
161
|
+
selectorParser(selectors => {
|
|
162
|
+
selectors.each(selector => {
|
|
163
|
+
if (selector.nodes.length === 1 && selector.nodes[0].type === 'class') {
|
|
164
|
+
classMapKeys.push(selector.nodes[0].value)
|
|
165
|
+
} else {
|
|
166
|
+
reporter.error('Only single class selector is supported in react native mode temporarily.', {
|
|
167
|
+
node: rule,
|
|
168
|
+
sourceMap,
|
|
169
|
+
target: {
|
|
170
|
+
kind: 'selector',
|
|
171
|
+
value: rule.selector
|
|
172
|
+
}
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
}).processSync(rule.selector)
|
|
177
|
+
|
|
178
|
+
if (classMapKeys.length) {
|
|
179
|
+
classMapKeys.forEach((key) => {
|
|
180
|
+
if (Object.keys(classMapValue).length) {
|
|
181
|
+
// set css defalut value
|
|
157
182
|
const val = classMap[key] || {}
|
|
158
183
|
classMap[key] = Object.assign(val, classMapValue)
|
|
184
|
+
|
|
185
|
+
// set css media
|
|
186
|
+
if (isMedia) {
|
|
187
|
+
const _media = classMap[key]?._media || []
|
|
188
|
+
_media.push({
|
|
189
|
+
options,
|
|
190
|
+
value: classMapValue
|
|
191
|
+
})
|
|
192
|
+
classMap[key]._media = _media
|
|
193
|
+
}
|
|
159
194
|
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
})
|
|
163
198
|
})
|
|
164
199
|
return classMap
|
|
165
200
|
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
const loaderUtils = require('loader-utils')
|
|
2
|
+
const addQuery = require('../utils/add-query')
|
|
3
|
+
const normalize = require('../utils/normalize')
|
|
4
|
+
const parseRequest = require('../utils/parse-request')
|
|
5
|
+
const { matchCondition } = require('../utils/match-condition')
|
|
6
|
+
const templateCompiler = require('../template-compiler/compiler')
|
|
7
|
+
const { genTemplate } = require('../template-compiler/gen-node-react')
|
|
8
|
+
const bindThis = require('../template-compiler/bind-this')
|
|
9
|
+
|
|
10
|
+
module.exports = function (content) {
|
|
11
|
+
const loaderContext = this
|
|
12
|
+
const mpx = loaderContext.getMpx()
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
projectRoot,
|
|
16
|
+
mode,
|
|
17
|
+
srcMode,
|
|
18
|
+
env,
|
|
19
|
+
defs,
|
|
20
|
+
wxsContentMap,
|
|
21
|
+
decodeHTMLText,
|
|
22
|
+
externalClasses,
|
|
23
|
+
forceProxyEventRules,
|
|
24
|
+
getModuleId,
|
|
25
|
+
rnConfig
|
|
26
|
+
} = mpx
|
|
27
|
+
|
|
28
|
+
const { resourcePath, rawResourcePath, queryObj } = parseRequest(loaderContext.resource)
|
|
29
|
+
const moduleId = getModuleId(resourcePath)
|
|
30
|
+
|
|
31
|
+
const warn = (msg, loc) => {
|
|
32
|
+
loaderContext.emitWarning(
|
|
33
|
+
new Error('[Mpx template warning][' + (loc || loaderContext.resourcePath) + ']: ' + msg)
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
const error = (msg, loc) => {
|
|
37
|
+
loaderContext.emitError(
|
|
38
|
+
new Error('[Mpx template error][' + (loc || loaderContext.resourcePath) + ']: ' + msg)
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
const parseOptions = {
|
|
42
|
+
warn,
|
|
43
|
+
error,
|
|
44
|
+
mode,
|
|
45
|
+
srcMode: queryObj.srcMode || srcMode,
|
|
46
|
+
env,
|
|
47
|
+
defs,
|
|
48
|
+
decodeHTMLText,
|
|
49
|
+
externalClasses,
|
|
50
|
+
moduleId,
|
|
51
|
+
filePath: rawResourcePath,
|
|
52
|
+
forceProxyEvent: matchCondition(resourcePath, forceProxyEventRules),
|
|
53
|
+
customBuiltInComponents: rnConfig && rnConfig.customBuiltInComponents
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Parse the template
|
|
57
|
+
const { meta } = templateCompiler.parse(content, parseOptions)
|
|
58
|
+
if (meta.wxsContentMap && wxsContentMap) {
|
|
59
|
+
for (const module in meta.wxsContentMap) {
|
|
60
|
+
wxsContentMap[`${rawResourcePath}~${module}`] = meta.wxsContentMap[module]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Generate imports
|
|
65
|
+
const imports = []
|
|
66
|
+
if (meta.imports) {
|
|
67
|
+
const reactTemplateLoaderPath = normalize.lib('react/template-loader')
|
|
68
|
+
meta.imports.forEach((importSrc) => {
|
|
69
|
+
const request = loaderUtils.urlToRequest(importSrc, projectRoot)
|
|
70
|
+
imports.push(`require(${loaderUtils.stringifyRequest(loaderContext, `!!${reactTemplateLoaderPath}!${request}`)})`)
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const builtInPaths = meta.builtInComponentsMap || {}
|
|
75
|
+
const builtInComponents = []
|
|
76
|
+
Object.keys(builtInPaths).forEach((componentName) => {
|
|
77
|
+
const componentRequest = loaderUtils.stringifyRequest(loaderContext, addQuery(builtInPaths[componentName], { isComponent: true }))
|
|
78
|
+
builtInComponents.push(`"${componentName}": function () { return getBuiltInBaseComponent(require(${componentRequest}), { __mpxBuiltIn: true }) }`)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
// Generate local templates
|
|
82
|
+
let localTemplatesCode = 'var localTemplates = {\n'
|
|
83
|
+
if (meta.templates) {
|
|
84
|
+
Object.keys(meta.templates).forEach((name) => {
|
|
85
|
+
const template = meta.templates[name]
|
|
86
|
+
const templateCode = genTemplate(template)
|
|
87
|
+
if (templateCode) {
|
|
88
|
+
localTemplatesCode += `${JSON.stringify(name)}: ${templateCode},\n`
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
localTemplatesCode += '};'
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
const ignoreMap = Object.assign({
|
|
96
|
+
createElement: true,
|
|
97
|
+
getComponent: true,
|
|
98
|
+
getTemplate: true
|
|
99
|
+
}, meta.wxsModuleMap)
|
|
100
|
+
const bindResult = bindThis.transform(localTemplatesCode, {
|
|
101
|
+
ignoreMap
|
|
102
|
+
})
|
|
103
|
+
localTemplatesCode = bindResult.code
|
|
104
|
+
} catch (e) {
|
|
105
|
+
loaderContext.emitError(
|
|
106
|
+
new Error(`[Mpx template error]: Invalid render function generated by the template, please check!\\n Error code:\\n ${localTemplatesCode}\\n Error Detail:\\n ${e.stack}`)
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
let wxsImports = ''
|
|
111
|
+
for (const module in meta.wxsModuleMap) {
|
|
112
|
+
const request = loaderUtils.urlToRequest(meta.wxsModuleMap[module], projectRoot)
|
|
113
|
+
wxsImports += `var ${module} = require(${loaderUtils.stringifyRequest(loaderContext, request)});\n`
|
|
114
|
+
}
|
|
115
|
+
const hasTemplateSource = imports.length || (meta.templates && Object.keys(meta.templates).length)
|
|
116
|
+
const templateHelpersCode = hasTemplateSource
|
|
117
|
+
? `var templates = Object.assign({}, ${imports.join(', ') || '{}'});
|
|
118
|
+
Object.assign(templates, localTemplates);
|
|
119
|
+
function getTemplate(name) {
|
|
120
|
+
return templates[name] || function(){};
|
|
121
|
+
}`
|
|
122
|
+
: ''
|
|
123
|
+
|
|
124
|
+
const output = `
|
|
125
|
+
${wxsImports}
|
|
126
|
+
var getBuiltInBaseComponent = require(${loaderUtils.stringifyRequest(loaderContext, normalize.lib('runtime/optionProcessorReact'))}).getComponent;
|
|
127
|
+
var builtInComponentsMap = {${builtInComponents.join(',')}};
|
|
128
|
+
${localTemplatesCode}
|
|
129
|
+
${templateHelpersCode}
|
|
130
|
+
function getBuiltInComponent(name) {
|
|
131
|
+
var getter = builtInComponentsMap[name];
|
|
132
|
+
return getter && getter();
|
|
133
|
+
}
|
|
134
|
+
function getTemplateComponent(name, getComponent) {
|
|
135
|
+
return getComponent(name) || getBuiltInComponent(name);
|
|
136
|
+
}
|
|
137
|
+
Object.keys(localTemplates).forEach(function (name) {
|
|
138
|
+
var template = localTemplates[name];
|
|
139
|
+
localTemplates[name] = function (createElement, getComponent) {
|
|
140
|
+
return template.call(this, createElement, function (componentName) {
|
|
141
|
+
return getTemplateComponent(componentName, getComponent);
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
});
|
|
145
|
+
module.exports = localTemplates;
|
|
146
|
+
`
|
|
147
|
+
return output
|
|
148
|
+
}
|
|
@@ -124,7 +124,7 @@ const AsyncSuspense = ({ type, chunkName, moduleId, innerProps, getLoading, getF
|
|
|
124
124
|
else if (status === 'error') {
|
|
125
125
|
if (type === 'page') {
|
|
126
126
|
const fallback = getFallback ? getFallback() : DefaultFallback;
|
|
127
|
-
return createElement(fallback, { onReload: reloadPage });
|
|
127
|
+
return createElement(fallback, { onReload: reloadPage, bindreload: reloadPage });
|
|
128
128
|
}
|
|
129
129
|
else {
|
|
130
130
|
return getFallback ? createElement(getFallback(), innerProps) : null;
|
|
@@ -310,8 +310,7 @@ const Image = forwardRef((props, ref) => {
|
|
|
310
310
|
style: extendObject({}, normalStyle, layoutStyle, isHeightFixMode ? { width: viewWidth } : {}, isWidthFixMode ? { height: viewHeight } : {})
|
|
311
311
|
}), [
|
|
312
312
|
'src',
|
|
313
|
-
'mode'
|
|
314
|
-
'svg'
|
|
313
|
+
'mode'
|
|
315
314
|
], {
|
|
316
315
|
layoutRef
|
|
317
316
|
});
|
|
@@ -71,7 +71,7 @@ export interface RegionProps extends BasePickerProps {
|
|
|
71
71
|
/** 表示选中的省市区,默认选中每一列的第一个值, 默认值 [] */
|
|
72
72
|
value?: string[];
|
|
73
73
|
/** 默认值 region */
|
|
74
|
-
level?: 'province' | 'city' | 'region'
|
|
74
|
+
level?: 'province' | 'city' | 'region';
|
|
75
75
|
/** 可为每一列的顶部添加一个自定义的项 */
|
|
76
76
|
'custom-item'?: string;
|
|
77
77
|
/** value 改变时触发 change 事件, event.detail = {value, code, postcode},
|
|
@@ -284,8 +284,9 @@ export function parseValues(str, char = ' ') {
|
|
|
284
284
|
// parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
|
|
285
285
|
function parseTransform(transformStr) {
|
|
286
286
|
const values = parseValues(transformStr);
|
|
287
|
-
// Todo
|
|
288
|
-
|
|
287
|
+
// Todo 2 RN下顺序不一致转换结果不一致,故这里不处理,动画前后transform 排序不一致的问题,由业务调整写法
|
|
288
|
+
// Todo 1 transform 排序不一致时,transform动画会闪烁,故这里同样的排序输出 transform
|
|
289
|
+
// values.sort()
|
|
289
290
|
const transform = [];
|
|
290
291
|
values.forEach(item => {
|
|
291
292
|
const match = item.match(/([/\w]+)\((.+)\)/);
|
|
@@ -56,6 +56,7 @@ const styles = StyleSheet.create({
|
|
|
56
56
|
|
|
57
57
|
interface DefaultFallbackProps {
|
|
58
58
|
onReload: () => void
|
|
59
|
+
bindreload: () => void
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
const DefaultFallback = ({ onReload }: DefaultFallbackProps) => {
|
|
@@ -171,7 +172,7 @@ const AsyncSuspense: React.FC<AsyncSuspenseProps> = ({
|
|
|
171
172
|
} else if (status === 'error') {
|
|
172
173
|
if (type === 'page') {
|
|
173
174
|
const fallback = getFallback ? getFallback() : DefaultFallback
|
|
174
|
-
return createElement(fallback as ComponentType<DefaultFallbackProps>, { onReload: reloadPage })
|
|
175
|
+
return createElement(fallback as ComponentType<DefaultFallbackProps>, { onReload: reloadPage, bindreload: reloadPage })
|
|
175
176
|
} else {
|
|
176
177
|
return getFallback ? createElement(getFallback(), innerProps) : null
|
|
177
178
|
}
|