mp-weixin-back 0.0.15 → 0.0.17
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/client.d.ts +90 -13
- package/dist/index.cjs +13 -5
- package/dist/index.d.cts +47 -14
- package/dist/index.d.mts +47 -14
- package/dist/index.d.ts +47 -14
- package/dist/index.mjs +13 -5
- package/package.json +29 -9
- package/readme.md +81 -21
- package/.editorconfig +0 -25
- package/.prettierrc.cjs +0 -8
- package/build.config.ts +0 -12
- package/shims-vue.d.ts +0 -6
- package/src/context.ts +0 -74
- 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 -43
- package/utils/constant.ts +0 -2
- package/utils/index.ts +0 -58
- package/utils/walker.ts +0 -523
- package/vite.config.ts +0 -19
package/.editorconfig
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
root = true
|
|
3
|
-
|
|
4
|
-
[*]
|
|
5
|
-
indent_style = space
|
|
6
|
-
# 缩进大小=2
|
|
7
|
-
indent_size = 2
|
|
8
|
-
|
|
9
|
-
end_of_line = lf
|
|
10
|
-
# 字符集=utf-8
|
|
11
|
-
charset = utf-8
|
|
12
|
-
# 删除行尾空格 = 是
|
|
13
|
-
trim_trailing_whitespace = true
|
|
14
|
-
# 插入最后一行=真
|
|
15
|
-
insert_final_newline = true
|
|
16
|
-
|
|
17
|
-
[*.md]
|
|
18
|
-
# 删除行尾空格 = 否
|
|
19
|
-
trim_trailing_whitespace = false
|
|
20
|
-
|
|
21
|
-
[package.json]
|
|
22
|
-
# 缩进样式=空格
|
|
23
|
-
indent_style = space
|
|
24
|
-
# 缩进大小=2
|
|
25
|
-
indent_size = 2
|
package/.prettierrc.cjs
DELETED
package/build.config.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { defineBuildConfig } from 'unbuild'
|
|
2
|
-
|
|
3
|
-
export default defineBuildConfig({
|
|
4
|
-
entries: ['src/index'],
|
|
5
|
-
declaration: true,
|
|
6
|
-
clean: true,
|
|
7
|
-
rollup: {
|
|
8
|
-
emitCJS: true,
|
|
9
|
-
},
|
|
10
|
-
failOnWarn: false,
|
|
11
|
-
externals: ['vite', 'vue', '@babel/generator'],
|
|
12
|
-
})
|
package/shims-vue.d.ts
DELETED
package/src/context.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import fs from 'fs'
|
|
3
|
-
import JSON5 from 'json5'
|
|
4
|
-
import { red, white, green } from 'kolorist'
|
|
5
|
-
import { ContextConfig, PagesJson } from '../types'
|
|
6
|
-
import { transformVueFile } from '../utils'
|
|
7
|
-
|
|
8
|
-
export class pageContext {
|
|
9
|
-
private logPreText = '[mp-weixin-back] : '
|
|
10
|
-
config: ContextConfig
|
|
11
|
-
pages: string[] = []
|
|
12
|
-
log = {
|
|
13
|
-
info: (text: string) => {
|
|
14
|
-
console.log(white(this.logPreText + text))
|
|
15
|
-
},
|
|
16
|
-
error: (text: string) => {
|
|
17
|
-
console.log(red(this.logPreText + text))
|
|
18
|
-
},
|
|
19
|
-
debugLog: (text: string) => {
|
|
20
|
-
if (this.config.mode === 'development' && this.config.debug) {
|
|
21
|
-
console.log(green(this.logPreText + text))
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
constructor(config: ContextConfig) {
|
|
27
|
-
this.config = config
|
|
28
|
-
}
|
|
29
|
-
getPagesJsonPath() {
|
|
30
|
-
const pagesJsonPath = path.join(this.config.root, 'src/pages.json')
|
|
31
|
-
return pagesJsonPath
|
|
32
|
-
}
|
|
33
|
-
// 获取页面配置详情
|
|
34
|
-
async getPagesJsonInfo() {
|
|
35
|
-
const hasPagesJson = fs.existsSync(this.getPagesJsonPath())
|
|
36
|
-
if (!hasPagesJson) return
|
|
37
|
-
try {
|
|
38
|
-
const content = await fs.promises.readFile(this.getPagesJsonPath(), 'utf-8')
|
|
39
|
-
const pagesContent = JSON5.parse(content) as PagesJson
|
|
40
|
-
const { pages, subpackages } = pagesContent
|
|
41
|
-
if (pages) {
|
|
42
|
-
const mainPages = pages.reduce((acc: string[], current) => {
|
|
43
|
-
acc.push(current.path)
|
|
44
|
-
return acc
|
|
45
|
-
}, [])
|
|
46
|
-
this.pages.push(...mainPages)
|
|
47
|
-
}
|
|
48
|
-
if (subpackages) {
|
|
49
|
-
for (let i = 0; i < subpackages.length; i++) {
|
|
50
|
-
const element = subpackages[i]
|
|
51
|
-
const root = element.root
|
|
52
|
-
const subPages = element.pages.reduce((acc: string[], current) => {
|
|
53
|
-
acc.push(`${root}/${current.path}`.replace('//', '/'))
|
|
54
|
-
return acc
|
|
55
|
-
}, [])
|
|
56
|
-
this.pages.push(...subPages)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
} catch (error: unknown) {
|
|
60
|
-
this.log.error('读取pages.json文件失败')
|
|
61
|
-
this.log.debugLog(String(error))
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
// 获取指定id的page
|
|
65
|
-
getPageById(id: string) {
|
|
66
|
-
const path = (id.split('src/')[1] || '').replace('.vue', '')
|
|
67
|
-
// 页面级别
|
|
68
|
-
return this.pages.find((i) => i === path) || null
|
|
69
|
-
}
|
|
70
|
-
async transform(code: string, id: string) {
|
|
71
|
-
const result = await transformVueFile.call(this, code, id)
|
|
72
|
-
return result
|
|
73
|
-
}
|
|
74
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { pageContext } from './context'
|
|
2
|
-
import { virtualFileId } from '../utils/constant'
|
|
3
|
-
import type { Plugin } from 'vite'
|
|
4
|
-
import type { Config, UserOptions } from '../types'
|
|
5
|
-
|
|
6
|
-
function MpBackPlugin(userOptions: UserOptions = {}): Plugin {
|
|
7
|
-
let context: pageContext
|
|
8
|
-
|
|
9
|
-
const defaultOptions: Config = {
|
|
10
|
-
initialValue: true,
|
|
11
|
-
preventDefault: false,
|
|
12
|
-
frequency: 1,
|
|
13
|
-
debug: false,
|
|
14
|
-
}
|
|
15
|
-
const options = { ...defaultOptions, ...userOptions }
|
|
16
|
-
|
|
17
|
-
return {
|
|
18
|
-
name: 'vite-plugin-mp-weixin-back',
|
|
19
|
-
enforce: 'pre',
|
|
20
|
-
configResolved(config) {
|
|
21
|
-
context = new pageContext({ ...options, mode: config.mode, root: config.root })
|
|
22
|
-
},
|
|
23
|
-
buildStart() {
|
|
24
|
-
context.getPagesJsonInfo()
|
|
25
|
-
},
|
|
26
|
-
resolveId(id) {
|
|
27
|
-
if (id === virtualFileId) {
|
|
28
|
-
return virtualFileId
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
load(id) {
|
|
32
|
-
if (id.includes('node_modules')) {
|
|
33
|
-
return
|
|
34
|
-
}
|
|
35
|
-
// 导出一个对象
|
|
36
|
-
if (id === virtualFileId) {
|
|
37
|
-
return `
|
|
38
|
-
import { ref } from 'vue'
|
|
39
|
-
export default function onPageBack() {}
|
|
40
|
-
export function activeMpBack(fn = null) {
|
|
41
|
-
fn?.()
|
|
42
|
-
}
|
|
43
|
-
export function inactiveMpBack(fn = null) {
|
|
44
|
-
fn?.()
|
|
45
|
-
}
|
|
46
|
-
export function useMpWeixinBack(initialValue = true) {
|
|
47
|
-
const __MP_BACK_SHOW_PAGE_CONTAINER__ = ref(initialValue)
|
|
48
|
-
|
|
49
|
-
const __MP_WEIXIN_ACTIVEBACK__ = () => {
|
|
50
|
-
__MP_BACK_SHOW_PAGE_CONTAINER__.value = true
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const __MP_WEIXIN_INACTIVEBACK__ = () => {
|
|
54
|
-
__MP_BACK_SHOW_PAGE_CONTAINER__.value = false
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return {
|
|
58
|
-
__MP_BACK_SHOW_PAGE_CONTAINER__,
|
|
59
|
-
__MP_WEIXIN_ACTIVEBACK__,
|
|
60
|
-
__MP_WEIXIN_INACTIVEBACK__
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
`
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
async transform(code, id) {
|
|
67
|
-
if (id.includes('node_modules') || !id.includes('.vue')) {
|
|
68
|
-
return
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return {
|
|
72
|
-
code: await context.transform(code, id),
|
|
73
|
-
map: null,
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
} as Plugin
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export default MpBackPlugin
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>我是默认的界面</div>
|
|
3
|
-
<button id="button" @click="disableMpBack"></button>
|
|
4
|
-
<button id="button2" @click="activeMpBack"></button>
|
|
5
|
-
</template>
|
|
6
|
-
|
|
7
|
-
<script setup>
|
|
8
|
-
import onPageBack, { activeMpBack as mpppacitve, inactiveMpBack } from 'mp-weixin-back-helper'
|
|
9
|
-
|
|
10
|
-
onPageBack(
|
|
11
|
-
() => {
|
|
12
|
-
console.log('触发了手势返回')
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
initialValue: false,
|
|
16
|
-
}
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
const activeMpBack = () => {
|
|
20
|
-
console.log('执行了activeMpBack')
|
|
21
|
-
mpppacitve()
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const disableMpBack = () => {
|
|
25
|
-
inactiveMpBack()
|
|
26
|
-
}
|
|
27
|
-
</script>
|
|
28
|
-
|
|
29
|
-
<style></style>
|
package/test/generate.spec.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'
|
|
2
|
-
import { mount } from '@vue/test-utils'
|
|
3
|
-
import IndexSetup from './data/index-setup.vue'
|
|
4
|
-
import IndexUtils from './data/index-utils.vue'
|
|
5
|
-
import IndexDefault from './data/index-default.vue'
|
|
6
|
-
|
|
7
|
-
describe('generate page-container components', () => {
|
|
8
|
-
let logSpy: ReturnType<typeof vi.spyOn>
|
|
9
|
-
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
logSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
afterEach(() => {
|
|
15
|
-
logSpy.mockRestore()
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
describe('setup compositionAPI', () => {
|
|
19
|
-
it('default case', async () => {
|
|
20
|
-
const wrapper = mount(IndexSetup)
|
|
21
|
-
await wrapper.vm.$nextTick()
|
|
22
|
-
|
|
23
|
-
const pageContainerRef = wrapper.find('page-container')
|
|
24
|
-
expect(pageContainerRef.exists()).toBe(true)
|
|
25
|
-
expect(wrapper.vm.__MP_BACK_SHOW_PAGE_CONTAINER__).toBe(true)
|
|
26
|
-
expect(typeof wrapper.vm.onBeforeLeave).toBe('function')
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
it('utils case', async () => {
|
|
30
|
-
const wrapper = mount(IndexUtils)
|
|
31
|
-
await wrapper.vm.$nextTick()
|
|
32
|
-
|
|
33
|
-
const pageContainerRef = wrapper.find('page-container')
|
|
34
|
-
expect(pageContainerRef.exists()).toBe(true)
|
|
35
|
-
expect(wrapper.vm.__MP_BACK_SHOW_PAGE_CONTAINER__).toBe(false)
|
|
36
|
-
expect(typeof wrapper.vm.onBeforeLeave).toBe('function')
|
|
37
|
-
|
|
38
|
-
await wrapper.find('#button2').trigger('click')
|
|
39
|
-
await new Promise(resolve => setTimeout(resolve, 0))
|
|
40
|
-
|
|
41
|
-
expect(logSpy).toHaveBeenCalledWith('执行了activeMpBack')
|
|
42
|
-
|
|
43
|
-
expect(wrapper.vm.__MP_BACK_SHOW_PAGE_CONTAINER__).toBe(true)
|
|
44
|
-
|
|
45
|
-
await wrapper.find('#button').trigger('click')
|
|
46
|
-
await new Promise(resolve => setTimeout(resolve, 0))
|
|
47
|
-
|
|
48
|
-
expect(wrapper.vm.__MP_BACK_SHOW_PAGE_CONTAINER__).toBe(false)
|
|
49
|
-
})
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
describe('optionsAPI', () => {
|
|
53
|
-
it('default case', async () => {
|
|
54
|
-
const wrapper = mount(IndexDefault)
|
|
55
|
-
await wrapper.vm.$nextTick()
|
|
56
|
-
|
|
57
|
-
const pageContainerRef = wrapper.find('page-container')
|
|
58
|
-
expect(pageContainerRef.exists()).toBe(true)
|
|
59
|
-
expect(wrapper.vm.__MP_BACK_SHOW_PAGE_CONTAINER__).toBe(true)
|
|
60
|
-
expect(wrapper.vm.__MP_BACK_FREQUENCY__).toBe(1)
|
|
61
|
-
expect(wrapper.vm.onBeforeLeave()).toBe(true)
|
|
62
|
-
})
|
|
63
|
-
})
|
|
64
|
-
})
|
package/tsconfig.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "es2018",
|
|
4
|
-
"lib": ["esnext"],
|
|
5
|
-
"types": ["node"],
|
|
6
|
-
"module": "esnext",
|
|
7
|
-
"moduleResolution": "node",
|
|
8
|
-
"resolveJsonModule": true,
|
|
9
|
-
"strict": true,
|
|
10
|
-
"strictNullChecks": true,
|
|
11
|
-
"esModuleInterop": true,
|
|
12
|
-
"skipDefaultLibCheck": true,
|
|
13
|
-
"skipLibCheck": true
|
|
14
|
-
}
|
|
15
|
-
}
|
package/types/index.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
export type UserOptions = Partial<Config>
|
|
2
|
-
|
|
3
|
-
export type Config = {
|
|
4
|
-
/**
|
|
5
|
-
* 初始化时是否监听手势返回,默认值为`true`
|
|
6
|
-
*/
|
|
7
|
-
initialValue: boolean
|
|
8
|
-
/**
|
|
9
|
-
* 是否阻止默认的回退事件,默认为 false
|
|
10
|
-
*/
|
|
11
|
-
preventDefault: boolean
|
|
12
|
-
/**
|
|
13
|
-
* 阻止次数,默认是 `1`
|
|
14
|
-
*/
|
|
15
|
-
frequency: number
|
|
16
|
-
/**
|
|
17
|
-
* 调试模式
|
|
18
|
-
*/
|
|
19
|
-
debug: boolean
|
|
20
|
-
/**
|
|
21
|
-
* 页面回退时触发
|
|
22
|
-
*/
|
|
23
|
-
onPageBack?: (params: BackParams) => void
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export type BackParams = {
|
|
27
|
-
/**
|
|
28
|
-
* 当前页面路径
|
|
29
|
-
*/
|
|
30
|
-
page: string
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export type ContextConfig = Config & {
|
|
34
|
-
mode: string
|
|
35
|
-
root: string
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
type Pages = { path: string }[]
|
|
39
|
-
|
|
40
|
-
export type PagesJson = {
|
|
41
|
-
pages: Pages
|
|
42
|
-
subpackages: { root: string; pages: Pages }[]
|
|
43
|
-
}
|
package/utils/constant.ts
DELETED
package/utils/index.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'
|
|
2
|
-
import { pageContext } from '../src/context'
|
|
3
|
-
import { vueWalker } from './walker'
|
|
4
|
-
|
|
5
|
-
let compilerPromise: Promise<typeof import('@vue/compiler-sfc')> | null = null
|
|
6
|
-
|
|
7
|
-
async function resolveCompiler(root: string): Promise<typeof import('@vue/compiler-sfc')> {
|
|
8
|
-
// 避免重复解析(防止并发调用时的竞态条件)
|
|
9
|
-
if (compilerPromise) {
|
|
10
|
-
return compilerPromise
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
compilerPromise = (async () => {
|
|
14
|
-
// 尝试加载用户项目中的 @vue/compiler-sfc
|
|
15
|
-
try {
|
|
16
|
-
const _require = createRequire(import.meta.url)
|
|
17
|
-
// 尝试从用户根目录解析
|
|
18
|
-
const compilerPath = _require.resolve('@vue/compiler-sfc', { paths: [root] })
|
|
19
|
-
return _require(compilerPath) as typeof import('@vue/compiler-sfc')
|
|
20
|
-
} catch (firstError) {
|
|
21
|
-
try {
|
|
22
|
-
// 降级尝试直接 import
|
|
23
|
-
return await import('@vue/compiler-sfc')
|
|
24
|
-
} catch (secondError) {
|
|
25
|
-
throw new Error(
|
|
26
|
-
`无法解析 @vue/compiler-sfc。\n` +
|
|
27
|
-
`此插件需要项目中安装 @vue/compiler-sfc。\n` +
|
|
28
|
-
`请手动安装:pnpm add -D @vue/compiler-sfc\n`
|
|
29
|
-
)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
})()
|
|
33
|
-
|
|
34
|
-
return compilerPromise
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export async function transformVueFile(this: pageContext, code: string, id: string) {
|
|
38
|
-
try {
|
|
39
|
-
const sfcCompiler = await resolveCompiler(this.config.root)
|
|
40
|
-
const sfc = sfcCompiler.parse(code).descriptor
|
|
41
|
-
const { template, script, scriptSetup } = sfc
|
|
42
|
-
if (!template?.content) {
|
|
43
|
-
return code
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (!script?.content && !scriptSetup?.content) {
|
|
47
|
-
return code
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// 判断页面是否为组合式写法
|
|
51
|
-
const walker = scriptSetup ? 'compositionWalk' : 'optionsWalk'
|
|
52
|
-
return vueWalker[walker](this, code, sfc, id)
|
|
53
|
-
} catch (error) {
|
|
54
|
-
this.log.error('解析vue文件失败,请检查文件是否正确')
|
|
55
|
-
this.log.error(String(error))
|
|
56
|
-
return code
|
|
57
|
-
}
|
|
58
|
-
}
|