@mpxjs/webpack-plugin 2.9.14 → 2.9.15
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/index.js
CHANGED
|
@@ -169,7 +169,7 @@ class MpxWebpackPlugin {
|
|
|
169
169
|
options.webConfig = options.webConfig || {}
|
|
170
170
|
options.partialCompile = options.mode !== 'web' && options.partialCompile
|
|
171
171
|
options.asyncSubpackageRules = options.asyncSubpackageRules || []
|
|
172
|
-
options.optimizeRenderRules = options.optimizeRenderRules
|
|
172
|
+
options.optimizeRenderRules = options.optimizeRenderRules ? (Array.isArray(options.optimizeRenderRules) ? options.optimizeRenderRules : [options.optimizeRenderRules]) : []
|
|
173
173
|
options.retryRequireAsync = options.retryRequireAsync || false
|
|
174
174
|
options.enableAliRequireAsync = options.enableAliRequireAsync || false
|
|
175
175
|
options.optimizeSize = options.optimizeSize || false
|
|
@@ -32,7 +32,7 @@ function checkBindThis (path) {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
// 计算访问路径
|
|
35
|
-
function
|
|
35
|
+
function getCollectPath (path) {
|
|
36
36
|
let current = path.parentPath
|
|
37
37
|
let last = path
|
|
38
38
|
let keyPath = '' + path.node.name
|
|
@@ -75,7 +75,7 @@ function checkDelAndGetPath (path) {
|
|
|
75
75
|
let replace = false
|
|
76
76
|
|
|
77
77
|
// 确定删除路径
|
|
78
|
-
while (!t.isBlockStatement(current)) {
|
|
78
|
+
while (!t.isBlockStatement(current) && !t.isProgram(current)) {
|
|
79
79
|
// case: !!a
|
|
80
80
|
if (t.isUnaryExpression(current.parent) && current.key === 'argument') {
|
|
81
81
|
delPath = current.parentPath
|
|
@@ -113,7 +113,7 @@ function checkDelAndGetPath (path) {
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
// 确定是否可删除
|
|
116
|
-
while (!t.isBlockStatement(current) &&
|
|
116
|
+
while (!t.isBlockStatement(current) && !t.isProgram(current)) {
|
|
117
117
|
const { key, listKey, parent } = current
|
|
118
118
|
|
|
119
119
|
if (t.isIfStatement(parent) && key === 'test') {
|
|
@@ -121,12 +121,12 @@ function checkDelAndGetPath (path) {
|
|
|
121
121
|
break
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
if (listKey === 'arguments'
|
|
124
|
+
if (t.isCallExpression(parent) && listKey === 'arguments') {
|
|
125
125
|
canDel = false
|
|
126
126
|
break
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
if (
|
|
129
|
+
if (t.isMemberExpression(parent) && parent.computed) {
|
|
130
130
|
if (key === 'property') {
|
|
131
131
|
replace = true
|
|
132
132
|
} else {
|
|
@@ -155,7 +155,7 @@ function checkDelAndGetPath (path) {
|
|
|
155
155
|
replace = true // 不能break,case: if (a + b) {}
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
if (key === 'value'
|
|
158
|
+
if (t.isObjectProperty(parent) && key === 'value') { // ({ name: a })
|
|
159
159
|
replace = true
|
|
160
160
|
}
|
|
161
161
|
|
|
@@ -172,15 +172,16 @@ function checkDelAndGetPath (path) {
|
|
|
172
172
|
|
|
173
173
|
// 判断前缀是否存在(只判断前缀,全等的情况,会返回false)
|
|
174
174
|
function checkPrefix (keys, key) {
|
|
175
|
-
for (
|
|
176
|
-
|
|
177
|
-
if (key === str) continue
|
|
178
|
-
// 确保判断当前标识是完整的单词
|
|
179
|
-
if (key.startsWith(str) && (key[str.length] === '.' || key[str.length] === '[')) return true
|
|
175
|
+
for (const item of keys) {
|
|
176
|
+
if (checkBIsPrefixOfA(key, item)) return true
|
|
180
177
|
}
|
|
181
178
|
return false
|
|
182
179
|
}
|
|
183
180
|
|
|
181
|
+
function checkBIsPrefixOfA (a, b) {
|
|
182
|
+
return a.startsWith(b) && (a[b.length] === '.' || a[b.length] === '[')
|
|
183
|
+
}
|
|
184
|
+
|
|
184
185
|
function dealRemove (path, replace) {
|
|
185
186
|
try {
|
|
186
187
|
if (replace) {
|
|
@@ -195,10 +196,75 @@ function dealRemove (path, replace) {
|
|
|
195
196
|
}
|
|
196
197
|
delete path.needBind
|
|
197
198
|
delete path.collectInfo
|
|
198
|
-
} catch (e) {
|
|
199
|
+
} catch (e) {
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function isSimpleKey (key) {
|
|
204
|
+
return !/[[.]/.test(key)
|
|
199
205
|
}
|
|
200
206
|
|
|
201
207
|
module.exports = {
|
|
208
|
+
transformSimple (code, {
|
|
209
|
+
ignoreMap = {}
|
|
210
|
+
}) {
|
|
211
|
+
const ast = babylon.parse(code, {
|
|
212
|
+
plugins: [
|
|
213
|
+
'objectRestSpread'
|
|
214
|
+
]
|
|
215
|
+
})
|
|
216
|
+
const collectKeySet = new Set()
|
|
217
|
+
const propKeySet = new Set()
|
|
218
|
+
let isProps = false
|
|
219
|
+
const visitor = {
|
|
220
|
+
// 标记收集props数据
|
|
221
|
+
CallExpression: {
|
|
222
|
+
enter (path) {
|
|
223
|
+
const callee = path.node.callee
|
|
224
|
+
if (
|
|
225
|
+
t.isMemberExpression(callee) &&
|
|
226
|
+
t.isThisExpression(callee.object) &&
|
|
227
|
+
(callee.property.name === '_p' || callee.property.value === '_p')
|
|
228
|
+
) {
|
|
229
|
+
isProps = true
|
|
230
|
+
path.isProps = true
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
exit (path) {
|
|
234
|
+
if (path.isProps) {
|
|
235
|
+
isProps = false
|
|
236
|
+
delete path.isProps
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
Identifier (path) {
|
|
241
|
+
if (
|
|
242
|
+
checkBindThis(path) &&
|
|
243
|
+
!ignoreMap[path.node.name] &&
|
|
244
|
+
!path.scope.hasBinding(path.node.name)
|
|
245
|
+
) {
|
|
246
|
+
if (isProps) {
|
|
247
|
+
propKeySet.add(path.node.name)
|
|
248
|
+
}
|
|
249
|
+
const { keyPath } = getCollectPath(path)
|
|
250
|
+
collectKeySet.add(keyPath)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
traverse(ast, visitor)
|
|
255
|
+
const collectKeys = [...collectKeySet]
|
|
256
|
+
const pCollectKeys = collectKeys.filter((keyA) => {
|
|
257
|
+
return collectKeys.every((keyB) => {
|
|
258
|
+
return !checkBIsPrefixOfA(keyA, keyB)
|
|
259
|
+
})
|
|
260
|
+
})
|
|
261
|
+
return {
|
|
262
|
+
code: pCollectKeys.map((key) => {
|
|
263
|
+
return isSimpleKey(key) ? `_sc(${JSON.stringify(key)});` : `_c(${JSON.stringify(key)});`
|
|
264
|
+
}).join('\n'),
|
|
265
|
+
propKeys: [...propKeySet]
|
|
266
|
+
}
|
|
267
|
+
},
|
|
202
268
|
transform (code, {
|
|
203
269
|
needCollect = false,
|
|
204
270
|
renderReduce = false,
|
|
@@ -213,22 +279,25 @@ module.exports = {
|
|
|
213
279
|
let currentBlock = null
|
|
214
280
|
const bindingsMap = new Map()
|
|
215
281
|
|
|
216
|
-
const
|
|
282
|
+
const propKeySet = new Set()
|
|
217
283
|
let isProps = false
|
|
218
284
|
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
currentBlock = path
|
|
227
|
-
},
|
|
228
|
-
exit (path) {
|
|
229
|
-
currentBlock = bindingsMap.get(path).parent
|
|
230
|
-
}
|
|
285
|
+
const blockCollectVisitor = {
|
|
286
|
+
enter (path) { // 收集作用域下所有变量(keyPath)
|
|
287
|
+
bindingsMap.set(path, {
|
|
288
|
+
parent: currentBlock,
|
|
289
|
+
bindings: {}
|
|
290
|
+
})
|
|
291
|
+
currentBlock = path
|
|
231
292
|
},
|
|
293
|
+
exit (path) {
|
|
294
|
+
currentBlock = bindingsMap.get(path).parent
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const collectVisitor = {
|
|
299
|
+
Program: blockCollectVisitor,
|
|
300
|
+
BlockStatement: blockCollectVisitor,
|
|
232
301
|
Identifier (path) {
|
|
233
302
|
if (
|
|
234
303
|
checkBindThis(path) &&
|
|
@@ -248,12 +317,12 @@ module.exports = {
|
|
|
248
317
|
}
|
|
249
318
|
return
|
|
250
319
|
}
|
|
251
|
-
const { last, keyPath } = calPropName(path)
|
|
252
320
|
path.needBind = true
|
|
321
|
+
const { last, keyPath } = getCollectPath(path)
|
|
253
322
|
if (needCollect) {
|
|
254
323
|
last.collectInfo = {
|
|
255
324
|
key: t.stringLiteral(keyPath),
|
|
256
|
-
isSimple:
|
|
325
|
+
isSimple: isSimpleKey(keyPath)
|
|
257
326
|
}
|
|
258
327
|
}
|
|
259
328
|
|
|
@@ -281,18 +350,21 @@ module.exports = {
|
|
|
281
350
|
}
|
|
282
351
|
}
|
|
283
352
|
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
currentBlock = path
|
|
291
|
-
},
|
|
292
|
-
exit (path) {
|
|
293
|
-
currentBlock = bindingsMap.get(path).parent
|
|
294
|
-
}
|
|
353
|
+
const blockBindVisitor = {
|
|
354
|
+
enter (path) {
|
|
355
|
+
const scope = bindingsMap.get(path)
|
|
356
|
+
const parentScope = bindingsMap.get(scope.parent)
|
|
357
|
+
scope.pBindings = parentScope ? Object.assign({}, parentScope.bindings, parentScope.pBindings) : {}
|
|
358
|
+
currentBlock = path
|
|
295
359
|
},
|
|
360
|
+
exit (path) {
|
|
361
|
+
currentBlock = bindingsMap.get(path).parent
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const bindVisitor = {
|
|
366
|
+
Program: blockBindVisitor,
|
|
367
|
+
BlockStatement: blockBindVisitor,
|
|
296
368
|
// 标记收集props数据
|
|
297
369
|
CallExpression: {
|
|
298
370
|
enter (path) {
|
|
@@ -350,7 +422,7 @@ module.exports = {
|
|
|
350
422
|
const name = path.node.name
|
|
351
423
|
if (name) { // 确保path没有被删除 且 没有被替换成字符串
|
|
352
424
|
if (isProps) {
|
|
353
|
-
|
|
425
|
+
propKeySet.add(name)
|
|
354
426
|
}
|
|
355
427
|
path.replaceWith(t.memberExpression(t.thisExpression(), path.node))
|
|
356
428
|
}
|
|
@@ -373,11 +445,11 @@ module.exports = {
|
|
|
373
445
|
}
|
|
374
446
|
|
|
375
447
|
traverse(ast, collectVisitor)
|
|
376
|
-
traverse(ast,
|
|
448
|
+
traverse(ast, bindVisitor)
|
|
377
449
|
|
|
378
450
|
return {
|
|
379
451
|
code: generate(ast).code,
|
|
380
|
-
propKeys
|
|
452
|
+
propKeys: [...propKeySet]
|
|
381
453
|
}
|
|
382
454
|
}
|
|
383
455
|
}
|
|
@@ -1933,12 +1933,17 @@ function postProcessTemplate (el) {
|
|
|
1933
1933
|
|
|
1934
1934
|
const isValidMode = makeMap('wx,ali,swan,tt,qq,web,qa,jd,dd,tenon,noMode')
|
|
1935
1935
|
|
|
1936
|
+
function isValidModeP (i) {
|
|
1937
|
+
return isValidMode(i[0] === '_' ? i.slice(1) : i)
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1936
1940
|
const wrapRE = /^\((.*)\)$/
|
|
1937
1941
|
|
|
1938
1942
|
function processAtMode (el) {
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1943
|
+
// 父节点的atMode匹配状态不应该影响子节点,atMode的影响范围应该限制在当前节点本身
|
|
1944
|
+
// if (el.parent && el.parent._atModeStatus) {
|
|
1945
|
+
// el._atModeStatus = el.parent._atModeStatus
|
|
1946
|
+
// }
|
|
1942
1947
|
|
|
1943
1948
|
const attrsListClone = cloneAttrsList(el.attrsList)
|
|
1944
1949
|
attrsListClone.forEach(item => {
|
|
@@ -1972,24 +1977,31 @@ function processAtMode (el) {
|
|
|
1972
1977
|
|
|
1973
1978
|
const modeArr = [...conditionMap.keys()]
|
|
1974
1979
|
|
|
1975
|
-
if (modeArr.every(i =>
|
|
1980
|
+
if (modeArr.every(i => isValidModeP(i))) {
|
|
1976
1981
|
const attrValue = getAndRemoveAttr(el, attrName).val
|
|
1977
1982
|
const replacedAttrName = attrArr.join('@')
|
|
1978
1983
|
const processedAttr = { name: replacedAttrName, value: attrValue }
|
|
1979
1984
|
|
|
1980
|
-
for (
|
|
1985
|
+
for (let [defineMode, defineEnvArr] of conditionMap.entries()) {
|
|
1986
|
+
const isImplicitMode = defineMode[0] === '_'
|
|
1987
|
+
if (isImplicitMode) defineMode = defineMode.slice(1)
|
|
1981
1988
|
if (defineMode === 'noMode' || defineMode === mode) {
|
|
1982
1989
|
// 命中 env 规则(没有定义env 或者定义的envArr包含当前env)
|
|
1983
1990
|
if (!defineEnvArr.length || defineEnvArr.includes(env)) {
|
|
1984
|
-
el._atModeStatus = ''
|
|
1985
1991
|
if (!replacedAttrName) {
|
|
1986
|
-
|
|
1987
|
-
|
|
1992
|
+
if (defineMode === 'noMode' || isImplicitMode) {
|
|
1993
|
+
// 若defineMode 为 noMode 或 implicitMode,则 element 都需要进行规则转换
|
|
1994
|
+
} else {
|
|
1988
1995
|
el._atModeStatus = 'match'
|
|
1989
1996
|
}
|
|
1990
1997
|
} else {
|
|
1991
|
-
|
|
1992
|
-
|
|
1998
|
+
if (defineMode === 'noMode' || isImplicitMode) {
|
|
1999
|
+
// 若defineMode 为 noMode 或 implicitMode,则直接将 attr 挂载回 el,进行规则转换
|
|
2000
|
+
addAttrs(el, [processedAttr])
|
|
2001
|
+
} else {
|
|
2002
|
+
// 如果命中了指定的mode,且当前 mode 不为 noMode 或 implicitMode,则把不需要转换的 attrs 暂存在 noTransAttrs 上,等规则转换后再挂载回去
|
|
2003
|
+
el.noTransAttrs ? el.noTransAttrs.push(processedAttr) : el.noTransAttrs = [processedAttr]
|
|
2004
|
+
}
|
|
1993
2005
|
}
|
|
1994
2006
|
// 命中mode,命中env,完成匹配,直接退出
|
|
1995
2007
|
break
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const compiler = require('./compiler')
|
|
2
|
-
const bindThis = require('./bind-this')
|
|
2
|
+
const bindThis = require('./bind-this')
|
|
3
3
|
const parseRequest = require('../utils/parse-request')
|
|
4
4
|
const { matchCondition } = require('../utils/match-condition')
|
|
5
5
|
const loaderUtils = require('loader-utils')
|
|
@@ -29,6 +29,13 @@ module.exports = function (raw) {
|
|
|
29
29
|
const hasScoped = queryObj.hasScoped
|
|
30
30
|
const moduleId = queryObj.moduleId || 'm' + mpx.pathHash(resourcePath)
|
|
31
31
|
|
|
32
|
+
let optimizeRenderLevel = 0
|
|
33
|
+
for (const rule of optimizeRenderRules) {
|
|
34
|
+
if (matchCondition(resourcePath, rule)) {
|
|
35
|
+
optimizeRenderLevel = rule.level || 1
|
|
36
|
+
break
|
|
37
|
+
}
|
|
38
|
+
}
|
|
32
39
|
const warn = (msg) => {
|
|
33
40
|
this.emitWarning(
|
|
34
41
|
new Error('[template compiler][' + this.resource + ']: ' + msg)
|
|
@@ -93,22 +100,27 @@ global.currentInject = {
|
|
|
93
100
|
|
|
94
101
|
const rawCode = compiler.genNode(ast)
|
|
95
102
|
if (rawCode) {
|
|
96
|
-
|
|
103
|
+
try {
|
|
104
|
+
const ignoreMap = Object.assign({
|
|
105
|
+
_i: true,
|
|
106
|
+
_c: true,
|
|
107
|
+
_sc: true,
|
|
108
|
+
_r: true
|
|
109
|
+
}, meta.wxsModuleMap)
|
|
110
|
+
const bindResult = optimizeRenderLevel === 2
|
|
111
|
+
? bindThis.transformSimple(rawCode, {
|
|
112
|
+
ignoreMap
|
|
113
|
+
})
|
|
114
|
+
: bindThis.transform(rawCode, {
|
|
115
|
+
needCollect: true,
|
|
116
|
+
renderReduce: optimizeRenderLevel === 1,
|
|
117
|
+
ignoreMap
|
|
118
|
+
})
|
|
119
|
+
resultSource += `
|
|
97
120
|
global.currentInject.render = function (_i, _c, _r, _sc) {
|
|
98
|
-
${
|
|
99
|
-
_r();
|
|
121
|
+
${bindResult.code}
|
|
122
|
+
_r(${optimizeRenderLevel === 2 ? 'true' : ''});
|
|
100
123
|
};\n`
|
|
101
|
-
try {
|
|
102
|
-
const bindResult = bindThis(renderCode, {
|
|
103
|
-
needCollect: true,
|
|
104
|
-
renderReduce: matchCondition(resourcePath, optimizeRenderRules),
|
|
105
|
-
ignoreMap: Object.assign({
|
|
106
|
-
_i: true,
|
|
107
|
-
_c: true,
|
|
108
|
-
_r: true
|
|
109
|
-
}, meta.wxsModuleMap)
|
|
110
|
-
})
|
|
111
|
-
resultSource += bindResult.code
|
|
112
124
|
if ((mode === 'tt' || mode === 'swan') && bindResult.propKeys) {
|
|
113
125
|
resultSource += `global.currentInject.propKeys = ${JSON.stringify(bindResult.propKeys)};\n`
|
|
114
126
|
}
|
|
@@ -118,7 +130,7 @@ Invalid render function generated by the template, please check!\n
|
|
|
118
130
|
Template result:
|
|
119
131
|
${result}\n
|
|
120
132
|
Error code:
|
|
121
|
-
${
|
|
133
|
+
${rawCode}
|
|
122
134
|
Error Detail:
|
|
123
135
|
${e.stack}`)
|
|
124
136
|
return result
|
|
@@ -126,7 +138,7 @@ ${e.stack}`)
|
|
|
126
138
|
}
|
|
127
139
|
|
|
128
140
|
if (meta.computed) {
|
|
129
|
-
resultSource += bindThis(`
|
|
141
|
+
resultSource += bindThis.transform(`
|
|
130
142
|
global.currentInject.injectComputed = {
|
|
131
143
|
${meta.computed.join(',')}
|
|
132
144
|
};`).code + '\n'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpxjs/webpack-plugin",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.15",
|
|
4
4
|
"description": "mpx compile core",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mpx"
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
"engines": {
|
|
84
84
|
"node": ">=14.14.0"
|
|
85
85
|
},
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "f3dcf3425dc3e0ad2378b2f35ca020aa9cdd1fb2"
|
|
87
87
|
}
|