@tarojs/taroize 3.8.0-canary.0 → 4.0.0-alpha.10
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/LICENSE +11 -4
- package/lib/src/cache.js +5 -2
- package/lib/src/cache.js.map +1 -1
- package/lib/src/constant.js +3 -2
- package/lib/src/constant.js.map +1 -1
- package/lib/src/events.js +28 -1
- package/lib/src/events.js.map +1 -1
- package/lib/src/global.js +10 -2
- package/lib/src/global.js.map +1 -1
- package/lib/src/index.js +34 -21
- package/lib/src/index.js.map +1 -1
- package/lib/src/json.js.map +1 -1
- package/lib/src/script.js +100 -31
- package/lib/src/script.js.map +1 -1
- package/lib/src/template.js +211 -45
- package/lib/src/template.js.map +1 -1
- package/lib/src/utils.js +273 -45
- package/lib/src/utils.js.map +1 -1
- package/lib/src/wxml.js +760 -167
- package/lib/src/wxml.js.map +1 -1
- package/package.json +54 -15
- package/lib/src/vue.js +0 -355
- package/lib/src/vue.js.map +0 -1
package/lib/src/wxml.js
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseContent = exports.
|
|
3
|
+
exports.parseStyle = exports.parseContent = exports.removeEmptyTextAndComment = exports.parseWXML = exports.createWxmlVistor = exports.getWxsImports = exports.createPreWxmlVistor = exports.convertStyleUnit = exports.wxTemplateCommand = exports.WX_SHOW = exports.WX_ELSE = exports.WX_KEY = exports.WX_FOR_INDEX = exports.WX_FOR_ITEM = exports.WX_FOR = exports.WX_ELSE_IF = exports.WX_IF = exports.NodeType = void 0;
|
|
4
4
|
/* eslint-disable camelcase */
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
5
|
+
const path = require("node:path");
|
|
6
|
+
const parser_1 = require("@babel/parser");
|
|
7
|
+
const traverse_1 = require("@babel/traverse");
|
|
8
|
+
const t = require("@babel/types");
|
|
9
|
+
const helper_1 = require("@tarojs/helper");
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
const shared_1 = require("@tarojs/shared");
|
|
8
12
|
const himalaya_wxml_1 = require("himalaya-wxml");
|
|
9
13
|
const lodash_1 = require("lodash");
|
|
14
|
+
const prettier = require("prettier");
|
|
10
15
|
const cache_1 = require("./cache");
|
|
11
16
|
const constant_1 = require("./constant");
|
|
12
17
|
const events_1 = require("./events");
|
|
13
18
|
const global_1 = require("./global");
|
|
14
19
|
const template_1 = require("./template");
|
|
15
20
|
const utils_1 = require("./utils");
|
|
16
|
-
const { prettyPrint } = require('html');
|
|
17
21
|
const allCamelCase = (str) => str.charAt(0).toUpperCase() + (0, lodash_1.camelCase)(str.substr(1));
|
|
18
22
|
function buildSlotName(slotName) {
|
|
19
23
|
return `render${slotName[0].toUpperCase() + slotName.replace('-', '').slice(1)}`;
|
|
@@ -23,7 +27,7 @@ var NodeType;
|
|
|
23
27
|
NodeType["Element"] = "element";
|
|
24
28
|
NodeType["Comment"] = "comment";
|
|
25
29
|
NodeType["Text"] = "text";
|
|
26
|
-
})(NodeType
|
|
30
|
+
})(NodeType || (exports.NodeType = NodeType = {}));
|
|
27
31
|
exports.WX_IF = 'wx:if';
|
|
28
32
|
exports.WX_ELSE_IF = 'wx:elif';
|
|
29
33
|
exports.WX_FOR = 'wx:for';
|
|
@@ -31,37 +35,183 @@ exports.WX_FOR_ITEM = 'wx:for-item';
|
|
|
31
35
|
exports.WX_FOR_INDEX = 'wx:for-index';
|
|
32
36
|
exports.WX_KEY = 'wx:key';
|
|
33
37
|
exports.WX_ELSE = 'wx:else';
|
|
34
|
-
exports.
|
|
35
|
-
|
|
36
|
-
exports.WX_ELSE_IF,
|
|
37
|
-
exports.WX_FOR,
|
|
38
|
-
exports.WX_FOR_ITEM,
|
|
39
|
-
exports.WX_FOR_INDEX,
|
|
40
|
-
exports.WX_KEY,
|
|
41
|
-
'wx:else'
|
|
42
|
-
];
|
|
38
|
+
exports.WX_SHOW = 'wx:show';
|
|
39
|
+
exports.wxTemplateCommand = [exports.WX_IF, exports.WX_ELSE_IF, exports.WX_FOR, exports.WX_FOR_ITEM, exports.WX_FOR_INDEX, exports.WX_KEY, 'wx:else'];
|
|
43
40
|
function buildElement(name, children = [], attributes = []) {
|
|
44
41
|
return {
|
|
45
42
|
tagName: name,
|
|
46
43
|
type: NodeType.Element,
|
|
47
44
|
attributes,
|
|
48
|
-
children
|
|
45
|
+
children,
|
|
49
46
|
};
|
|
50
47
|
}
|
|
51
|
-
|
|
48
|
+
// 将 style 属性中属性名转小驼峰格式 并且将 {{}} 转为 ${}格式生成对应ast节点
|
|
49
|
+
function convertStyleAttrs(styleAttrsMap) {
|
|
50
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] convertStyleAttrs - 进入函数 ${(0, utils_1.getLineBreak)()}`);
|
|
51
|
+
styleAttrsMap.forEach((attr) => {
|
|
52
|
+
attr.attrName = (0, shared_1.toCamelCase)(attr.attrName.trim());
|
|
53
|
+
// 匹配 {{}} 内部以及左右两边值
|
|
54
|
+
const attrValueReg = /([^{}]*)\{\{([^{}]*)\}\}([^{}]*)/;
|
|
55
|
+
const matchs = attrValueReg.exec(attr.value);
|
|
56
|
+
if (matchs !== null) {
|
|
57
|
+
const tempLeftValue = matchs[1] || '';
|
|
58
|
+
const tempMidValue = matchs[2] || '';
|
|
59
|
+
const tempRightValue = matchs[3] || '';
|
|
60
|
+
// 将模版中的内容转换为 ast 节点
|
|
61
|
+
const tempMidValueAst = (0, parser_1.parse)(tempMidValue).program.body[0];
|
|
62
|
+
attr.value = t.templateLiteral([t.templateElement({ raw: tempLeftValue }), t.templateElement({ raw: tempRightValue }, true)], [tempMidValueAst.expression]);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
attr.value = t.stringLiteral(attr.value.trim());
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 对 style 中单个属性值进行解析
|
|
71
|
+
*
|
|
72
|
+
* @param { any[] } styleAttrsMap 元素为单个属性值的数组
|
|
73
|
+
* @param { any[] } attrKeyValueMap 属性解析为 {attrName: attrValue} 形式的数组
|
|
74
|
+
*/
|
|
75
|
+
function parseStyleAttrs(styleAttrsMap, attrKeyValueMap) {
|
|
76
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] parseStyleAttrs - 进入函数 ${(0, utils_1.getLineBreak)()}`);
|
|
77
|
+
styleAttrsMap.forEach((attr) => {
|
|
78
|
+
if (attr) {
|
|
79
|
+
// 对含三元运算符的写法 style="width:{{ xx ? xx : xx }}" 匹配第一个 : 避免匹配三元表达式中的 : 运算符
|
|
80
|
+
const reg = /([^:]+):\s*([^;]+)/;
|
|
81
|
+
const matchs = attr.match(reg);
|
|
82
|
+
const attrName = matchs[1];
|
|
83
|
+
const value = matchs[2];
|
|
84
|
+
if (attrName) {
|
|
85
|
+
attrKeyValueMap.push({ attrName, value });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
function convertStyleUnit(value) {
|
|
91
|
+
let tempValue = value;
|
|
92
|
+
// 尺寸单位转换 都转为rem : 1rpx 转为 1/40rem,,1px 转为 1/20rem
|
|
93
|
+
if (tempValue.indexOf('px') !== -1) {
|
|
94
|
+
// 把 xxx="...[数字]rpx/px" 的尺寸单位都转为 rem, 转换方法类似postcss-taro-unit-transform
|
|
95
|
+
try {
|
|
96
|
+
tempValue = tempValue
|
|
97
|
+
.replace(/\s*-?([0-9.]+)(px)\b/gi, function (match, size, unit) {
|
|
98
|
+
if (Number(size) === 0) {
|
|
99
|
+
return match.replace(size, '0').replace(unit, 'rem');
|
|
100
|
+
}
|
|
101
|
+
return match.replace(size, parseFloat(size) / 20 + '').replace(unit, 'rem');
|
|
102
|
+
})
|
|
103
|
+
.replace(/\s*-?([0-9.]+)(rpx)\b/gi, function (match, size, unit) {
|
|
104
|
+
if (Number(size) === 0) {
|
|
105
|
+
return match.replace(size, '0').replace(unit, 'rem');
|
|
106
|
+
}
|
|
107
|
+
return match.replace(size, parseFloat(size) / 40 + '').replace(unit, 'rem');
|
|
108
|
+
});
|
|
109
|
+
// 把 xx="...{{参数}}rpx/px"的尺寸单位都转为rem,比如"{{参数}}rpx" -> "{{参数/40}}rem"
|
|
110
|
+
tempValue = tempValue
|
|
111
|
+
.replace(/\{\{([^{}]*)\}\}(px)/gi, function (match, size, unit) {
|
|
112
|
+
// 判断{{}}是否包含加减乘除算式和三元表达式, 是的话得加括号
|
|
113
|
+
if (match.match(/[+\-*/?]/g)) {
|
|
114
|
+
return match.replace(size, '(' + size + ')/20').replace(unit, 'rem');
|
|
115
|
+
}
|
|
116
|
+
return match.replace(size, size + '/20').replace(unit, 'rem');
|
|
117
|
+
})
|
|
118
|
+
.replace(/\{\{([^{}]*)\}\}(rpx)/gi, function (match, size, unit) {
|
|
119
|
+
if (match.match(/[+\-*/?]/g)) {
|
|
120
|
+
return match.replace(size, '(' + size + ')/40').replace(unit, 'rem');
|
|
121
|
+
}
|
|
122
|
+
return match.replace(size, size + '/40').replace(unit, 'rem');
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
(0, utils_1.createErrorCodeMsg)('WxmlUnitConversionError', `wxml内px/rpx单位转换失败: ${error}`, tempValue, global_1.globals.currentParseFile);
|
|
127
|
+
(0, helper_1.printLog)("error" /* processTypeEnum.ERROR */, `wxml内px/rpx单位转换失败: ${error}`);
|
|
128
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] convertStyleUnit - wxml内px/rpx单位转换异常 ${(0, utils_1.getLineBreak)()}${error} ${(0, utils_1.getLineBreak)()}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return tempValue;
|
|
132
|
+
}
|
|
133
|
+
exports.convertStyleUnit = convertStyleUnit;
|
|
134
|
+
/**
|
|
135
|
+
* 预解析,收集wxml所有的模板信息
|
|
136
|
+
*
|
|
137
|
+
* @param { any[] } templates wxml页面下的模板信息
|
|
138
|
+
* @returns Visitor
|
|
139
|
+
*/
|
|
140
|
+
const createPreWxmlVistor = (templates) => {
|
|
141
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createPreWxmlVistor - 入参 ${(0, utils_1.getLineBreak)()}templates: ${templates} ${(0, utils_1.getLineBreak)()}`);
|
|
142
|
+
// const Applys = new Map<string, string[]>()
|
|
143
|
+
return {
|
|
144
|
+
JSXElement: {
|
|
145
|
+
enter(path) {
|
|
146
|
+
const openingElement = path.get('openingElement');
|
|
147
|
+
const jsxName = openingElement.get('name');
|
|
148
|
+
if (!jsxName.isJSXIdentifier()) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const tagName = jsxName.node.name;
|
|
152
|
+
if (tagName !== 'Template') {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const templateInfo = (0, template_1.preParseTemplate)(path);
|
|
156
|
+
if (templateInfo) {
|
|
157
|
+
templates.set(templateInfo.name, {
|
|
158
|
+
funcs: templateInfo.funcs,
|
|
159
|
+
applyTemplates: templateInfo.applys,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
exports.createPreWxmlVistor = createPreWxmlVistor;
|
|
167
|
+
/**
|
|
168
|
+
* 根据template中使用的wxs组装需要导入的wxs语句
|
|
169
|
+
* 如: import xxx from '../xxx.wxs.js'
|
|
170
|
+
*
|
|
171
|
+
* @param templateFileName template模版文件名
|
|
172
|
+
* @param usedWxses template中使用的变量是wxs模块的集合
|
|
173
|
+
* @param dirPath 当前解析文件的路径
|
|
174
|
+
* @returns 需要导入的wxs语句集合
|
|
175
|
+
*/
|
|
176
|
+
function getWxsImports(templateFileName, usedWxses, dirPath) {
|
|
177
|
+
const templatePath = path.join(global_1.globals.rootPath, 'imports', `${templateFileName}.js`);
|
|
178
|
+
const wxsImports = [];
|
|
179
|
+
for (const usedWxs of usedWxses) {
|
|
180
|
+
const wxsAbsPath = path.resolve(dirPath, `${usedWxs.src}.js`);
|
|
181
|
+
const wxsRelPath = path.relative(path.dirname(templatePath), wxsAbsPath);
|
|
182
|
+
wxsImports.push((0, utils_1.buildImportStatement)((0, utils_1.normalizePath)(wxsRelPath), [], usedWxs.module));
|
|
183
|
+
}
|
|
184
|
+
return wxsImports;
|
|
185
|
+
}
|
|
186
|
+
exports.getWxsImports = getWxsImports;
|
|
187
|
+
const createWxmlVistor = (loopIds, refIds, dirPath, wxses = [], imports = [], templates) => {
|
|
188
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createWxmlVistor - 入参 ${(0, utils_1.getLineBreak)()}dirPath: ${dirPath} ${(0, utils_1.getLineBreak)()}`);
|
|
52
189
|
const jsxAttrVisitor = (path) => {
|
|
190
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createWxmlVistor - 解析JSXAttribute ${(0, utils_1.getLineBreak)()}${path} ${(0, utils_1.getLineBreak)()}`);
|
|
53
191
|
const name = path.node.name;
|
|
54
|
-
const jsx = path.findParent(p => p.isJSXElement());
|
|
192
|
+
const jsx = path.findParent((p) => p.isJSXElement());
|
|
55
193
|
// 把 hidden 转换为 wxif
|
|
56
194
|
if (name.name === 'hidden') {
|
|
57
195
|
const value = path.get('value');
|
|
58
|
-
if (t.isJSXExpressionContainer(value)) {
|
|
196
|
+
if (t.isJSXExpressionContainer(value) && !t.isJSXEmptyExpression(value.node.expression)) {
|
|
59
197
|
const exclamation = t.unaryExpression('!', value.node.expression);
|
|
60
198
|
path.set('value', t.jSXExpressionContainer(exclamation));
|
|
61
199
|
path.set('name', t.jSXIdentifier(exports.WX_IF));
|
|
62
200
|
}
|
|
63
201
|
}
|
|
202
|
+
// 当设置图片mode="",则改为默认值(且taro不支持mode空值)
|
|
203
|
+
if (name.name === 'mode' && path.node.value === null) {
|
|
204
|
+
path.set('value', t.stringLiteral('scaleToFill'));
|
|
205
|
+
}
|
|
206
|
+
// 当设置 style 属性但未赋值则删除该属性
|
|
207
|
+
if (name.name === 'style' && !path.node.value) {
|
|
208
|
+
path.remove();
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
64
211
|
const valueCopy = (0, lodash_1.cloneDeep)(path.get('value').node);
|
|
212
|
+
if (typeof valueCopy === 'undefined' || t.isJSXFragment(valueCopy)) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
65
215
|
transformIf(name.name, path, jsx, valueCopy);
|
|
66
216
|
const loopItem = transformLoop(name.name, path, jsx, valueCopy);
|
|
67
217
|
if (loopItem) {
|
|
@@ -74,14 +224,31 @@ const createWxmlVistor = (loopIds, refIds, dirPath, wxses = [], imports = []) =>
|
|
|
74
224
|
}
|
|
75
225
|
};
|
|
76
226
|
const renameJSXKey = (path) => {
|
|
227
|
+
var _a, _b, _c, _d;
|
|
228
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createWxmlVistor - 解析JSXIdentifier ${(0, utils_1.getLineBreak)()}${path} ${(0, utils_1.getLineBreak)()}`);
|
|
77
229
|
const nodeName = path.node.name;
|
|
78
230
|
if (path.parentPath.isJSXAttribute()) {
|
|
79
|
-
|
|
80
|
-
|
|
231
|
+
const cacheNode = (0, lodash_1.cloneDeep)(path.parentPath.parentPath.parent);
|
|
232
|
+
if (nodeName === exports.WX_SHOW) {
|
|
233
|
+
path.replaceWith(t.jSXIdentifier(exports.WX_IF)); // wx:show转换后不支持,不频繁切换的话wx:if可替代
|
|
234
|
+
const position = {
|
|
235
|
+
col: ((_a = cacheNode.position) === null || _a === void 0 ? void 0 : _a.start.column) || 0,
|
|
236
|
+
row: ((_b = cacheNode.position) === null || _b === void 0 ? void 0 : _b.start.line) || 0
|
|
237
|
+
};
|
|
238
|
+
(0, utils_1.createErrorCodeMsg)('uncompilableAttribute', `属性 ${nodeName}不能编译,会被替换为wx:if`, (0, utils_1.astToCode)(cacheNode) || '', global_1.globals.currentParseFile, position);
|
|
239
|
+
// eslint-disable-next-line no-console
|
|
240
|
+
console.log(`属性 ${nodeName}不能编译,会被替换为wx:if`);
|
|
241
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] createWxmlVistor - ${nodeName} 属性不能编译,会被替换为 wx:if ${(0, utils_1.getLineBreak)()}`);
|
|
81
242
|
}
|
|
82
|
-
if (nodeName.startsWith('wx:') && !exports.wxTemplateCommand.includes(nodeName)) {
|
|
243
|
+
else if (nodeName.startsWith('wx:') && !exports.wxTemplateCommand.includes(nodeName)) {
|
|
244
|
+
const position = {
|
|
245
|
+
col: ((_c = cacheNode.position) === null || _c === void 0 ? void 0 : _c.start.column) || 0,
|
|
246
|
+
row: ((_d = cacheNode.position) === null || _d === void 0 ? void 0 : _d.start.line) || 0
|
|
247
|
+
};
|
|
248
|
+
(0, utils_1.createErrorCodeMsg)('unknownScopeAttribute', `未知 wx 作用域属性: ${nodeName},该属性会被移除掉。`, (0, utils_1.astToCode)(cacheNode) || '', global_1.globals.currentParseFile, position);
|
|
83
249
|
// eslint-disable-next-line no-console
|
|
84
250
|
console.log(`未知 wx 作用域属性: ${nodeName},该属性会被移除掉。`);
|
|
251
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] createWxmlVistor - 未知 wx 作用域属性: ${nodeName},该属性会被移除掉 ${(0, utils_1.getLineBreak)()}`);
|
|
85
252
|
path.parentPath.remove();
|
|
86
253
|
}
|
|
87
254
|
}
|
|
@@ -89,8 +256,25 @@ const createWxmlVistor = (loopIds, refIds, dirPath, wxses = [], imports = []) =>
|
|
|
89
256
|
return {
|
|
90
257
|
JSXAttribute: jsxAttrVisitor,
|
|
91
258
|
JSXIdentifier: renameJSXKey,
|
|
259
|
+
Identifier: {
|
|
260
|
+
enter(path) {
|
|
261
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createWxmlVistor - 解析Identifier ${(0, utils_1.getLineBreak)()}${path} ${(0, utils_1.getLineBreak)()}`);
|
|
262
|
+
if (!path.isReferencedIdentifier()) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const jsxExprContainer = path.findParent((p) => p.isJSXExpressionContainer());
|
|
266
|
+
if (!jsxExprContainer || !jsxExprContainer.isJSXExpressionContainer()) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
if ((0, utils_1.isValidVarName)(path.node.name)) {
|
|
270
|
+
refIds.add(path.node.name);
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
},
|
|
92
274
|
JSXElement: {
|
|
93
275
|
enter(path) {
|
|
276
|
+
var _a, _b, _c;
|
|
277
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createWxmlVistor - 解析JSXElement ${(0, utils_1.getLineBreak)()}${path} ${(0, utils_1.getLineBreak)()}`);
|
|
94
278
|
const openingElement = path.get('openingElement');
|
|
95
279
|
const jsxName = openingElement.get('name');
|
|
96
280
|
const attrs = openingElement.get('attributes');
|
|
@@ -98,31 +282,22 @@ const createWxmlVistor = (loopIds, refIds, dirPath, wxses = [], imports = []) =>
|
|
|
98
282
|
return;
|
|
99
283
|
}
|
|
100
284
|
path.traverse({
|
|
101
|
-
Identifier(p) {
|
|
102
|
-
if (!p.isReferencedIdentifier()) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
const jsxExprContainer = p.findParent(p => p.isJSXExpressionContainer());
|
|
106
|
-
if (!jsxExprContainer || !jsxExprContainer.isJSXExpressionContainer()) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
if ((0, utils_1.isValidVarName)(p.node.name)) {
|
|
110
|
-
refIds.add(p.node.name);
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
285
|
JSXAttribute: jsxAttrVisitor,
|
|
114
|
-
JSXIdentifier: renameJSXKey
|
|
286
|
+
JSXIdentifier: renameJSXKey,
|
|
115
287
|
});
|
|
116
|
-
const slotAttr = attrs.find(a => { var _a; return ((_a = a.node) === null || _a === void 0 ? void 0 : _a.name.name) === 'slot'; });
|
|
117
|
-
if (slotAttr) {
|
|
288
|
+
const slotAttr = attrs.find((a) => { var _a; return t.isJSXAttribute(a.node) && ((_a = a.node) === null || _a === void 0 ? void 0 : _a.name.name) === 'slot'; });
|
|
289
|
+
if (slotAttr && t.isJSXAttribute(slotAttr.node)) {
|
|
118
290
|
const slotValue = slotAttr.node.value;
|
|
291
|
+
let slotName = '';
|
|
119
292
|
if (slotValue && t.isStringLiteral(slotValue)) {
|
|
120
|
-
|
|
121
|
-
const parentComponent = path.findParent(p => p.isJSXElement() &&
|
|
293
|
+
slotName = slotValue.value;
|
|
294
|
+
const parentComponent = path.findParent((p) => p.isJSXElement() &&
|
|
295
|
+
t.isJSXIdentifier(p.node.openingElement.name) &&
|
|
296
|
+
!utils_1.DEFAULT_Component_SET.has(p.node.openingElement.name.name));
|
|
122
297
|
if (parentComponent && parentComponent.isJSXElement()) {
|
|
123
298
|
slotAttr.remove();
|
|
124
299
|
path.traverse({
|
|
125
|
-
JSXAttribute: jsxAttrVisitor
|
|
300
|
+
JSXAttribute: jsxAttrVisitor,
|
|
126
301
|
});
|
|
127
302
|
const block = (0, utils_1.buildBlockElement)();
|
|
128
303
|
block.children = [(0, lodash_1.cloneDeep)(path.node)];
|
|
@@ -131,19 +306,26 @@ const createWxmlVistor = (loopIds, refIds, dirPath, wxses = [], imports = []) =>
|
|
|
131
306
|
}
|
|
132
307
|
}
|
|
133
308
|
else {
|
|
134
|
-
|
|
309
|
+
// 当元素设置slot标签且值为空串时,移除slot属性
|
|
310
|
+
slotAttr.remove();
|
|
135
311
|
}
|
|
136
312
|
}
|
|
137
313
|
const tagName = jsxName.node.name;
|
|
138
314
|
if (tagName === 'Slot') {
|
|
139
|
-
|
|
315
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createWxmlVistor - tagName: Slot ${(0, utils_1.getLineBreak)()}`);
|
|
316
|
+
const nameAttr = attrs.find((a) => t.isJSXAttribute(a.node) && a.node.name.name === 'name');
|
|
140
317
|
let slotName = '';
|
|
141
|
-
if (nameAttr) {
|
|
318
|
+
if (nameAttr && t.isJSXAttribute(nameAttr.node)) {
|
|
142
319
|
if (nameAttr.node.value && t.isStringLiteral(nameAttr.node.value)) {
|
|
143
320
|
slotName = nameAttr.node.value.value;
|
|
144
321
|
}
|
|
145
322
|
else {
|
|
146
|
-
|
|
323
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] createWxmlVistor - slot 的值不是一个字符串 ${(0, utils_1.getLineBreak)()}`);
|
|
324
|
+
// const error = codeFrameError(jsxName.node, 'slot 的值必须是一个字符串')
|
|
325
|
+
// @ts-ignore
|
|
326
|
+
const { line, column } = ((_b = (_a = path.node) === null || _a === void 0 ? void 0 : _a.position) === null || _b === void 0 ? void 0 : _b.start) || { line: 0, column: 0 };
|
|
327
|
+
const position = { col: column, row: line };
|
|
328
|
+
throw new utils_1.IReportError('slot 的值必须是一个字符串', 'SlotValueTypeError', 'WXML_FILE', (0, utils_1.astToCode)(path.node) || '', position);
|
|
147
329
|
}
|
|
148
330
|
}
|
|
149
331
|
const children = t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier('props')), t.identifier(slotName ? buildSlotName(slotName) : 'children'));
|
|
@@ -151,60 +333,137 @@ const createWxmlVistor = (loopIds, refIds, dirPath, wxses = [], imports = []) =>
|
|
|
151
333
|
path.replaceWith(path.parentPath.isJSXElement() ? t.jSXExpressionContainer(children) : children);
|
|
152
334
|
}
|
|
153
335
|
catch (error) {
|
|
336
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] createWxmlVistor - Slot 节点替换异常 ${(0, utils_1.getLineBreak)()}${error} ${(0, utils_1.getLineBreak)()}`);
|
|
154
337
|
//
|
|
155
338
|
}
|
|
156
339
|
}
|
|
157
340
|
if (tagName === 'Wxs') {
|
|
158
|
-
|
|
341
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createWxmlVistor - tagName: Wxs ${(0, utils_1.getLineBreak)()}`);
|
|
342
|
+
wxses.push(getWXS(attrs.map((a) => a.node), path, imports));
|
|
159
343
|
}
|
|
160
344
|
if (tagName === 'Template') {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
// })
|
|
164
|
-
const template = (0, template_1.parseTemplate)(path, dirPath);
|
|
345
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createWxmlVistor - tagName: Template ${(0, utils_1.getLineBreak)()}`);
|
|
346
|
+
const template = (0, template_1.parseTemplate)(path, dirPath, wxses);
|
|
165
347
|
if (template) {
|
|
166
|
-
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
]);
|
|
348
|
+
let funcs = new Set();
|
|
349
|
+
const { ast: classDecl, name, tmplName, usedWxses } = template;
|
|
350
|
+
const wxsImports = getWxsImports(name, usedWxses, dirPath);
|
|
351
|
+
const taroComponentsImport = (0, utils_1.buildImportStatement)('@tarojs/components', [...global_1.usedComponents]);
|
|
170
352
|
const taroImport = (0, utils_1.buildImportStatement)('@tarojs/taro', [], 'Taro');
|
|
171
353
|
const reactImport = (0, utils_1.buildImportStatement)('react', [], 'React');
|
|
172
|
-
//
|
|
173
|
-
|
|
174
|
-
// [],
|
|
175
|
-
// 'withWeapp'
|
|
176
|
-
// )
|
|
354
|
+
// 引入 @tarojs/with-weapp
|
|
355
|
+
const withWeappImport = (0, utils_1.buildImportStatement)('@tarojs/with-weapp', [], 'withWeapp');
|
|
177
356
|
const ast = t.file(t.program([]));
|
|
178
|
-
ast.program.body.unshift(taroComponentsImport, reactImport, taroImport,
|
|
179
|
-
// withWeappImport,
|
|
180
|
-
t.exportDefaultDeclaration(classDecl));
|
|
357
|
+
ast.program.body.unshift(taroComponentsImport, reactImport, taroImport, withWeappImport, ...wxsImports, classDecl, t.exportDefaultDeclaration(t.identifier(name)));
|
|
181
358
|
const usedTemplate = new Set();
|
|
182
|
-
|
|
359
|
+
// funcs的值首先来源于预解析结果
|
|
360
|
+
if (templates) {
|
|
361
|
+
const applyFuncs = (_c = templates.get(name)) === null || _c === void 0 ? void 0 : _c.funcs;
|
|
362
|
+
if (applyFuncs) {
|
|
363
|
+
funcs = applyFuncs;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
(0, traverse_1.default)(ast, {
|
|
183
367
|
JSXIdentifier(path) {
|
|
368
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createWxmlVistor - 解析JSXIdentifier ${(0, utils_1.getLineBreak)()}${path} ${(0, utils_1.getLineBreak)()}`);
|
|
184
369
|
const node = path.node;
|
|
185
370
|
if (node.name.endsWith('Tmpl') && node.name.length > 4 && path.parentPath.isJSXOpeningElement()) {
|
|
186
371
|
usedTemplate.add(node.name);
|
|
372
|
+
// 传递的方法有两处来源
|
|
373
|
+
const templateImport = imports.find((tmplImport) => tmplImport.name === `${node.name}`);
|
|
374
|
+
const templateInfo = templates === null || templates === void 0 ? void 0 : templates.get(node.name);
|
|
375
|
+
let templateFuncs = templateImport === null || templateImport === void 0 ? void 0 : templateImport.funcs;
|
|
376
|
+
if (templateInfo === null || templateInfo === void 0 ? void 0 : templateInfo.funcs) {
|
|
377
|
+
if (templateFuncs) {
|
|
378
|
+
templateFuncs = new Set([...templateFuncs, ...templateInfo.funcs]);
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
templateFuncs = templateInfo.funcs;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (templateFuncs && templateFuncs.size > 0) {
|
|
385
|
+
const openingElement = path.parentPath.node;
|
|
386
|
+
const attributes = openingElement.attributes;
|
|
387
|
+
templateFuncs.forEach((templateFunc) => {
|
|
388
|
+
const value = t.jsxExpressionContainer(t.identifier(templateFunc));
|
|
389
|
+
const name = t.jsxIdentifier(templateFunc);
|
|
390
|
+
// 传递的方法插入到Tmpl标签属性中
|
|
391
|
+
attributes.push(t.jsxAttribute(name, value));
|
|
392
|
+
if (!funcs.has(templateFunc)) {
|
|
393
|
+
funcs.add(templateFunc);
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
}
|
|
187
397
|
}
|
|
188
|
-
}
|
|
398
|
+
},
|
|
399
|
+
JSXAttribute(path) {
|
|
400
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createWxmlVistor - 解析JSXAttribute ${(0, utils_1.getLineBreak)()}${path} ${(0, utils_1.getLineBreak)()}`);
|
|
401
|
+
// 识别template使用到的处理事件的func
|
|
402
|
+
const node = path.node;
|
|
403
|
+
if (t.isJSXExpressionContainer(node.value) &&
|
|
404
|
+
t.isMemberExpression(node.value.expression) &&
|
|
405
|
+
t.isThisExpression(node.value.expression.object) &&
|
|
406
|
+
t.isIdentifier(node.value.expression.property)) {
|
|
407
|
+
const funcName = node.value.expression.property.name;
|
|
408
|
+
// func的调用形式 this.func --> func
|
|
409
|
+
path.replaceWith(t.jsxAttribute(node.name, t.jsxExpressionContainer(t.identifier(funcName))));
|
|
410
|
+
}
|
|
411
|
+
},
|
|
189
412
|
});
|
|
190
|
-
|
|
413
|
+
(0, traverse_1.default)(ast, {
|
|
414
|
+
// 将使用到的处理事件的func写入到props
|
|
415
|
+
BlockStatement(path) {
|
|
416
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createWxmlVistor - 解析BlockStatement ${(0, utils_1.getLineBreak)()}${path} ${(0, utils_1.getLineBreak)()}`);
|
|
417
|
+
if (funcs.size > 0) {
|
|
418
|
+
const body = path.node.body;
|
|
419
|
+
if (t.isVariableDeclaration(body[0])) {
|
|
420
|
+
// 如果已经定义了props
|
|
421
|
+
const declarator = body[0].declarations[0];
|
|
422
|
+
if (t.isObjectPattern(declarator.id)) {
|
|
423
|
+
const properties = declarator.id.properties;
|
|
424
|
+
funcs.forEach((func) => {
|
|
425
|
+
properties.push(t.objectProperty(t.identifier(func), t.identifier(func), false, true));
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
// 没有定义,则插入 const {xxx} = this.props
|
|
431
|
+
const properties = [];
|
|
432
|
+
funcs.forEach((func) => {
|
|
433
|
+
properties.push(t.objectProperty(t.identifier(func), t.identifier(func), false, true));
|
|
434
|
+
});
|
|
435
|
+
const id = t.objectPattern(properties);
|
|
436
|
+
const init = t.memberExpression(t.thisExpression(), t.identifier('props'));
|
|
437
|
+
const declarator = t.variableDeclarator(id, init);
|
|
438
|
+
const declaration = t.variableDeclaration('const', [declarator]);
|
|
439
|
+
body.splice(0, 0, declaration);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
path.stop();
|
|
443
|
+
},
|
|
444
|
+
});
|
|
445
|
+
usedTemplate.forEach((componentName) => {
|
|
191
446
|
if (componentName !== classDecl.id.name) {
|
|
192
447
|
ast.program.body.unshift((0, utils_1.buildImportStatement)(`./${componentName}`, [], componentName));
|
|
193
448
|
}
|
|
194
449
|
});
|
|
195
450
|
imports.push({
|
|
196
451
|
ast,
|
|
197
|
-
name
|
|
452
|
+
name,
|
|
453
|
+
funcs,
|
|
454
|
+
tmplName,
|
|
198
455
|
});
|
|
199
456
|
}
|
|
200
457
|
}
|
|
201
458
|
if (tagName === 'Import') {
|
|
459
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createWxmlVistor - tagName: Import ${(0, utils_1.getLineBreak)()}`);
|
|
202
460
|
const mods = (0, template_1.parseModule)(path, dirPath, 'import');
|
|
203
461
|
if (mods) {
|
|
204
462
|
imports.push(...mods);
|
|
205
463
|
}
|
|
206
464
|
}
|
|
207
465
|
if (tagName === 'Include') {
|
|
466
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] createWxmlVistor - tagName: Include ${(0, utils_1.getLineBreak)()}`);
|
|
208
467
|
(0, template_1.parseModule)(path, dirPath, 'include');
|
|
209
468
|
}
|
|
210
469
|
},
|
|
@@ -217,33 +476,93 @@ const createWxmlVistor = (loopIds, refIds, dirPath, wxses = [], imports = []) =>
|
|
|
217
476
|
const children = path.node.children;
|
|
218
477
|
if (children.length === 1) {
|
|
219
478
|
const caller = children[0];
|
|
220
|
-
if (t.isJSXExpressionContainer(caller) &&
|
|
479
|
+
if (t.isJSXExpressionContainer(caller) &&
|
|
480
|
+
t.isCallExpression(caller.expression) &&
|
|
481
|
+
!path.parentPath.isExpressionStatement()) {
|
|
221
482
|
try {
|
|
222
483
|
path.replaceWith(caller);
|
|
223
484
|
}
|
|
224
485
|
catch (error) {
|
|
486
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] createWxmlVistor - block 节点替换异常 ${(0, utils_1.getLineBreak)()}${error} ${(0, utils_1.getLineBreak)()}`);
|
|
225
487
|
//
|
|
226
488
|
}
|
|
227
489
|
}
|
|
228
490
|
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
491
|
+
},
|
|
492
|
+
},
|
|
231
493
|
};
|
|
232
494
|
};
|
|
233
495
|
exports.createWxmlVistor = createWxmlVistor;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
496
|
+
/**
|
|
497
|
+
* @description 根据模板信息中的直接调用,遍历获取完整的调用
|
|
498
|
+
* @param templates 模板信息
|
|
499
|
+
*/
|
|
500
|
+
function templateBfs(templates) {
|
|
501
|
+
var _a;
|
|
502
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] templateBfs - 进入函数 ${(0, utils_1.getLineBreak)()}`);
|
|
503
|
+
const names = [];
|
|
504
|
+
const applys = new Map();
|
|
505
|
+
for (const key of templates.keys()) {
|
|
506
|
+
names.push(key);
|
|
507
|
+
const templateInfo = templates.get(key);
|
|
508
|
+
if (templateInfo) {
|
|
509
|
+
applys.set(key, templateInfo.applyTemplates);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
for (const name of names) {
|
|
513
|
+
const templateInfo = templates.get(name);
|
|
514
|
+
if (!templateInfo || templateInfo.applyTemplates.size === 0) {
|
|
515
|
+
continue;
|
|
516
|
+
}
|
|
517
|
+
const visited = new Set();
|
|
518
|
+
const queue = [name];
|
|
519
|
+
while (queue.length > 0) {
|
|
520
|
+
const template = queue.shift();
|
|
521
|
+
if (visited.has(template)) {
|
|
522
|
+
continue;
|
|
523
|
+
}
|
|
524
|
+
visited.add(template);
|
|
525
|
+
const templateApplys = applys.get(template);
|
|
526
|
+
if (!templateApplys || templateApplys.size === 0) {
|
|
527
|
+
continue;
|
|
528
|
+
}
|
|
529
|
+
templateApplys.forEach((item) => {
|
|
530
|
+
if (names.includes(item)) {
|
|
531
|
+
queue.push(item);
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
visited.delete(name);
|
|
536
|
+
templateInfo.applyTemplates = visited;
|
|
537
|
+
for (const item of visited) {
|
|
538
|
+
const applyFuncs = (_a = templates.get(item)) === null || _a === void 0 ? void 0 : _a.funcs;
|
|
539
|
+
if (applyFuncs) {
|
|
540
|
+
const funcs = templateInfo.funcs;
|
|
541
|
+
templateInfo.funcs = new Set([...funcs, ...applyFuncs]);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
templates.set(name, templateInfo);
|
|
238
545
|
}
|
|
546
|
+
}
|
|
547
|
+
function parseWXML(dirPath, wxml, parseImport) {
|
|
548
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] parseWXML - 入参 ${(0, utils_1.getLineBreak)()}dirPath: ${dirPath} ${(0, utils_1.getLineBreak)()}parseImport: ${parseImport} ${(0, utils_1.getLineBreak)()}`);
|
|
239
549
|
try {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
550
|
+
if (wxml) {
|
|
551
|
+
const REG_WXS = /(<wxs)[^>]*>[\s\S]*?(<\/ *wxs *>)/g;
|
|
552
|
+
if (REG_WXS.test(wxml)) {
|
|
553
|
+
// prettier html parser 只对 <srcipt> 标签里的 JS 脚本进行格式化,<wxs> 里的脚本会被格式化在一行中,此时脚本如果存在注释的话会报错。
|
|
554
|
+
// 因此需要把 <wxs> 转换为 <script> 后再使用 prettier 进行格式化。
|
|
555
|
+
wxml = wxml.replace(/<wxs/g, '<script').replace(/<\/ *wxs *>/g, '</script>');
|
|
556
|
+
wxml = prettier.format(wxml, { parser: 'html' });
|
|
557
|
+
wxml = wxml.replace(/<script/g, '<wxs').replace(/<\/ *script *>/g, '</wxs>');
|
|
558
|
+
}
|
|
559
|
+
else {
|
|
560
|
+
wxml = prettier.format(wxml, { parser: 'html' });
|
|
561
|
+
}
|
|
562
|
+
}
|
|
245
563
|
}
|
|
246
564
|
catch (error) {
|
|
565
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] parseWXML - wxml代码格式化异常 ${(0, utils_1.getLineBreak)()}${error} ${(0, utils_1.getLineBreak)()}`);
|
|
247
566
|
//
|
|
248
567
|
}
|
|
249
568
|
if (!parseImport) {
|
|
@@ -255,21 +574,35 @@ function parseWXML(dirPath, wxml, parseImport) {
|
|
|
255
574
|
const imports = [];
|
|
256
575
|
const refIds = new Set();
|
|
257
576
|
const loopIds = new Set();
|
|
577
|
+
// 模板信息
|
|
578
|
+
const templates = new Map();
|
|
258
579
|
if (!wxml) {
|
|
259
580
|
return {
|
|
260
581
|
wxses,
|
|
261
582
|
imports,
|
|
262
583
|
refIds,
|
|
263
|
-
wxml: t.nullLiteral()
|
|
584
|
+
wxml: t.nullLiteral(),
|
|
264
585
|
};
|
|
265
586
|
}
|
|
266
|
-
const nodes =
|
|
267
|
-
const ast = t.file(t.program([
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
587
|
+
const nodes = removeEmptyTextAndComment((0, himalaya_wxml_1.parse)(wxml.trim(), Object.assign(Object.assign({}, himalaya_wxml_1.parseDefaults), { includePositions: true })));
|
|
588
|
+
const ast = t.file(t.program([t.expressionStatement(parseNode(buildElement('block', nodes)))], []));
|
|
589
|
+
// 确认当前解析页面是否已经解析过,如果解析过则直接获取缓存解析
|
|
590
|
+
let parseResult = (0, cache_1.getCacheWxml)(dirPath, hydrate(ast));
|
|
591
|
+
if (parseResult) {
|
|
592
|
+
return parseResult;
|
|
593
|
+
}
|
|
594
|
+
// 在解析wxml页面前,先进行预解析
|
|
595
|
+
// 当前预解析主要为了抽取页面下的模板信息
|
|
596
|
+
(0, traverse_1.default)(ast, (0, exports.createPreWxmlVistor)(templates));
|
|
597
|
+
// 获取template调用后,需要通过遍历,获取某个模板完整的调用关系
|
|
598
|
+
templateBfs(templates);
|
|
599
|
+
(0, traverse_1.default)(ast, (0, exports.createWxmlVistor)(loopIds, refIds, dirPath, wxses, imports, templates));
|
|
600
|
+
refIds.forEach((id) => {
|
|
601
|
+
if (loopIds.has(id) ||
|
|
602
|
+
imports
|
|
603
|
+
.filter((i) => i.wxs)
|
|
604
|
+
.map((i) => i.name)
|
|
605
|
+
.includes(id)) {
|
|
273
606
|
refIds.delete(id);
|
|
274
607
|
}
|
|
275
608
|
});
|
|
@@ -277,13 +610,14 @@ function parseWXML(dirPath, wxml, parseImport) {
|
|
|
277
610
|
wxses,
|
|
278
611
|
imports,
|
|
279
612
|
wxml: hydrate(ast),
|
|
280
|
-
refIds
|
|
613
|
+
refIds,
|
|
281
614
|
};
|
|
282
615
|
(0, cache_1.saveCacheWxml)(dirPath, parseResult);
|
|
283
616
|
return parseResult;
|
|
284
617
|
}
|
|
285
618
|
exports.parseWXML = parseWXML;
|
|
286
619
|
function getWXS(attrs, path, imports) {
|
|
620
|
+
var _a, _b, _c, _d, _e, _f;
|
|
287
621
|
let moduleName = null;
|
|
288
622
|
let src = null;
|
|
289
623
|
for (const attr of attrs) {
|
|
@@ -292,13 +626,16 @@ function getWXS(attrs, path, imports) {
|
|
|
292
626
|
const attrValue = attr.value;
|
|
293
627
|
let value = null;
|
|
294
628
|
if (attrValue === null) {
|
|
295
|
-
|
|
629
|
+
// @ts-ignore
|
|
630
|
+
const { line, column } = ((_b = (_a = path.node) === null || _a === void 0 ? void 0 : _a.position) === null || _b === void 0 ? void 0 : _b.start) || { line: 0, column: 0 };
|
|
631
|
+
const position = { col: column, row: line };
|
|
632
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] getWXS - wxs 标签的属性值为空 ${(0, utils_1.getLineBreak)()}`);
|
|
633
|
+
throw new utils_1.IReportError('wxs 标签的属性值不得为空', 'WxsTagAttributeEmptyError', 'WXML_FILE', (0, utils_1.astToCode)(path.node) || '', position);
|
|
296
634
|
}
|
|
297
635
|
if (t.isStringLiteral(attrValue)) {
|
|
298
636
|
value = attrValue.value;
|
|
299
637
|
}
|
|
300
|
-
else if (t.isJSXExpressionContainer(attrValue) &&
|
|
301
|
-
t.isStringLiteral(attrValue.expression)) {
|
|
638
|
+
else if (t.isJSXExpressionContainer(attrValue) && t.isStringLiteral(attrValue.expression)) {
|
|
302
639
|
value = attrValue.expression.value;
|
|
303
640
|
}
|
|
304
641
|
if (attrName === 'module') {
|
|
@@ -310,32 +647,116 @@ function getWXS(attrs, path, imports) {
|
|
|
310
647
|
}
|
|
311
648
|
}
|
|
312
649
|
if (!src) {
|
|
313
|
-
const { children: [script] } = path.node;
|
|
650
|
+
const { children: [script], } = path.node;
|
|
314
651
|
if (!t.isJSXText(script)) {
|
|
315
|
-
|
|
652
|
+
// @ts-ignore
|
|
653
|
+
const { line, column } = ((_d = (_c = path.node) === null || _c === void 0 ? void 0 : _c.position) === null || _d === void 0 ? void 0 : _d.start) || { line: 0, column: 0 };
|
|
654
|
+
const position = { col: column, row: line };
|
|
655
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] getWXS - wxs 没有 src 属性且标签内部没有 wxs 代码 ${(0, utils_1.getLineBreak)()}`);
|
|
656
|
+
throw new utils_1.IReportError('wxs 如果没有 src 属性,标签内部必须有 wxs 代码。', 'WxsTagCodeMissingError', 'WXML_FILE', (0, utils_1.astToCode)(path.node) || '', position);
|
|
316
657
|
}
|
|
317
658
|
src = './wxs__' + moduleName;
|
|
318
659
|
const ast = (0, utils_1.parseCode)(script.value);
|
|
319
|
-
(0,
|
|
660
|
+
(0, traverse_1.default)(ast, {
|
|
320
661
|
CallExpression(path) {
|
|
662
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
663
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] getWXS - 解析CallExpression ${(0, utils_1.getLineBreak)()}${path} ${(0, utils_1.getLineBreak)()}`);
|
|
664
|
+
// wxs标签中getRegExp转换为new RegExp
|
|
321
665
|
if (t.isIdentifier(path.node.callee, { name: 'getRegExp' })) {
|
|
322
|
-
|
|
666
|
+
// 根据正则表达式是否定义了正则匹配修饰符,有则不变,没有就用默认
|
|
667
|
+
if (path.node.arguments.length > 1) {
|
|
668
|
+
const regex = path.node.arguments[0];
|
|
669
|
+
const modifier = path.node.arguments[1];
|
|
670
|
+
if (t.isStringLiteral(regex) && t.isStringLiteral(modifier)) {
|
|
671
|
+
const regexStr = (_a = regex.extra) === null || _a === void 0 ? void 0 : _a.raw;
|
|
672
|
+
const regexModifier = (_b = modifier.extra) === null || _b === void 0 ? void 0 : _b.rawValue;
|
|
673
|
+
const regexWithoutQuotes = regexStr.replace(/^['"](.*)['"]$/, '$1');
|
|
674
|
+
const newExpr = t.newExpression(t.identifier('RegExp'), [
|
|
675
|
+
t.stringLiteral(regexWithoutQuotes),
|
|
676
|
+
t.stringLiteral(regexModifier),
|
|
677
|
+
]);
|
|
678
|
+
path.replaceWith(newExpr);
|
|
679
|
+
}
|
|
680
|
+
else if (t.isIdentifier(regex) || t.isIdentifier(modifier)) {
|
|
681
|
+
// @ts-ignore
|
|
682
|
+
const { line, column } = ((_d = (_c = path.node) === null || _c === void 0 ? void 0 : _c.position) === null || _d === void 0 ? void 0 : _d.start) || { line: 0, column: 0 };
|
|
683
|
+
const position = { col: column, row: line };
|
|
684
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] getWXS - getRegExp 函数暂不支持传入变量类型的参数 ${(0, utils_1.getLineBreak)()}`);
|
|
685
|
+
throw new utils_1.IReportError('getRegExp 函数暂不支持传入变量类型的参数', 'GetRegExpVariableTypeError', 'WXML_FILE', (0, utils_1.astToCode)(path.node) || '', position);
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
// @ts-ignore
|
|
689
|
+
const { line, column } = ((_f = (_e = path.node) === null || _e === void 0 ? void 0 : _e.position) === null || _f === void 0 ? void 0 : _f.start) || { line: 0, column: 0 };
|
|
690
|
+
const position = { col: column, row: line };
|
|
691
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] getWXS - getRegExp 函数暂不支持传入非字符串类型的参数 ${(0, utils_1.getLineBreak)()}`);
|
|
692
|
+
throw new utils_1.IReportError('getRegExp 函数暂不支持传入非字符串类型的参数', 'GetRegExpParameterTypeError', 'WXML_FILE', (0, utils_1.astToCode)(path.node) || '', position);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
else if (path.node.arguments.length === 1) {
|
|
696
|
+
const regex = path.node.arguments[0];
|
|
697
|
+
if (t.isStringLiteral(regex)) {
|
|
698
|
+
const regexStr = (_g = regex.extra) === null || _g === void 0 ? void 0 : _g.raw;
|
|
699
|
+
const regexWithoutQuotes = regexStr.replace(/^['"](.*)['"]$/, '$1');
|
|
700
|
+
const newExpr = t.newExpression(t.identifier('RegExp'), [t.stringLiteral(regexWithoutQuotes)]);
|
|
701
|
+
path.replaceWith(newExpr);
|
|
702
|
+
}
|
|
703
|
+
else if (t.isIdentifier(regex)) {
|
|
704
|
+
// @ts-ignore
|
|
705
|
+
const { line, column } = ((_j = (_h = path.node) === null || _h === void 0 ? void 0 : _h.position) === null || _j === void 0 ? void 0 : _j.start) || { line: 0, column: 0 };
|
|
706
|
+
const position = { col: column, row: line };
|
|
707
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] getWXS - getRegExp 函数暂不支持传入变量类型的参数 ${(0, utils_1.getLineBreak)()}`);
|
|
708
|
+
throw new utils_1.IReportError('getRegExp 函数暂不支持传入变量类型的参数', 'GetRegExpVariableTypeError', 'WXML_FILE', (0, utils_1.astToCode)(path.node) || '', position);
|
|
709
|
+
}
|
|
710
|
+
else {
|
|
711
|
+
// @ts-ignore
|
|
712
|
+
const { line, column } = ((_l = (_k = path.node) === null || _k === void 0 ? void 0 : _k.position) === null || _l === void 0 ? void 0 : _l.start) || { line: 0, column: 0 };
|
|
713
|
+
const position = { col: column, row: line };
|
|
714
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] getWXS - getRegExp 函数暂不支持传入非字符串类型的参数 ${(0, utils_1.getLineBreak)()}`);
|
|
715
|
+
throw new utils_1.IReportError('getRegExp 函数暂不支持传入非字符串类型的参数', 'GetRegExpParameterTypeError', 'WXML_FILE', (0, utils_1.astToCode)(path.node) || '', position);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
else {
|
|
719
|
+
const newExpr = t.newExpression(t.identifier('RegExp'), []);
|
|
720
|
+
path.replaceWith(newExpr);
|
|
721
|
+
}
|
|
323
722
|
}
|
|
324
|
-
|
|
723
|
+
// wxs标签中getDate()转换为new Date()
|
|
724
|
+
if (t.isIdentifier(path.node.callee, { name: 'getDate' })) {
|
|
725
|
+
let argument = [];
|
|
726
|
+
let newDate;
|
|
727
|
+
const date = path.node.arguments[0];
|
|
728
|
+
if (t.isStringLiteral(date)) {
|
|
729
|
+
argument = path.node.arguments.map((item) => { var _a; return t.stringLiteral((_a = item.extra) === null || _a === void 0 ? void 0 : _a.rawValue); });
|
|
730
|
+
newDate = t.newExpression(t.identifier('Date'), [...argument]);
|
|
731
|
+
}
|
|
732
|
+
else if (t.isNumericLiteral(date)) {
|
|
733
|
+
argument = path.node.arguments.map((item) => { var _a; return t.numericLiteral((_a = item.extra) === null || _a === void 0 ? void 0 : _a.rawValue); });
|
|
734
|
+
newDate = t.newExpression(t.identifier('Date'), [...argument]);
|
|
735
|
+
}
|
|
736
|
+
else {
|
|
737
|
+
newDate = t.newExpression(t.identifier('Date'), []);
|
|
738
|
+
}
|
|
739
|
+
path.replaceWith(newDate);
|
|
740
|
+
}
|
|
741
|
+
},
|
|
325
742
|
});
|
|
326
743
|
imports.push({
|
|
327
744
|
ast,
|
|
328
745
|
name: moduleName,
|
|
329
|
-
wxs: true
|
|
746
|
+
wxs: true,
|
|
330
747
|
});
|
|
331
748
|
}
|
|
332
749
|
if (!moduleName || !src) {
|
|
333
|
-
|
|
750
|
+
// @ts-ignore
|
|
751
|
+
const { line, column } = ((_f = (_e = path.node) === null || _e === void 0 ? void 0 : _e.position) === null || _f === void 0 ? void 0 : _f.start) || { line: 0, column: 0 };
|
|
752
|
+
const position = { col: column, row: line };
|
|
753
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] getWXS - wxs 未同时存在 wxs、src 两个属性 ${(0, utils_1.getLineBreak)()}`);
|
|
754
|
+
throw new utils_1.IReportError('一个 wxs 需要同时存在两个属性:`module`, `src`', 'WxsTagAttributesMissingError', 'WXML_FILE', (0, utils_1.astToCode)(path.node) || '', position);
|
|
334
755
|
}
|
|
335
756
|
path.remove();
|
|
336
757
|
return {
|
|
337
758
|
module: moduleName,
|
|
338
|
-
src
|
|
759
|
+
src,
|
|
339
760
|
};
|
|
340
761
|
}
|
|
341
762
|
function hydrate(file) {
|
|
@@ -344,9 +765,7 @@ function hydrate(file) {
|
|
|
344
765
|
const jsx = ast.expression;
|
|
345
766
|
if (jsx.children.length === 1) {
|
|
346
767
|
const children = jsx.children[0];
|
|
347
|
-
return t.isJSXExpressionContainer(children)
|
|
348
|
-
? children.expression
|
|
349
|
-
: children;
|
|
768
|
+
return t.isJSXExpressionContainer(children) ? children.expression : children;
|
|
350
769
|
}
|
|
351
770
|
else {
|
|
352
771
|
return jsx;
|
|
@@ -354,16 +773,21 @@ function hydrate(file) {
|
|
|
354
773
|
}
|
|
355
774
|
}
|
|
356
775
|
function transformLoop(name, attr, jsx, value) {
|
|
776
|
+
var _a, _b;
|
|
357
777
|
const jsxElement = jsx.get('openingElement');
|
|
358
778
|
if (!jsxElement.node) {
|
|
359
779
|
return;
|
|
360
780
|
}
|
|
361
|
-
const attrs = jsxElement.get('attributes').map(a => a.node);
|
|
362
|
-
const wxForItem = attrs.find(a => a.name.name === exports.WX_FOR_ITEM);
|
|
363
|
-
const hasSinglewxForItem = wxForItem && wxForItem.value && t.isJSXExpressionContainer(wxForItem.value);
|
|
781
|
+
const attrs = jsxElement.get('attributes').map((a) => a.node);
|
|
782
|
+
const wxForItem = attrs.find((a) => t.isJSXAttribute(a) && a.name.name === exports.WX_FOR_ITEM);
|
|
783
|
+
const hasSinglewxForItem = wxForItem && t.isJSXAttribute(wxForItem) && wxForItem.value && t.isJSXExpressionContainer(wxForItem.value);
|
|
364
784
|
if (hasSinglewxForItem || name === exports.WX_FOR || name === 'wx:for-items') {
|
|
365
785
|
if (!value || !t.isJSXExpressionContainer(value)) {
|
|
366
|
-
|
|
786
|
+
// @ts-ignore
|
|
787
|
+
const { line, column } = ((_b = (_a = jsx.node) === null || _a === void 0 ? void 0 : _a.position) === null || _b === void 0 ? void 0 : _b.start) || { line: 0, column: 0 };
|
|
788
|
+
const position = { col: column, row: line };
|
|
789
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] transformLoop - wx:for 的值未用 "{{}}" 包裹 ${(0, utils_1.getLineBreak)()}`);
|
|
790
|
+
throw new utils_1.IReportError('wx:for 的值必须使用 "{{}}" 包裹', 'WxForValueFormatError', 'WXML_FILE', (0, utils_1.astToCode)(jsx.node) || '', position);
|
|
367
791
|
}
|
|
368
792
|
attr.remove();
|
|
369
793
|
let item = t.stringLiteral('item');
|
|
@@ -371,18 +795,27 @@ function transformLoop(name, attr, jsx, value) {
|
|
|
371
795
|
jsx
|
|
372
796
|
.get('openingElement')
|
|
373
797
|
.get('attributes')
|
|
374
|
-
.forEach(p => {
|
|
798
|
+
.forEach((p) => {
|
|
799
|
+
var _a, _b, _c, _d;
|
|
375
800
|
const node = p.node;
|
|
376
801
|
if (node.name.name === exports.WX_FOR_ITEM) {
|
|
377
802
|
if (!node.value || !t.isStringLiteral(node.value)) {
|
|
378
|
-
|
|
803
|
+
// @ts-ignore
|
|
804
|
+
const { line, column } = ((_b = (_a = jsx.node) === null || _a === void 0 ? void 0 : _a.position) === null || _b === void 0 ? void 0 : _b.start) || { line: 0, column: 0 };
|
|
805
|
+
const position = { col: column, row: line };
|
|
806
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] transformLoop - ${exports.WX_FOR_ITEM} 的值不是一个字符串 ${(0, utils_1.getLineBreak)()}`);
|
|
807
|
+
throw new utils_1.IReportError(exports.WX_FOR_ITEM + ' 的值必须是一个字符串', 'WxForItemValueError', 'WXML_FILE', (0, utils_1.astToCode)(jsx.node) || '', position);
|
|
379
808
|
}
|
|
380
809
|
item = node.value;
|
|
381
810
|
p.remove();
|
|
382
811
|
}
|
|
383
812
|
if (node.name.name === exports.WX_FOR_INDEX) {
|
|
384
813
|
if (!node.value || !t.isStringLiteral(node.value)) {
|
|
385
|
-
|
|
814
|
+
// @ts-ignore
|
|
815
|
+
const { line, column } = ((_d = (_c = jsx.node) === null || _c === void 0 ? void 0 : _c.position) === null || _d === void 0 ? void 0 : _d.start) || { line: 0, column: 0 };
|
|
816
|
+
const position = { col: column, row: line };
|
|
817
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] transformLoop - ${exports.WX_FOR_INDEX} 的值不是一个字符串 ${(0, utils_1.getLineBreak)()}`);
|
|
818
|
+
throw new utils_1.IReportError(exports.WX_FOR_INDEX + ' 的值必须是一个字符串', 'WxForIndexValueError', 'WXML_FILE', (0, utils_1.astToCode)(jsx.node) || '', position);
|
|
386
819
|
}
|
|
387
820
|
index = node.value;
|
|
388
821
|
p.remove();
|
|
@@ -391,19 +824,50 @@ function transformLoop(name, attr, jsx, value) {
|
|
|
391
824
|
jsx
|
|
392
825
|
.get('openingElement')
|
|
393
826
|
.get('attributes')
|
|
394
|
-
.forEach(p => {
|
|
827
|
+
.forEach((p) => {
|
|
395
828
|
const node = p.node;
|
|
396
|
-
if (node.name.name === exports.WX_KEY
|
|
397
|
-
|
|
398
|
-
|
|
829
|
+
if (node.name.name === exports.WX_KEY) {
|
|
830
|
+
node.name = t.jSXIdentifier('key');
|
|
831
|
+
if (t.isStringLiteral(node.value)) {
|
|
832
|
+
if (node.value.value === '*this') {
|
|
833
|
+
node.value = t.jSXExpressionContainer(t.identifier(item.value));
|
|
834
|
+
}
|
|
835
|
+
else if (node.value.value === 'index') {
|
|
836
|
+
// index表示item在数组里的下标, 并不是item的某个property, 单独抽出来处理
|
|
837
|
+
node.value = t.jSXExpressionContainer(t.identifier(node.value.value));
|
|
838
|
+
}
|
|
839
|
+
else {
|
|
840
|
+
node.value = t.jSXExpressionContainer(t.memberExpression(t.identifier(item.value), t.identifier(node.value.value)));
|
|
841
|
+
}
|
|
399
842
|
}
|
|
400
|
-
|
|
401
|
-
|
|
843
|
+
}
|
|
844
|
+
});
|
|
845
|
+
jsx
|
|
846
|
+
.get('openingElement')
|
|
847
|
+
.get('attributes')
|
|
848
|
+
.forEach((p) => {
|
|
849
|
+
const node = p.node;
|
|
850
|
+
if (node.name.name === exports.WX_IF) {
|
|
851
|
+
// 如果同时使用了 wx:if,分离
|
|
852
|
+
const ifBlock = (0, utils_1.buildBlockElement)();
|
|
853
|
+
ifBlock.children = [(0, lodash_1.cloneDeep)(jsx.node)];
|
|
854
|
+
try {
|
|
855
|
+
jsx.replaceWith(ifBlock);
|
|
856
|
+
}
|
|
857
|
+
catch (error) {
|
|
858
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] transformLoop - wx:if和wx:for合用时父组件使用wx:if导致使用replaceWith异常 ${(0, utils_1.getLineBreak)()}${error} ${(0, utils_1.getLineBreak)()}`);
|
|
859
|
+
// jsx外层是wx:if的转换,替换(replaceWith)时会抛出异常
|
|
860
|
+
// catch异常后,正常替换
|
|
402
861
|
}
|
|
862
|
+
p.remove();
|
|
403
863
|
}
|
|
404
864
|
});
|
|
865
|
+
if (t.isJSXEmptyExpression(value.expression)) {
|
|
866
|
+
(0, helper_1.printLog)("warning" /* processTypeEnum.WARNING */, 'value.expression', 'wxml.ts -> t.isJSXEmptyExpression(value.expression)');
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
405
869
|
const replacement = t.jSXExpressionContainer(t.callExpression(t.memberExpression(value.expression, t.identifier('map')), [
|
|
406
|
-
t.arrowFunctionExpression([t.identifier(item.value), t.identifier(index.value)], t.blockStatement([t.returnStatement(jsx.node)]))
|
|
870
|
+
t.arrowFunctionExpression([t.identifier(item.value), t.identifier(index.value)], t.blockStatement([t.returnStatement(jsx.node)])),
|
|
407
871
|
]));
|
|
408
872
|
const block = (0, utils_1.buildBlockElement)();
|
|
409
873
|
block.children = [replacement];
|
|
@@ -411,31 +875,47 @@ function transformLoop(name, attr, jsx, value) {
|
|
|
411
875
|
jsx.replaceWith(block);
|
|
412
876
|
}
|
|
413
877
|
catch (error) {
|
|
878
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] transformLoop - 节点替换异常 ${(0, utils_1.getLineBreak)()}${error} ${(0, utils_1.getLineBreak)()}`);
|
|
414
879
|
//
|
|
415
880
|
}
|
|
416
881
|
return {
|
|
417
882
|
item: item.value,
|
|
418
|
-
index: index.value
|
|
883
|
+
index: index.value,
|
|
419
884
|
};
|
|
420
885
|
}
|
|
421
886
|
}
|
|
422
887
|
function transformIf(name, attr, jsx, value) {
|
|
888
|
+
var _a, _b;
|
|
423
889
|
if (name !== exports.WX_IF) {
|
|
424
890
|
return;
|
|
425
891
|
}
|
|
426
|
-
if (jsx.node.openingElement.attributes.some(a => a.name.name === 'slot')) {
|
|
892
|
+
if (jsx.node.openingElement.attributes.some((a) => t.isJSXAttribute(a) && a.name.name === 'slot')) {
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
895
|
+
// 考虑到wx:if和wx:for的优先级,如果同时使用,先解析wx:for
|
|
896
|
+
if (jsx.node.openingElement.attributes.some((a) => t.isJSXAttribute(a) && (a.name.name === 'wx:for' || a.name.name === 'wx:for-items'))) {
|
|
427
897
|
return;
|
|
428
898
|
}
|
|
429
899
|
const conditions = [];
|
|
430
900
|
let siblings = [];
|
|
431
901
|
try {
|
|
432
|
-
siblings = jsx
|
|
902
|
+
siblings = jsx
|
|
903
|
+
.getAllNextSiblings()
|
|
904
|
+
.filter((s) => !(s.isJSXExpressionContainer() && t.isJSXEmptyExpression(s.get('expression'))));
|
|
433
905
|
}
|
|
434
906
|
catch (error) {
|
|
907
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] transformIf - 节点过滤异常 ${(0, utils_1.getLineBreak)()}${error} ${(0, utils_1.getLineBreak)()}`);
|
|
435
908
|
return;
|
|
436
909
|
}
|
|
437
910
|
if (value === null || !t.isJSXExpressionContainer(value)) {
|
|
911
|
+
const cacheNode = (0, lodash_1.cloneDeep)(attr.parentPath.parent);
|
|
912
|
+
const position = {
|
|
913
|
+
col: ((_a = cacheNode.position) === null || _a === void 0 ? void 0 : _a.start.column) || 0,
|
|
914
|
+
row: ((_b = cacheNode.position) === null || _b === void 0 ? void 0 : _b.start.line) || 0,
|
|
915
|
+
};
|
|
916
|
+
(0, utils_1.createErrorCodeMsg)('wxIfValueFormatError', 'wx:if 的值需要用双括号 `{{}}` 包裹它的值', (0, utils_1.astToCode)(cacheNode) || '', global_1.globals.currentParseFile, position);
|
|
438
917
|
console.error('wx:if 的值需要用双括号 `{{}}` 包裹它的值');
|
|
918
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] transformIf - wx:if 的值需要用双括号 {{}} 包裹它的值 ${(0, utils_1.getLineBreak)()}`);
|
|
439
919
|
if (value && t.isStringLiteral(value)) {
|
|
440
920
|
value = t.jSXExpressionContainer((0, utils_1.buildTemplate)(value.value));
|
|
441
921
|
}
|
|
@@ -443,11 +923,13 @@ function transformIf(name, attr, jsx, value) {
|
|
|
443
923
|
conditions.push({
|
|
444
924
|
condition: exports.WX_IF,
|
|
445
925
|
path: jsx,
|
|
446
|
-
tester: value
|
|
926
|
+
tester: value,
|
|
927
|
+
cachePath: (0, lodash_1.cloneDeep)(jsx)
|
|
447
928
|
});
|
|
448
929
|
attr.remove();
|
|
449
930
|
for (let index = 0; index < siblings.length; index++) {
|
|
450
931
|
const sibling = siblings[index];
|
|
932
|
+
const cacheSibling = (0, lodash_1.cloneDeep)(sibling);
|
|
451
933
|
const next = (0, lodash_1.cloneDeep)(siblings[index + 1]);
|
|
452
934
|
const currMatches = findWXIfProps(sibling);
|
|
453
935
|
const nextMatches = findWXIfProps(next);
|
|
@@ -457,7 +939,8 @@ function transformIf(name, attr, jsx, value) {
|
|
|
457
939
|
conditions.push({
|
|
458
940
|
condition: currMatches.reg.input,
|
|
459
941
|
path: sibling,
|
|
460
|
-
tester: currMatches.tester
|
|
942
|
+
tester: currMatches.tester,
|
|
943
|
+
cachePath: cacheSibling
|
|
461
944
|
});
|
|
462
945
|
if (nextMatches === null) {
|
|
463
946
|
break;
|
|
@@ -466,33 +949,48 @@ function transformIf(name, attr, jsx, value) {
|
|
|
466
949
|
handleConditions(conditions);
|
|
467
950
|
}
|
|
468
951
|
function handleConditions(conditions) {
|
|
952
|
+
var _a, _b;
|
|
469
953
|
if (conditions.length === 1) {
|
|
470
954
|
const ct = conditions[0];
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
955
|
+
if (!t.isJSXEmptyExpression(ct.tester.expression)) {
|
|
956
|
+
try {
|
|
957
|
+
ct.path.replaceWith(t.jSXExpressionContainer(t.logicalExpression('&&', ct.tester.expression, (0, lodash_1.cloneDeep)(ct.path.node))));
|
|
958
|
+
}
|
|
959
|
+
catch (error) {
|
|
960
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] handleConditions - 替换节点异常 ${(0, utils_1.getLineBreak)()}${error} ${(0, utils_1.getLineBreak)()}`);
|
|
961
|
+
//
|
|
962
|
+
}
|
|
476
963
|
}
|
|
477
964
|
}
|
|
478
965
|
if (conditions.length > 1) {
|
|
479
966
|
const lastLength = conditions.length - 1;
|
|
480
967
|
const lastCon = conditions[lastLength];
|
|
968
|
+
// 记录当前操作的 condition
|
|
969
|
+
let currentCondition = null;
|
|
481
970
|
let lastAlternate = (0, lodash_1.cloneDeep)(lastCon.path.node);
|
|
482
971
|
try {
|
|
483
|
-
if (lastCon.condition === exports.WX_ELSE_IF) {
|
|
972
|
+
if (lastCon.condition === exports.WX_ELSE_IF && !t.isJSXEmptyExpression(lastCon.tester.expression)) {
|
|
484
973
|
lastAlternate = t.logicalExpression('&&', lastCon.tester.expression, lastAlternate);
|
|
485
974
|
}
|
|
486
|
-
const node = conditions
|
|
487
|
-
|
|
488
|
-
.
|
|
975
|
+
const node = conditions.slice(0, lastLength).reduceRight((acc, condition) => {
|
|
976
|
+
currentCondition = condition;
|
|
977
|
+
if (t.isJSXEmptyExpression(condition.tester.expression)) {
|
|
978
|
+
(0, helper_1.printLog)("warning" /* processTypeEnum.WARNING */, 'condition.tester.expression', 't.isJSXEmptyExpression(condition.tester.expression)');
|
|
979
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] handleConditions - t.isJSXEmptyExpression(condition.tester.expression) ${(0, utils_1.getLineBreak)()}`);
|
|
980
|
+
return null;
|
|
981
|
+
}
|
|
489
982
|
return t.conditionalExpression(condition.tester.expression, (0, lodash_1.cloneDeep)(condition.path.node), acc);
|
|
490
983
|
}, lastAlternate);
|
|
491
|
-
|
|
492
|
-
|
|
984
|
+
if (node != null) {
|
|
985
|
+
conditions[0].path.replaceWith(t.jSXExpressionContainer(node));
|
|
986
|
+
conditions.slice(1).forEach((c) => c.path.remove());
|
|
987
|
+
}
|
|
493
988
|
}
|
|
494
989
|
catch (error) {
|
|
495
|
-
|
|
990
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] handleConditions - wx:elif 转换异常 ${(0, utils_1.getLineBreak)()}${error} ${(0, utils_1.getLineBreak)()}`);
|
|
991
|
+
const { line, column } = ((_b = (_a = currentCondition.cachePath.node) === null || _a === void 0 ? void 0 : _a.position) === null || _b === void 0 ? void 0 : _b.start) || { line: 0, column: 0 };
|
|
992
|
+
const position = { col: column, row: line };
|
|
993
|
+
throw new utils_1.IReportError('属性转换错误 wx:elif 的值需要用双括号 `{{}}` 包裹它的值', 'wxElifValueFormatError', 'WXML_FILE', (0, utils_1.astToCode)(currentCondition.cachePath.node) || '', position);
|
|
496
994
|
}
|
|
497
995
|
}
|
|
498
996
|
}
|
|
@@ -503,9 +1001,9 @@ function findWXIfProps(jsx) {
|
|
|
503
1001
|
jsx
|
|
504
1002
|
.get('openingElement')
|
|
505
1003
|
.get('attributes')
|
|
506
|
-
.some(path => {
|
|
1004
|
+
.some((path) => {
|
|
507
1005
|
const attr = path.node;
|
|
508
|
-
if (t.isJSXIdentifier(attr.name)) {
|
|
1006
|
+
if (t.isJSXIdentifier(attr.name) && attr != null) {
|
|
509
1007
|
const name = attr.name.name;
|
|
510
1008
|
if (name === exports.WX_IF) {
|
|
511
1009
|
return true;
|
|
@@ -515,7 +1013,7 @@ function findWXIfProps(jsx) {
|
|
|
515
1013
|
path.remove();
|
|
516
1014
|
matches = {
|
|
517
1015
|
reg: match,
|
|
518
|
-
tester: attr.value
|
|
1016
|
+
tester: attr.value,
|
|
519
1017
|
};
|
|
520
1018
|
return true;
|
|
521
1019
|
}
|
|
@@ -525,20 +1023,25 @@ function findWXIfProps(jsx) {
|
|
|
525
1023
|
return matches;
|
|
526
1024
|
}
|
|
527
1025
|
function parseNode(node, tagName) {
|
|
1026
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] parseNode - 入参 ${(0, utils_1.getLineBreak)()}tagName: ${tagName} ${(0, utils_1.getLineBreak)()}`);
|
|
528
1027
|
if (node.type === NodeType.Text) {
|
|
529
1028
|
return parseText(node, tagName);
|
|
530
1029
|
}
|
|
531
1030
|
else if (node.type === NodeType.Comment) {
|
|
532
1031
|
const emptyStatement = t.jSXEmptyExpression();
|
|
533
|
-
emptyStatement.innerComments = [
|
|
1032
|
+
emptyStatement.innerComments = [
|
|
1033
|
+
{
|
|
534
1034
|
type: 'CommentBlock',
|
|
535
|
-
value: ' ' + node.content + ' '
|
|
536
|
-
}
|
|
537
|
-
|
|
1035
|
+
value: ' ' + node.content + ' ',
|
|
1036
|
+
},
|
|
1037
|
+
];
|
|
1038
|
+
const jsxExpressionContainer = t.jSXExpressionContainer(emptyStatement);
|
|
1039
|
+
return (0, utils_1.addLocInfo)(jsxExpressionContainer, node);
|
|
538
1040
|
}
|
|
539
1041
|
return parseElement(node);
|
|
540
1042
|
}
|
|
541
1043
|
function parseElement(element) {
|
|
1044
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] parseElement - 进入函数 ${(0, utils_1.getLineBreak)()}`);
|
|
542
1045
|
const tagName = t.jSXIdentifier(global_1.THIRD_PARTY_COMPONENTS.has(element.tagName) ? element.tagName : allCamelCase(element.tagName));
|
|
543
1046
|
if (utils_1.DEFAULT_Component_SET.has(tagName.name)) {
|
|
544
1047
|
global_1.usedComponents.add(tagName.name);
|
|
@@ -546,7 +1049,7 @@ function parseElement(element) {
|
|
|
546
1049
|
let attributes = element.attributes;
|
|
547
1050
|
if (tagName.name === 'Template') {
|
|
548
1051
|
let isSpread = false;
|
|
549
|
-
attributes = attributes.map(attr => {
|
|
1052
|
+
attributes = attributes.map((attr) => {
|
|
550
1053
|
if (attr.key === 'data') {
|
|
551
1054
|
const value = attr.value || '';
|
|
552
1055
|
const content = parseContent(value);
|
|
@@ -562,9 +1065,9 @@ function parseElement(element) {
|
|
|
562
1065
|
// (...a) => {{a}}
|
|
563
1066
|
attr.value = `{{${str.slice(4, strLastIndex)}}}`;
|
|
564
1067
|
}
|
|
565
|
-
else if (/^\(([A-Za-z]+)\)$/.test(str)) {
|
|
1068
|
+
else if (/^\(([A-Za-z,\s]+)\)$/.test(str)) {
|
|
566
1069
|
// (a) => {{a:a}}
|
|
567
|
-
attr.value = `{{${str.replace(
|
|
1070
|
+
attr.value = `{{${str.slice(1, strLastIndex).replace(/([A-Za-z]+)/g, '$1:$1')}}}`;
|
|
568
1071
|
}
|
|
569
1072
|
else {
|
|
570
1073
|
// (a:'a') => {{a:'a'}}
|
|
@@ -581,41 +1084,56 @@ function parseElement(element) {
|
|
|
581
1084
|
if (isSpread) {
|
|
582
1085
|
attributes.push({
|
|
583
1086
|
key: 'spread',
|
|
584
|
-
value: null
|
|
1087
|
+
value: null,
|
|
585
1088
|
});
|
|
586
1089
|
}
|
|
587
1090
|
}
|
|
588
|
-
return t.jSXElement(
|
|
1091
|
+
// return t.jSXElement(
|
|
1092
|
+
// t.jSXOpeningElement(tagName, attributes.map(parseAttribute)),
|
|
1093
|
+
// t.jSXClosingElement(tagName),
|
|
1094
|
+
// removeEmptyTextAndComment(element.children).map((el) => parseNode(el, element.tagName)),
|
|
1095
|
+
// false
|
|
1096
|
+
// )
|
|
1097
|
+
const jSXElement = t.jSXElement(t.jSXOpeningElement(tagName, attributes.map(parseAttribute)), t.jSXClosingElement(tagName), removeEmptyTextAndComment(element.children).map((el) => parseNode(el, element.tagName)), false);
|
|
1098
|
+
return (0, utils_1.addLocInfo)(jSXElement, element);
|
|
589
1099
|
}
|
|
590
|
-
function
|
|
591
|
-
return nodes
|
|
592
|
-
|
|
1100
|
+
function removeEmptyTextAndComment(nodes) {
|
|
1101
|
+
return nodes
|
|
1102
|
+
.filter((node) => {
|
|
1103
|
+
return (node.type === NodeType.Element ||
|
|
593
1104
|
(node.type === NodeType.Text && node.content.trim().length !== 0) ||
|
|
594
|
-
node.type === NodeType.Comment;
|
|
595
|
-
})
|
|
1105
|
+
node.type === NodeType.Comment);
|
|
1106
|
+
})
|
|
1107
|
+
.filter((node, index) => !(index === 0 && node.type === NodeType.Comment));
|
|
596
1108
|
}
|
|
597
|
-
exports.
|
|
1109
|
+
exports.removeEmptyTextAndComment = removeEmptyTextAndComment;
|
|
598
1110
|
function parseText(node, tagName) {
|
|
1111
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] parseText - 进入函数 ${(0, utils_1.getLineBreak)()}`);
|
|
599
1112
|
if (tagName === 'wxs') {
|
|
600
|
-
return t.jSXText(node.content)
|
|
1113
|
+
// return t.jSXText(node.content)
|
|
1114
|
+
return (0, utils_1.addLocInfo)(t.jSXText(node.content), node);
|
|
601
1115
|
}
|
|
602
1116
|
const { type, content } = parseContent(node.content);
|
|
603
1117
|
if (type === 'raw') {
|
|
604
1118
|
const text = content.replace(/([{}]+)/g, "{'$1'}");
|
|
605
|
-
return t.jSXText(text)
|
|
1119
|
+
// return t.jSXText(text)
|
|
1120
|
+
return (0, utils_1.addLocInfo)(t.jSXText(text), node);
|
|
606
1121
|
}
|
|
607
|
-
return t.jSXExpressionContainer(
|
|
1122
|
+
// return t.jSXExpressionContainer(buildTemplate(content))
|
|
1123
|
+
return (0, utils_1.addLocInfo)(t.jSXExpressionContainer((0, utils_1.buildTemplate)(content)), node);
|
|
608
1124
|
}
|
|
1125
|
+
// 匹配{{content}}
|
|
609
1126
|
const handlebarsRE = /\{\{((?:.|\n)+?)\}\}/g;
|
|
610
1127
|
function singleQuote(s) {
|
|
611
1128
|
return `'${s}'`;
|
|
612
1129
|
}
|
|
613
1130
|
function parseContent(content, single = false) {
|
|
1131
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] parseContent - 进入函数 ${(0, utils_1.getLineBreak)()}`);
|
|
614
1132
|
content = content.trim();
|
|
615
1133
|
if (!handlebarsRE.test(content)) {
|
|
616
1134
|
return {
|
|
617
1135
|
type: 'raw',
|
|
618
|
-
content
|
|
1136
|
+
content,
|
|
619
1137
|
};
|
|
620
1138
|
}
|
|
621
1139
|
const tokens = [];
|
|
@@ -641,22 +1159,85 @@ function parseContent(content, single = false) {
|
|
|
641
1159
|
}
|
|
642
1160
|
return {
|
|
643
1161
|
type: 'expression',
|
|
644
|
-
content: tokens.join('+')
|
|
1162
|
+
content: tokens.join('+'),
|
|
645
1163
|
};
|
|
646
1164
|
}
|
|
647
1165
|
exports.parseContent = parseContent;
|
|
1166
|
+
/**
|
|
1167
|
+
* 判断 style 中的属性是否都是 attrName: attrValue 格式
|
|
1168
|
+
*
|
|
1169
|
+
* @param styleAttrsMap
|
|
1170
|
+
*/
|
|
1171
|
+
function isAllKeyValueFormat(styleAttrsMap) {
|
|
1172
|
+
// 匹配 attrName: attrValue 格式
|
|
1173
|
+
const isKeyValueFormat = /^(([A-Za-z-]+)\s*):(\s*).*/;
|
|
1174
|
+
const filterStyleAttrs = styleAttrsMap.filter((attr) => attr.trim() !== '');
|
|
1175
|
+
const isStringAttr = filterStyleAttrs.every((attr) => isKeyValueFormat.test(attr.trim()));
|
|
1176
|
+
return isStringAttr;
|
|
1177
|
+
}
|
|
1178
|
+
/**
|
|
1179
|
+
* 解析内联style属性
|
|
1180
|
+
*
|
|
1181
|
+
* @param key 内联属性的类型
|
|
1182
|
+
* @param value 内联属性的值
|
|
1183
|
+
* @returns
|
|
1184
|
+
*/
|
|
1185
|
+
function parseStyle(key, value) {
|
|
1186
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] parseStyle - 入参 ${(0, utils_1.getLineBreak)()}key: ${key} ${(0, utils_1.getLineBreak)()}value: ${value} ${(0, utils_1.getLineBreak)()}`);
|
|
1187
|
+
const styleAttrs = value.trim().split(';');
|
|
1188
|
+
// 针对attrName: attrValue 格式做转换处理, 其他类型采用'+'连接符
|
|
1189
|
+
if (isAllKeyValueFormat(styleAttrs)) {
|
|
1190
|
+
const attrKeyValueMap = [];
|
|
1191
|
+
parseStyleAttrs(styleAttrs, attrKeyValueMap);
|
|
1192
|
+
convertStyleAttrs(attrKeyValueMap);
|
|
1193
|
+
const objectLiteral = t.objectExpression(attrKeyValueMap.map((attr) => t.objectProperty(t.identifier(attr.attrName), attr.value)));
|
|
1194
|
+
return t.jSXAttribute(t.jSXIdentifier(key), t.jsxExpressionContainer(objectLiteral));
|
|
1195
|
+
}
|
|
1196
|
+
else {
|
|
1197
|
+
return parseContent(value);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
exports.parseStyle = parseStyle;
|
|
648
1201
|
function parseAttribute(attr) {
|
|
1202
|
+
(0, utils_1.updateLogFileContent)(`INFO [taroize] parseAttribute - 入参 ${(0, utils_1.getLineBreak)()}attr: ${JSON.stringify(attr)} ${(0, utils_1.getLineBreak)()}`);
|
|
649
1203
|
let { key, value } = attr;
|
|
650
1204
|
let jsxValue = null;
|
|
1205
|
+
let type = '';
|
|
1206
|
+
let content = '';
|
|
651
1207
|
if (value) {
|
|
1208
|
+
const cacheValue = value;
|
|
652
1209
|
if (key === 'class' && value.startsWith('[') && value.endsWith(']')) {
|
|
653
1210
|
value = value.slice(1, value.length - 1).replace(',', '');
|
|
1211
|
+
(0, utils_1.createErrorCodeMsg)('unsupportedClassArray', 'Taro/React 不支持 class 传入数组,此写法可能无法得到正确的 class', `class=${JSON.stringify(cacheValue).replace(/"/g, "'")}`, global_1.globals.currentParseFile);
|
|
1212
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] parseAttribute - Taro/React 不支持 class 传入数组,此写法可能无法得到正确的 class ${(0, utils_1.getLineBreak)()}`);
|
|
654
1213
|
// eslint-disable-next-line no-console
|
|
655
1214
|
console.log((0, utils_1.codeFrameError)(attr, 'Taro/React 不支持 class 传入数组,此写法可能无法得到正确的 class'));
|
|
656
1215
|
}
|
|
657
|
-
|
|
1216
|
+
value = convertStyleUnit(value);
|
|
1217
|
+
// 判断属性是否为style属性
|
|
1218
|
+
if (key === 'style' && value) {
|
|
1219
|
+
try {
|
|
1220
|
+
const styleParseReslut = parseStyle(key, value);
|
|
1221
|
+
if (t.isJSXAttribute(styleParseReslut)) {
|
|
1222
|
+
return styleParseReslut;
|
|
1223
|
+
}
|
|
1224
|
+
else {
|
|
1225
|
+
content = styleParseReslut.content;
|
|
1226
|
+
type = styleParseReslut.type;
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
catch (error) {
|
|
1230
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] parseAttribute - 属性 style="${value}" 解析异常 ${(0, utils_1.getLineBreak)()}${error} ${(0, utils_1.getLineBreak)()}`);
|
|
1231
|
+
throw new utils_1.IReportError(`属性解析失败 style="${value}"解析失败,${error}`, 'StyleAttributeParsingError', 'WXML_FILE', `style="${value}"`);
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
else {
|
|
1235
|
+
const parseContentResult = parseContent(value);
|
|
1236
|
+
content = parseContentResult.content;
|
|
1237
|
+
type = parseContentResult.type;
|
|
1238
|
+
}
|
|
658
1239
|
if (type === 'raw') {
|
|
659
|
-
jsxValue = t.stringLiteral(content.replace(/"/g, '
|
|
1240
|
+
jsxValue = t.stringLiteral(content.replace(/"/g, "'"));
|
|
660
1241
|
}
|
|
661
1242
|
else {
|
|
662
1243
|
let expr;
|
|
@@ -671,27 +1252,33 @@ function parseAttribute(attr) {
|
|
|
671
1252
|
expr = t.stringLiteral('');
|
|
672
1253
|
}
|
|
673
1254
|
else {
|
|
674
|
-
|
|
1255
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] parseAttribute - 模板参数转换异常 ${(0, utils_1.getLineBreak)()}${err} ${(0, utils_1.getLineBreak)()}`);
|
|
1256
|
+
throw new utils_1.IReportError(err, 'TemplateParameterConversionError', 'WXML_FILE', `${key}: ${value}`);
|
|
675
1257
|
}
|
|
676
1258
|
}
|
|
677
|
-
else if (content.includes(':') ||
|
|
678
|
-
const file = (0,
|
|
1259
|
+
else if (content.includes(':') || content.includes('...')) {
|
|
1260
|
+
const file = (0, parser_1.parse)(`var a = ${attr.value.slice(1, attr.value.length - 1)}`, {
|
|
1261
|
+
plugins: ['objectRestSpread'],
|
|
1262
|
+
});
|
|
679
1263
|
expr = file.program.body[0].declarations[0].init;
|
|
680
1264
|
}
|
|
681
1265
|
else {
|
|
682
1266
|
const err = `转换模板参数: \`${key}: ${value}\` 报错`;
|
|
683
|
-
|
|
1267
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] parseAttribute - 模板参数转换异常 ${(0, utils_1.getLineBreak)()}${err} ${(0, utils_1.getLineBreak)()}`);
|
|
1268
|
+
throw new utils_1.IReportError(err, 'TemplateParameterConversionError', 'WXML_FILE', `${key}: ${value}`);
|
|
684
1269
|
}
|
|
685
1270
|
}
|
|
686
1271
|
if (t.isThisExpression(expr)) {
|
|
1272
|
+
(0, utils_1.createErrorCodeMsg)('ThisKeywordUsageWarning', '在参数中使用 `this` 可能会造成意想不到的结果,已将此参数修改为 `__placeholder__`,你可以在转换后的代码查找这个关键字修改。', value, global_1.globals.currentParseFile);
|
|
1273
|
+
(0, utils_1.updateLogFileContent)(`WARN [taroize] parseAttribute - 在参数中使用 this 可能会造成意想不到的结果 ${(0, utils_1.getLineBreak)()}`);
|
|
687
1274
|
console.error('在参数中使用 `this` 可能会造成意想不到的结果,已将此参数修改为 `__placeholder__`,你可以在转换后的代码查找这个关键字修改。');
|
|
688
1275
|
expr = t.stringLiteral('__placeholder__');
|
|
689
1276
|
}
|
|
690
1277
|
jsxValue = t.jSXExpressionContainer(expr);
|
|
691
1278
|
}
|
|
692
1279
|
}
|
|
693
|
-
|
|
694
|
-
if (/^on[A-Z]/.test(jsxKey) &&
|
|
1280
|
+
let jsxKey = handleAttrKey(key);
|
|
1281
|
+
if (/^on[A-Z]/.test(jsxKey) && !/^catch/.test(key) && jsxValue && t.isStringLiteral(jsxValue)) {
|
|
695
1282
|
jsxValue = t.jSXExpressionContainer(t.memberExpression(t.thisExpression(), t.identifier(jsxValue.value)));
|
|
696
1283
|
}
|
|
697
1284
|
if (key.startsWith('catch') && value) {
|
|
@@ -700,15 +1287,20 @@ function parseAttribute(attr) {
|
|
|
700
1287
|
global_1.globals.hasCatchTrue = true;
|
|
701
1288
|
}
|
|
702
1289
|
else if (t.isStringLiteral(jsxValue)) {
|
|
703
|
-
jsxValue = t.jSXExpressionContainer(t.
|
|
1290
|
+
jsxValue = t.jSXExpressionContainer(t.memberExpression(t.thisExpression(), t.identifier(jsxValue.value)));
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
// 如果data-xxx自定义属性名xxx不是以-分隔的写法就要转成全小写属性名
|
|
1294
|
+
if (value && jsxKey.startsWith('data-')) {
|
|
1295
|
+
const realKey = jsxKey.replace(/^data-/, '');
|
|
1296
|
+
if (realKey.indexOf('-') === -1) {
|
|
1297
|
+
jsxKey = `data-${realKey.toLowerCase()}`;
|
|
704
1298
|
}
|
|
705
1299
|
}
|
|
706
1300
|
return t.jSXAttribute(t.jSXIdentifier(jsxKey), jsxValue);
|
|
707
1301
|
}
|
|
708
1302
|
function handleAttrKey(key) {
|
|
709
|
-
if (key.startsWith('wx:') ||
|
|
710
|
-
key.startsWith('wx-') ||
|
|
711
|
-
key.startsWith('data-')) {
|
|
1303
|
+
if (key.startsWith('wx:') || key.startsWith('wx-') || key.startsWith('data-')) {
|
|
712
1304
|
return key;
|
|
713
1305
|
}
|
|
714
1306
|
else if (key === 'class') {
|
|
@@ -722,7 +1314,8 @@ function handleAttrKey(key) {
|
|
|
722
1314
|
key = key.replace(/^(bind:|catch:|bind|catch)/, 'on');
|
|
723
1315
|
key = (0, lodash_1.camelCase)(key);
|
|
724
1316
|
if (!(0, utils_1.isValidVarName)(key)) {
|
|
725
|
-
|
|
1317
|
+
(0, utils_1.updateLogFileContent)(`ERROR [taroize] handleAttrKey - ${key} 不是一个有效 JavaScript 变量名 ${(0, utils_1.getLineBreak)()}`);
|
|
1318
|
+
throw new utils_1.IReportError(`属性名"${key}" 不是一个有效 JavaScript 变量名`, 'InvalidVariableNameError', 'WXML_FILE', `${key}`);
|
|
726
1319
|
}
|
|
727
1320
|
return key.substr(0, 2) + key[2].toUpperCase() + key.substr(3);
|
|
728
1321
|
}
|