mp-weixin-back 0.0.16 → 0.0.18
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/dist/index.cjs +599 -482
- package/dist/index.d.cts +32 -1
- package/dist/index.d.mts +32 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.mjs +599 -482
- package/package.json +15 -4
- package/readme.md +50 -18
- package/.changeset/README.md +0 -8
- package/.changeset/config.json +0 -11
- package/.editorconfig +0 -25
- package/.github/workflows/publish.yml +0 -38
- package/.prettierrc.cjs +0 -8
- package/build.config.ts +0 -12
- package/llms.txt +0 -154
- package/shims-vue.d.ts +0 -6
- package/src/context.ts +0 -78
- package/src/index.ts +0 -79
- package/test/data/index-default.vue +0 -17
- package/test/data/index-setup.vue +0 -14
- package/test/data/index-utils.vue +0 -29
- package/test/generate.spec.ts +0 -64
- package/tsconfig.json +0 -15
- package/types/index.ts +0 -80
- package/utils/constant.ts +0 -2
- package/utils/index.ts +0 -62
- package/utils/walker.ts +0 -523
- package/vite.config.ts +0 -19
package/utils/walker.ts
DELETED
|
@@ -1,523 +0,0 @@
|
|
|
1
|
-
import generate from '@babel/generator'
|
|
2
|
-
import MagicString from 'magic-string'
|
|
3
|
-
import { babelParse, walkAST } from 'ast-kit'
|
|
4
|
-
import { pageContext } from '../src/context'
|
|
5
|
-
import { virtualFileId } from './constant'
|
|
6
|
-
import type {
|
|
7
|
-
WithStatement,
|
|
8
|
-
BlockStatement,
|
|
9
|
-
Statement,
|
|
10
|
-
FunctionExpression,
|
|
11
|
-
Node,
|
|
12
|
-
ObjectExpression,
|
|
13
|
-
ObjectMethod,
|
|
14
|
-
ObjectProperty,
|
|
15
|
-
} from '@babel/types'
|
|
16
|
-
|
|
17
|
-
const pageContainerComp =
|
|
18
|
-
' <page-container :show="__MP_BACK_SHOW_PAGE_CONTAINER__" :overlay="false" @beforeleave="onBeforeLeave" :z-index="1" :duration="false"></page-container>\n'
|
|
19
|
-
|
|
20
|
-
function isArrowFunction(func: Function) {
|
|
21
|
-
if (typeof func !== 'function') return false
|
|
22
|
-
return !func.hasOwnProperty('prototype') && func.toString().includes('=>')
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function compositionWalk(context: pageContext, code: string, sfc: any, id: string) {
|
|
26
|
-
const codeMs = new MagicString(code)
|
|
27
|
-
const setupAst = babelParse(sfc.scriptSetup!.loc.source, sfc.scriptSetup!.lang)
|
|
28
|
-
|
|
29
|
-
let pageInfo = {
|
|
30
|
-
hasPageBack: false,
|
|
31
|
-
pageBackFnName: 'onPageBack',
|
|
32
|
-
hasImportRef: false,
|
|
33
|
-
backConfig: { ...context.config },
|
|
34
|
-
onPageBackBodyAst: [] as Statement[],
|
|
35
|
-
onPageBackCallNodeToRemove: null as Node | null,
|
|
36
|
-
activeFnName: 'activeMpBack',
|
|
37
|
-
inActiveFnName: 'inactiveMpBack',
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const activeFnCallsToModify: any[] = []
|
|
41
|
-
const inActiveFnCallsToModify: any[] = []
|
|
42
|
-
|
|
43
|
-
if (setupAst) {
|
|
44
|
-
walkAST<Node>(setupAst, {
|
|
45
|
-
enter(node) {
|
|
46
|
-
if (node.type === 'ImportDeclaration') {
|
|
47
|
-
if (node.source.value.includes(virtualFileId)) {
|
|
48
|
-
const importDefaultSpecifiers = node.specifiers.filter(
|
|
49
|
-
(i) => i.type === 'ImportDefaultSpecifier'
|
|
50
|
-
)
|
|
51
|
-
const importDefaultSpecifier = importDefaultSpecifiers[0]
|
|
52
|
-
pageInfo.hasPageBack = true
|
|
53
|
-
pageInfo.pageBackFnName = importDefaultSpecifier.local.name
|
|
54
|
-
|
|
55
|
-
const importSpecifiers = node.specifiers.filter((i) => i.type === 'ImportSpecifier')
|
|
56
|
-
importSpecifiers.map((specifiers) => {
|
|
57
|
-
if (
|
|
58
|
-
specifiers.imported.type === 'Identifier' &&
|
|
59
|
-
specifiers.imported.name === 'activeMpBack'
|
|
60
|
-
) {
|
|
61
|
-
pageInfo.activeFnName = specifiers.local.name
|
|
62
|
-
}
|
|
63
|
-
if (
|
|
64
|
-
specifiers.imported.type === 'Identifier' &&
|
|
65
|
-
specifiers.imported.name === 'inactiveMpBack'
|
|
66
|
-
) {
|
|
67
|
-
pageInfo.inActiveFnName = specifiers.local.name
|
|
68
|
-
}
|
|
69
|
-
})
|
|
70
|
-
}
|
|
71
|
-
if (node.source.value === 'vue') {
|
|
72
|
-
node.specifiers.some((specifier) => {
|
|
73
|
-
if (specifier.local.name === 'ref') {
|
|
74
|
-
pageInfo.hasImportRef = true
|
|
75
|
-
return true
|
|
76
|
-
}
|
|
77
|
-
return false
|
|
78
|
-
})
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (
|
|
83
|
-
node.type === 'ExpressionStatement' &&
|
|
84
|
-
node.expression.type === 'CallExpression' &&
|
|
85
|
-
node.expression.callee.loc?.identifierName === pageInfo.pageBackFnName
|
|
86
|
-
) {
|
|
87
|
-
// 记录下整个 onPageBack(...) 语句节点,以便后续移除
|
|
88
|
-
pageInfo.onPageBackCallNodeToRemove = node
|
|
89
|
-
const callback = node.expression.arguments[0]
|
|
90
|
-
const backArguments = node.expression.arguments[1]
|
|
91
|
-
|
|
92
|
-
if (backArguments?.type === 'ObjectExpression') {
|
|
93
|
-
const config = new Function(
|
|
94
|
-
// @ts-ignore
|
|
95
|
-
`return (${(generate.default ? generate.default : generate)(backArguments).code});`
|
|
96
|
-
)()
|
|
97
|
-
Object.assign(pageInfo.backConfig, config)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (
|
|
101
|
-
callback &&
|
|
102
|
-
(callback.type === 'ArrowFunctionExpression' || callback.type === 'FunctionExpression')
|
|
103
|
-
) {
|
|
104
|
-
pageInfo.onPageBackBodyAst = callback.body.body
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// 跳过此节点的子节点遍历,因为我们将手动处理其内部逻辑
|
|
108
|
-
return
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (
|
|
112
|
-
node.type === 'ExpressionStatement' &&
|
|
113
|
-
node.expression.type === 'CallExpression' &&
|
|
114
|
-
node.expression.callee.loc?.identifierName === pageInfo.activeFnName
|
|
115
|
-
) {
|
|
116
|
-
activeFnCallsToModify.push({
|
|
117
|
-
start: node.expression.start,
|
|
118
|
-
end: node.expression.end,
|
|
119
|
-
original: sfc.scriptSetup!.loc.source.substring(
|
|
120
|
-
node.expression.start,
|
|
121
|
-
node.expression.end
|
|
122
|
-
),
|
|
123
|
-
name: pageInfo.activeFnName,
|
|
124
|
-
})
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (
|
|
128
|
-
node.type === 'ExpressionStatement' &&
|
|
129
|
-
node.expression.type === 'CallExpression' &&
|
|
130
|
-
node.expression.callee.loc?.identifierName === pageInfo.inActiveFnName
|
|
131
|
-
) {
|
|
132
|
-
inActiveFnCallsToModify.push({
|
|
133
|
-
start: node.expression.start,
|
|
134
|
-
end: node.expression.end,
|
|
135
|
-
original: sfc.scriptSetup!.loc.source.substring(
|
|
136
|
-
node.expression.start,
|
|
137
|
-
node.expression.end
|
|
138
|
-
),
|
|
139
|
-
name: pageInfo.inActiveFnName,
|
|
140
|
-
})
|
|
141
|
-
}
|
|
142
|
-
},
|
|
143
|
-
})
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// 没有引入mp-weixin-back-helper
|
|
147
|
-
if (!pageInfo.hasPageBack) return code
|
|
148
|
-
|
|
149
|
-
if (pageInfo.onPageBackCallNodeToRemove) {
|
|
150
|
-
const scriptSetupOffset = sfc.scriptSetup!.loc.start.offset
|
|
151
|
-
const nodeToRemove = pageInfo.onPageBackCallNodeToRemove as any
|
|
152
|
-
const globalStart = scriptSetupOffset + nodeToRemove.start
|
|
153
|
-
const globalEnd = scriptSetupOffset + nodeToRemove.end
|
|
154
|
-
codeMs.remove(globalStart, globalEnd)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
let callbackCode = ''
|
|
158
|
-
if (pageInfo.onPageBackBodyAst.length > 0) {
|
|
159
|
-
// 包装成一个临时的 AST 根节点以供遍历
|
|
160
|
-
const tempAstRoot = {
|
|
161
|
-
type: 'BlockStatement',
|
|
162
|
-
body: pageInfo.onPageBackBodyAst,
|
|
163
|
-
} as WithStatement
|
|
164
|
-
|
|
165
|
-
walkAST(tempAstRoot, {
|
|
166
|
-
enter(node: any) {
|
|
167
|
-
if (node.type === 'CallExpression' && node.callee.type === 'Identifier') {
|
|
168
|
-
const createIdentifier = (name: string) => ({ type: 'Identifier', name })
|
|
169
|
-
|
|
170
|
-
if (node.callee.name === pageInfo.activeFnName) {
|
|
171
|
-
node.arguments.unshift(createIdentifier('__MP_WEIXIN_ACTIVEBACK__'))
|
|
172
|
-
} else if (node.callee.name === pageInfo.inActiveFnName) {
|
|
173
|
-
node.arguments.unshift(createIdentifier('__MP_WEIXIN_INACTIVEBACK__'))
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
callbackCode = pageInfo.onPageBackBodyAst
|
|
180
|
-
// @ts-ignore
|
|
181
|
-
.map((statement) => (generate.default ? generate.default : generate)(statement).code)
|
|
182
|
-
.join('\n')
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (code.includes('<page-container')) {
|
|
186
|
-
context.log.debugLog(`${context.getPageById(id)}页面已有page-container组件,注入失败`)
|
|
187
|
-
return code
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (!pageInfo.backConfig.preventDefault) {
|
|
191
|
-
callbackCode += 'uni.navigateBack({ delta: 1 });'
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const importUseMpWeixinBack = `import { useMpWeixinBack } from '${virtualFileId}'`
|
|
195
|
-
const importRefFromVue = !pageInfo.hasImportRef ? `import { ref } from 'vue'` : ''
|
|
196
|
-
const stateFrequency = 'let __MP_BACK_FREQUENCY__ = 1;'
|
|
197
|
-
|
|
198
|
-
const statePageContainerVar = `
|
|
199
|
-
const { __MP_BACK_SHOW_PAGE_CONTAINER__, __MP_WEIXIN_ACTIVEBACK__, __MP_WEIXIN_INACTIVEBACK__ } = useMpWeixinBack(${pageInfo.backConfig.initialValue})
|
|
200
|
-
`
|
|
201
|
-
|
|
202
|
-
// 获取传入插件的统一方法
|
|
203
|
-
const configBack = (() => {
|
|
204
|
-
const onPageBack = pageInfo.backConfig.onPageBack
|
|
205
|
-
if (!onPageBack) return ''
|
|
206
|
-
if (typeof onPageBack !== 'function') {
|
|
207
|
-
throw new Error('`onPageBack` must be a function')
|
|
208
|
-
}
|
|
209
|
-
const params = JSON.stringify({ page: context.getPageById(id) })
|
|
210
|
-
if (isArrowFunction(onPageBack) || onPageBack.toString().includes('function')) {
|
|
211
|
-
return `(${onPageBack})(${params});`
|
|
212
|
-
}
|
|
213
|
-
return `(function ${onPageBack})()`
|
|
214
|
-
})()
|
|
215
|
-
|
|
216
|
-
const stateBeforeLeave = `
|
|
217
|
-
const onBeforeLeave = () => {
|
|
218
|
-
if (!__MP_BACK_SHOW_PAGE_CONTAINER__.value) {
|
|
219
|
-
return
|
|
220
|
-
}
|
|
221
|
-
if (__MP_BACK_FREQUENCY__ < ${pageInfo.backConfig.frequency}) {
|
|
222
|
-
__MP_BACK_SHOW_PAGE_CONTAINER__.value = false
|
|
223
|
-
setTimeout(() => __MP_BACK_SHOW_PAGE_CONTAINER__.value = true, 0);
|
|
224
|
-
__MP_BACK_FREQUENCY__++
|
|
225
|
-
}
|
|
226
|
-
${configBack}
|
|
227
|
-
${callbackCode}
|
|
228
|
-
};
|
|
229
|
-
`
|
|
230
|
-
const { template, scriptSetup } = sfc
|
|
231
|
-
|
|
232
|
-
// template标签中插入page-container组件
|
|
233
|
-
const tempOffsets = {
|
|
234
|
-
start: template.loc.start.offset,
|
|
235
|
-
end: template.loc.end.offset,
|
|
236
|
-
content: template.content,
|
|
237
|
-
}
|
|
238
|
-
const templateMagicString = new MagicString(tempOffsets.content)
|
|
239
|
-
templateMagicString.append(pageContainerComp)
|
|
240
|
-
codeMs.overwrite(tempOffsets.start, tempOffsets.end, templateMagicString.toString())
|
|
241
|
-
|
|
242
|
-
// script标签中插入声明的变量和方法
|
|
243
|
-
const scriptOffsets = {
|
|
244
|
-
start: scriptSetup.loc.start.offset,
|
|
245
|
-
end: scriptSetup.loc.end.offset,
|
|
246
|
-
content: scriptSetup.content || '',
|
|
247
|
-
}
|
|
248
|
-
const scriptMagicString = new MagicString(scriptOffsets.content)
|
|
249
|
-
scriptMagicString.prepend(
|
|
250
|
-
` ${importRefFromVue}
|
|
251
|
-
${importUseMpWeixinBack}
|
|
252
|
-
${stateFrequency}
|
|
253
|
-
${statePageContainerVar}
|
|
254
|
-
${stateBeforeLeave} `
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
// 应用 activeMpBack 调用的修改
|
|
258
|
-
activeFnCallsToModify.forEach((call) => {
|
|
259
|
-
// 使用正则匹配函数调用结构,确保我们只修改括号内的内容
|
|
260
|
-
const fnCallRegex = new RegExp(`${call.name}\\(([^)]*)\\)`, 'g')
|
|
261
|
-
const newCall = call.original.replace(fnCallRegex, (_match: any, args: string) => {
|
|
262
|
-
// 如果原调用没有参数
|
|
263
|
-
if (!args.trim()) {
|
|
264
|
-
return `${call.name}(__MP_WEIXIN_ACTIVEBACK__)`
|
|
265
|
-
}
|
|
266
|
-
// 如果有参数,添加新参数
|
|
267
|
-
return `${call.name}(__MP_WEIXIN_ACTIVEBACK__, ${args})`
|
|
268
|
-
})
|
|
269
|
-
|
|
270
|
-
scriptMagicString.overwrite(call.start, call.end, newCall)
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
inActiveFnCallsToModify.forEach((call) => {
|
|
274
|
-
// 使用正则匹配函数调用结构,确保我们只修改括号内的内容
|
|
275
|
-
const fnCallRegex = new RegExp(`${call.name}\\(([^)]*)\\)`, 'g')
|
|
276
|
-
const newCall = call.original.replace(fnCallRegex, (_match: any, args: string) => {
|
|
277
|
-
// 如果原调用没有参数
|
|
278
|
-
if (!args.trim()) {
|
|
279
|
-
return `${call.name}(__MP_WEIXIN_INACTIVEBACK__)`
|
|
280
|
-
}
|
|
281
|
-
// 如果有参数,添加新参数
|
|
282
|
-
return `${call.name}(__MP_WEIXIN_INACTIVEBACK__, ${args})`
|
|
283
|
-
})
|
|
284
|
-
|
|
285
|
-
scriptMagicString.overwrite(call.start, call.end, newCall)
|
|
286
|
-
})
|
|
287
|
-
|
|
288
|
-
codeMs.overwrite(scriptOffsets.start, scriptOffsets.end, scriptMagicString.toString())
|
|
289
|
-
|
|
290
|
-
return codeMs.toString()
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
function optionsWalk(context: pageContext, code: string, sfc: any, id: string) {
|
|
294
|
-
const codeMs = new MagicString(code)
|
|
295
|
-
const ast = babelParse(sfc.script.loc.source, sfc.script.lang)
|
|
296
|
-
|
|
297
|
-
let pageInfo = {
|
|
298
|
-
hasPageBack: false,
|
|
299
|
-
pageBackFnName: 'onPageBack',
|
|
300
|
-
backConfig: { ...context.config },
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
let exportDefaultNode: ObjectExpression | null = null
|
|
304
|
-
let dataMethodNode: BlockStatement | null = null
|
|
305
|
-
let methodsNode: ObjectExpression | null = null
|
|
306
|
-
let onPageBackNodeMethod: ObjectMethod | null = null
|
|
307
|
-
let onPageBackNodeProperty: ObjectProperty | null = null
|
|
308
|
-
|
|
309
|
-
if (ast) {
|
|
310
|
-
walkAST<Node>(ast, {
|
|
311
|
-
enter(node) {
|
|
312
|
-
// todo需要判断使用默认选项式还是使用了setup
|
|
313
|
-
if (
|
|
314
|
-
node.type === 'ExportDefaultDeclaration' &&
|
|
315
|
-
node.declaration.type === 'ObjectExpression'
|
|
316
|
-
) {
|
|
317
|
-
exportDefaultNode = node.declaration
|
|
318
|
-
const properties = node.declaration.properties
|
|
319
|
-
|
|
320
|
-
for (let i = 0; i < properties.length; i++) {
|
|
321
|
-
const element = properties[i]
|
|
322
|
-
// export default 的 data()
|
|
323
|
-
if (
|
|
324
|
-
element.type === 'ObjectMethod' &&
|
|
325
|
-
element.key.type === 'Identifier' &&
|
|
326
|
-
element.key.name === 'data' &&
|
|
327
|
-
element.body.type === 'BlockStatement'
|
|
328
|
-
) {
|
|
329
|
-
dataMethodNode = element.body
|
|
330
|
-
}
|
|
331
|
-
// export default 的 methods
|
|
332
|
-
if (
|
|
333
|
-
element.type === 'ObjectProperty' &&
|
|
334
|
-
element.key.type === 'Identifier' &&
|
|
335
|
-
element.key.name === 'methods'
|
|
336
|
-
) {
|
|
337
|
-
methodsNode = element.value as ObjectExpression
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
// 获取export default 的 onPackBack
|
|
341
|
-
const blockStatementCondition =
|
|
342
|
-
element.type === 'ObjectMethod' &&
|
|
343
|
-
element.key.type === 'Identifier' &&
|
|
344
|
-
element.key.name === pageInfo.pageBackFnName &&
|
|
345
|
-
element.body.type === 'BlockStatement'
|
|
346
|
-
|
|
347
|
-
const functionExpressionCondition =
|
|
348
|
-
element.type === 'ObjectProperty' &&
|
|
349
|
-
element.key.type === 'Identifier' &&
|
|
350
|
-
element.key.name === pageInfo.pageBackFnName &&
|
|
351
|
-
element.value.type === 'FunctionExpression'
|
|
352
|
-
|
|
353
|
-
if (blockStatementCondition) {
|
|
354
|
-
pageInfo.hasPageBack = true
|
|
355
|
-
onPageBackNodeMethod = element
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
if (functionExpressionCondition) {
|
|
359
|
-
pageInfo.hasPageBack = true
|
|
360
|
-
onPageBackNodeProperty = element
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
},
|
|
365
|
-
})
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
if (!pageInfo.hasPageBack) return
|
|
369
|
-
|
|
370
|
-
const newDataProperty = [
|
|
371
|
-
{
|
|
372
|
-
type: 'ObjectProperty',
|
|
373
|
-
key: { type: 'Identifier', name: '__MP_BACK_SHOW_PAGE_CONTAINER__' },
|
|
374
|
-
value: { type: 'BooleanLiteral', value: true },
|
|
375
|
-
computed: false,
|
|
376
|
-
shorthand: false,
|
|
377
|
-
},
|
|
378
|
-
{
|
|
379
|
-
type: 'ObjectProperty',
|
|
380
|
-
key: { type: 'Identifier', name: '__MP_BACK_FREQUENCY__' },
|
|
381
|
-
value: { type: 'NumericLiteral', value: 1 },
|
|
382
|
-
computed: false,
|
|
383
|
-
shorthand: false,
|
|
384
|
-
},
|
|
385
|
-
] as ObjectProperty[]
|
|
386
|
-
if (dataMethodNode) {
|
|
387
|
-
const returnStatement = (dataMethodNode as BlockStatement).body.find(
|
|
388
|
-
(node) => node.type === 'ReturnStatement'
|
|
389
|
-
)
|
|
390
|
-
if (
|
|
391
|
-
returnStatement &&
|
|
392
|
-
returnStatement.argument &&
|
|
393
|
-
returnStatement.argument.type === 'ObjectExpression'
|
|
394
|
-
) {
|
|
395
|
-
// 添加新的属性
|
|
396
|
-
returnStatement.argument.properties.push(...newDataProperty)
|
|
397
|
-
}
|
|
398
|
-
} else if (exportDefaultNode) {
|
|
399
|
-
const addData: ObjectMethod = {
|
|
400
|
-
type: 'ObjectMethod',
|
|
401
|
-
key: { type: 'Identifier', name: 'data' },
|
|
402
|
-
kind: 'method',
|
|
403
|
-
params: [],
|
|
404
|
-
async: false,
|
|
405
|
-
generator: false,
|
|
406
|
-
computed: false,
|
|
407
|
-
body: {
|
|
408
|
-
type: 'BlockStatement',
|
|
409
|
-
directives: [],
|
|
410
|
-
body: [
|
|
411
|
-
{
|
|
412
|
-
type: 'ReturnStatement',
|
|
413
|
-
argument: {
|
|
414
|
-
type: 'ObjectExpression',
|
|
415
|
-
properties: newDataProperty,
|
|
416
|
-
},
|
|
417
|
-
},
|
|
418
|
-
],
|
|
419
|
-
},
|
|
420
|
-
}
|
|
421
|
-
;(exportDefaultNode as ObjectExpression).properties.push(addData)
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// 获取传入插件的统一方法
|
|
425
|
-
const configBack = (() => {
|
|
426
|
-
const onPageBack = pageInfo.backConfig.onPageBack
|
|
427
|
-
if (!onPageBack) return ''
|
|
428
|
-
if (typeof onPageBack !== 'function') {
|
|
429
|
-
throw new Error('`onPageBack` must be a function')
|
|
430
|
-
}
|
|
431
|
-
const params = JSON.stringify({ page: context.getPageById(id) })
|
|
432
|
-
if (isArrowFunction(onPageBack) || onPageBack.toString().includes('function')) {
|
|
433
|
-
return `(${onPageBack})(${params});`
|
|
434
|
-
}
|
|
435
|
-
return `(function ${onPageBack})()`
|
|
436
|
-
})()
|
|
437
|
-
|
|
438
|
-
const stateBeforeLeave = `
|
|
439
|
-
function onBeforeLeave() {
|
|
440
|
-
if (this.__MP_BACK_FREQUENCY__ < ${pageInfo.backConfig.frequency}) {
|
|
441
|
-
this.__MP_BACK_SHOW_PAGE_CONTAINER__ = false
|
|
442
|
-
setTimeout(() => { this.__MP_BACK_SHOW_PAGE_CONTAINER__ = true }, 0);
|
|
443
|
-
this.__MP_BACK_FREQUENCY__++
|
|
444
|
-
}
|
|
445
|
-
${configBack}
|
|
446
|
-
${!pageInfo.backConfig.preventDefault ? 'uni.navigateBack({ delta: 1 });' : ''}
|
|
447
|
-
};
|
|
448
|
-
`
|
|
449
|
-
const stateBeforeLeaveAst = babelParse(stateBeforeLeave)
|
|
450
|
-
const stateBeforeLeaveNode = stateBeforeLeaveAst.body.find(
|
|
451
|
-
(node) => node.type === 'FunctionDeclaration'
|
|
452
|
-
)
|
|
453
|
-
const newMethodsProperty = {
|
|
454
|
-
type: 'ObjectMethod',
|
|
455
|
-
key: {
|
|
456
|
-
type: 'Identifier',
|
|
457
|
-
name: 'onBeforeLeave',
|
|
458
|
-
},
|
|
459
|
-
kind: 'method',
|
|
460
|
-
generator: false,
|
|
461
|
-
async: false,
|
|
462
|
-
params: [],
|
|
463
|
-
computed: false,
|
|
464
|
-
body: {
|
|
465
|
-
type: 'BlockStatement',
|
|
466
|
-
directives: [],
|
|
467
|
-
body: [
|
|
468
|
-
...(onPageBackNodeMethod ? (onPageBackNodeMethod as ObjectMethod)!.body.body : []),
|
|
469
|
-
...(onPageBackNodeProperty
|
|
470
|
-
? ((onPageBackNodeProperty as ObjectProperty)!.value as FunctionExpression).body.body
|
|
471
|
-
: []),
|
|
472
|
-
...stateBeforeLeaveNode!.body.body,
|
|
473
|
-
],
|
|
474
|
-
},
|
|
475
|
-
} as ObjectMethod
|
|
476
|
-
if (methodsNode) {
|
|
477
|
-
;(methodsNode as ObjectExpression).properties.push(newMethodsProperty)
|
|
478
|
-
} else if (exportDefaultNode) {
|
|
479
|
-
const addMethods: ObjectProperty = {
|
|
480
|
-
type: 'ObjectProperty',
|
|
481
|
-
computed: false,
|
|
482
|
-
shorthand: false,
|
|
483
|
-
key: {
|
|
484
|
-
type: 'Identifier',
|
|
485
|
-
name: 'methods',
|
|
486
|
-
},
|
|
487
|
-
value: {
|
|
488
|
-
type: 'ObjectExpression',
|
|
489
|
-
properties: [newMethodsProperty],
|
|
490
|
-
},
|
|
491
|
-
}
|
|
492
|
-
;(exportDefaultNode as ObjectExpression).properties.push(addMethods)
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
const { template, script } = sfc
|
|
496
|
-
|
|
497
|
-
// template标签中插入page-container组件
|
|
498
|
-
const tempOffsets = {
|
|
499
|
-
start: template.loc.start.offset,
|
|
500
|
-
end: template.loc.end.offset,
|
|
501
|
-
content: template.content,
|
|
502
|
-
}
|
|
503
|
-
const templateMagicString = new MagicString(tempOffsets.content)
|
|
504
|
-
templateMagicString.append(pageContainerComp)
|
|
505
|
-
codeMs.overwrite(tempOffsets.start, tempOffsets.end, templateMagicString.toString())
|
|
506
|
-
|
|
507
|
-
// script标签中插入声明的变量和方法
|
|
508
|
-
const scriptOffsets = {
|
|
509
|
-
start: script.loc.start.offset,
|
|
510
|
-
end: script.loc.end.offset,
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
// @ts-ignore
|
|
514
|
-
const newScriptContent = (generate.default ? generate.default : generate)(ast).code
|
|
515
|
-
codeMs.overwrite(scriptOffsets.start, scriptOffsets.end, newScriptContent)
|
|
516
|
-
|
|
517
|
-
return codeMs.toString()
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
export const vueWalker = {
|
|
521
|
-
compositionWalk,
|
|
522
|
-
optionsWalk,
|
|
523
|
-
}
|
package/vite.config.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vite'
|
|
2
|
-
import vue from '@vitejs/plugin-vue'
|
|
3
|
-
import mpBack from './dist/index.mjs'
|
|
4
|
-
|
|
5
|
-
export default defineConfig({
|
|
6
|
-
plugins: [
|
|
7
|
-
mpBack(),
|
|
8
|
-
vue({
|
|
9
|
-
template: {
|
|
10
|
-
compilerOptions: {
|
|
11
|
-
isCustomElement: (tag) => tag.startsWith('page-') || tag.startsWith('mp-'),
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
}),
|
|
15
|
-
],
|
|
16
|
-
test: {
|
|
17
|
-
environment: 'happy-dom',
|
|
18
|
-
},
|
|
19
|
-
})
|