mp-weixin-back 0.0.3 → 0.0.5
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/build.config.ts +12 -0
- package/dist/index.cjs +146 -216
- package/dist/index.d.mts +27 -0
- package/dist/index.mjs +223 -0
- package/package.json +20 -8
- package/src/context.ts +2 -1
- package/dist/index.js +0 -272
- package/tsup.config.ts +0 -15
package/build.config.ts
ADDED
package/dist/index.cjs
CHANGED
|
@@ -1,175 +1,104 @@
|
|
|
1
|
-
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __defProps = Object.defineProperties;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
7
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
9
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
10
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
11
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
12
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
13
|
-
var __spreadValues = (a, b) => {
|
|
14
|
-
for (var prop in b || (b = {}))
|
|
15
|
-
if (__hasOwnProp.call(b, prop))
|
|
16
|
-
__defNormalProp(a, prop, b[prop]);
|
|
17
|
-
if (__getOwnPropSymbols)
|
|
18
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
19
|
-
if (__propIsEnum.call(b, prop))
|
|
20
|
-
__defNormalProp(a, prop, b[prop]);
|
|
21
|
-
}
|
|
22
|
-
return a;
|
|
23
|
-
};
|
|
24
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
|
-
var __export = (target, all) => {
|
|
26
|
-
for (var name in all)
|
|
27
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
28
|
-
};
|
|
29
|
-
var __copyProps = (to, from, except, desc) => {
|
|
30
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
31
|
-
for (let key of __getOwnPropNames(from))
|
|
32
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
33
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
34
|
-
}
|
|
35
|
-
return to;
|
|
36
|
-
};
|
|
37
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
38
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
39
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
40
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
41
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
42
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
43
|
-
mod
|
|
44
|
-
));
|
|
45
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
46
|
-
var __async = (__this, __arguments, generator) => {
|
|
47
|
-
return new Promise((resolve, reject) => {
|
|
48
|
-
var fulfilled = (value) => {
|
|
49
|
-
try {
|
|
50
|
-
step(generator.next(value));
|
|
51
|
-
} catch (e) {
|
|
52
|
-
reject(e);
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
var rejected = (value) => {
|
|
56
|
-
try {
|
|
57
|
-
step(generator.throw(value));
|
|
58
|
-
} catch (e) {
|
|
59
|
-
reject(e);
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
63
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
64
|
-
});
|
|
65
|
-
};
|
|
1
|
+
'use strict';
|
|
66
2
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const JSON5 = require('json5');
|
|
6
|
+
const generate = require('@babel/generator');
|
|
7
|
+
const compilerSfc = require('@vue/compiler-sfc');
|
|
8
|
+
const astKit = require('ast-kit');
|
|
73
9
|
|
|
74
|
-
|
|
75
|
-
var import_path = __toESM(require("path"), 1);
|
|
76
|
-
var import_fs = __toESM(require("fs"), 1);
|
|
77
|
-
var import_json5 = __toESM(require("json5"), 1);
|
|
10
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
78
11
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
12
|
+
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
13
|
+
const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
14
|
+
const JSON5__default = /*#__PURE__*/_interopDefaultCompat(JSON5);
|
|
15
|
+
const generate__default = /*#__PURE__*/_interopDefaultCompat(generate);
|
|
83
16
|
|
|
84
|
-
|
|
85
|
-
var virtualFileId = "mp-weixin-back-helper";
|
|
17
|
+
const virtualFileId = "mp-weixin-back-helper";
|
|
86
18
|
|
|
87
|
-
// utils/index.ts
|
|
88
19
|
function isArrowFunction(func) {
|
|
89
|
-
if (typeof func !== "function")
|
|
20
|
+
if (typeof func !== "function")
|
|
21
|
+
return false;
|
|
90
22
|
return !func.hasOwnProperty("prototype") && func.toString().includes("=>");
|
|
91
23
|
}
|
|
92
|
-
function parseSFC(code) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
});
|
|
24
|
+
async function parseSFC(code) {
|
|
25
|
+
try {
|
|
26
|
+
return compilerSfc.parse(code).descriptor;
|
|
27
|
+
} catch (error) {
|
|
28
|
+
throw new Error(`\u89E3\u6790vue\u6587\u4EF6\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u6587\u4EF6\u662F\u5426\u6B63\u786E`);
|
|
29
|
+
}
|
|
100
30
|
}
|
|
101
|
-
function transformVueFile(code, id) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (element.local.name == "ref") {
|
|
130
|
-
hasImportRef = true;
|
|
131
|
-
break;
|
|
132
|
-
}
|
|
31
|
+
async function transformVueFile(code, id) {
|
|
32
|
+
if (code.includes("<page-container")) {
|
|
33
|
+
return code;
|
|
34
|
+
}
|
|
35
|
+
if (!code.includes("<template")) {
|
|
36
|
+
return code;
|
|
37
|
+
}
|
|
38
|
+
const componentStr = '<page-container :show="__MP_BACK_SHOW_PAGE_CONTAINER__" :overlay="false" @beforeleave="onBeforeLeave" :z-index="1" :duration="false"></page-container>';
|
|
39
|
+
const sfc = await parseSFC(code);
|
|
40
|
+
const setupCode = sfc.scriptSetup?.loc.source;
|
|
41
|
+
const setupAst = astKit.babelParse(setupCode || "", sfc.scriptSetup?.lang);
|
|
42
|
+
let pageBackConfig = this.config;
|
|
43
|
+
let hasPageBack = false, hasImportRef = false, pageBackFnName = "onPageBack", callbackCode = ``;
|
|
44
|
+
if (setupAst) {
|
|
45
|
+
astKit.walkAST(setupAst, {
|
|
46
|
+
enter(node) {
|
|
47
|
+
if (node.type == "ImportDeclaration" && node.source.value.includes(virtualFileId)) {
|
|
48
|
+
const importSpecifier = node.specifiers[0];
|
|
49
|
+
hasPageBack = true;
|
|
50
|
+
pageBackFnName = importSpecifier.local.name;
|
|
51
|
+
}
|
|
52
|
+
if (node.type == "ImportDeclaration" && node.source.value === "vue") {
|
|
53
|
+
const importSpecifiers = node.specifiers;
|
|
54
|
+
for (let i = 0; i < importSpecifiers.length; i++) {
|
|
55
|
+
const element = importSpecifiers[i];
|
|
56
|
+
if (element.local.name == "ref") {
|
|
57
|
+
hasImportRef = true;
|
|
58
|
+
break;
|
|
133
59
|
}
|
|
134
60
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
61
|
+
}
|
|
62
|
+
if (node.type == "ExpressionStatement" && node.expression.type == "CallExpression" && node.expression.callee.loc?.identifierName == pageBackFnName) {
|
|
63
|
+
const callback = node.expression.arguments[0];
|
|
64
|
+
const backArguments = node.expression.arguments[1];
|
|
65
|
+
if (backArguments && backArguments.type == "ObjectExpression") {
|
|
66
|
+
const config = new Function(`return (${generate__default(backArguments).code});`)();
|
|
67
|
+
pageBackConfig = { ...pageBackConfig, ...config };
|
|
68
|
+
}
|
|
69
|
+
if (callback && (callback.type === "ArrowFunctionExpression" || callback.type === "FunctionExpression")) {
|
|
70
|
+
const body = callback.body;
|
|
71
|
+
if (body.type === "BlockStatement") {
|
|
72
|
+
body.body.forEach((statement) => {
|
|
73
|
+
callbackCode += generate__default(statement).code;
|
|
74
|
+
});
|
|
149
75
|
}
|
|
150
76
|
}
|
|
151
77
|
}
|
|
152
|
-
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (!hasPageBack)
|
|
82
|
+
return;
|
|
83
|
+
if (!pageBackConfig.preventDefault) {
|
|
84
|
+
callbackCode += `uni.navigateBack({ delta: 1 });`;
|
|
85
|
+
}
|
|
86
|
+
const configBack = (() => {
|
|
87
|
+
if (!pageBackConfig.onPageBack)
|
|
88
|
+
return "";
|
|
89
|
+
if (typeof pageBackConfig.onPageBack !== "function") {
|
|
90
|
+
throw new Error("`onPageBack` must be a function");
|
|
153
91
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
92
|
+
const params = JSON.stringify({
|
|
93
|
+
page: this.getPageById(id)
|
|
94
|
+
});
|
|
95
|
+
const hasFunction = pageBackConfig.onPageBack.toString().includes("function");
|
|
96
|
+
if (isArrowFunction(pageBackConfig.onPageBack) || hasFunction) {
|
|
97
|
+
return `(${pageBackConfig.onPageBack})(${params});`;
|
|
157
98
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
throw new Error("`onPageBack` must be a function");
|
|
162
|
-
}
|
|
163
|
-
const params = JSON.stringify({
|
|
164
|
-
page: this.getPageById(id)
|
|
165
|
-
});
|
|
166
|
-
const hasFunction = pageBackConfig.onPageBack.toString().includes("function");
|
|
167
|
-
if (isArrowFunction(pageBackConfig.onPageBack) || hasFunction) {
|
|
168
|
-
return `(${pageBackConfig.onPageBack})(${params});`;
|
|
169
|
-
}
|
|
170
|
-
return `(function ${pageBackConfig.onPageBack})()`;
|
|
171
|
-
})();
|
|
172
|
-
const beforeLeaveStr = `
|
|
99
|
+
return `(function ${pageBackConfig.onPageBack})()`;
|
|
100
|
+
})();
|
|
101
|
+
const beforeLeaveStr = `
|
|
173
102
|
${!hasImportRef ? "import { ref } from 'vue'" : ""}
|
|
174
103
|
let __MP_BACK_FREQUENCY__ = 1
|
|
175
104
|
const __MP_BACK_SHOW_PAGE_CONTAINER__ = ref(true);
|
|
@@ -187,91 +116,93 @@ function transformVueFile(code, id) {
|
|
|
187
116
|
${callbackCode}
|
|
188
117
|
};
|
|
189
118
|
`;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
119
|
+
const result = code.replace(
|
|
120
|
+
/(<template.*?>)([\s\S]*?)(<\/template>)([\s\S]*?)(<script\s+(?:lang="ts"\s+)?setup.*?>|$)/,
|
|
121
|
+
(match, templateStart, templateContent, templateEnd, middleContent, scriptSetup) => {
|
|
122
|
+
const hasScriptSetup = Boolean(scriptSetup);
|
|
123
|
+
const scriptStartTag = hasScriptSetup ? scriptSetup : "<script setup>";
|
|
124
|
+
const scriptEndTag = hasScriptSetup ? "" : "<\/script>";
|
|
125
|
+
const injectedTemplate = `${templateStart}${templateContent}
|
|
197
126
|
${componentStr}
|
|
198
127
|
${templateEnd}`;
|
|
199
|
-
|
|
128
|
+
const injectedScript = `
|
|
200
129
|
${middleContent}${scriptStartTag}
|
|
201
130
|
${beforeLeaveStr}
|
|
202
131
|
${scriptEndTag}`;
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
});
|
|
132
|
+
return injectedTemplate + injectedScript;
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
return result;
|
|
208
136
|
}
|
|
209
137
|
|
|
210
|
-
|
|
211
|
-
var
|
|
138
|
+
var __defProp = Object.defineProperty;
|
|
139
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
140
|
+
var __publicField = (obj, key, value) => {
|
|
141
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
142
|
+
return value;
|
|
143
|
+
};
|
|
144
|
+
class pageContext {
|
|
212
145
|
constructor(config) {
|
|
213
|
-
this
|
|
146
|
+
__publicField(this, "config");
|
|
147
|
+
__publicField(this, "pages", []);
|
|
214
148
|
this.config = config;
|
|
215
149
|
}
|
|
216
150
|
getPagesJsonPath() {
|
|
217
|
-
const pagesJsonPath =
|
|
151
|
+
const pagesJsonPath = path__default.join(this.config.root, "src/pages.json");
|
|
218
152
|
return pagesJsonPath;
|
|
219
153
|
}
|
|
220
154
|
// 获取页面配置详情
|
|
221
|
-
getPagesJsonInfo() {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
if (subpackages) {
|
|
237
|
-
const root = subpackages.root;
|
|
238
|
-
const subPages = subpackages.pages.reduce((acc, current) => {
|
|
239
|
-
acc.push(`${root}/${current.path}`.replace("//", "/"));
|
|
240
|
-
return acc;
|
|
241
|
-
}, []);
|
|
242
|
-
this.pages.push(...subPages);
|
|
243
|
-
}
|
|
244
|
-
} catch (error) {
|
|
245
|
-
throw new Error("\u8BF7\u6B63\u786E\u914D\u7F6E\u9879\u76EE\u7684pages.json\u6587\u4EF6");
|
|
155
|
+
async getPagesJsonInfo() {
|
|
156
|
+
const hasPagesJson = fs__default.existsSync(this.getPagesJsonPath());
|
|
157
|
+
if (!hasPagesJson)
|
|
158
|
+
return;
|
|
159
|
+
try {
|
|
160
|
+
const content = await fs__default.promises.readFile(this.getPagesJsonPath(), "utf-8");
|
|
161
|
+
const pagesContent = JSON5__default.parse(content);
|
|
162
|
+
const { pages, subpackages } = pagesContent;
|
|
163
|
+
if (pages) {
|
|
164
|
+
const mainPages = pages.reduce((acc, current) => {
|
|
165
|
+
acc.push(current.path);
|
|
166
|
+
return acc;
|
|
167
|
+
}, []);
|
|
168
|
+
this.pages.push(...mainPages);
|
|
246
169
|
}
|
|
247
|
-
|
|
170
|
+
if (subpackages) {
|
|
171
|
+
const root = subpackages.root;
|
|
172
|
+
const subPages = subpackages.pages.reduce((acc, current) => {
|
|
173
|
+
acc.push(`${root}/${current.path}`.replace("//", "/"));
|
|
174
|
+
return acc;
|
|
175
|
+
}, []);
|
|
176
|
+
this.pages.push(...subPages);
|
|
177
|
+
}
|
|
178
|
+
} catch (error) {
|
|
179
|
+
console.error("\u8BFB\u53D6pages.json\u6587\u4EF6\u5931\u8D25");
|
|
180
|
+
console.error(error);
|
|
181
|
+
}
|
|
248
182
|
}
|
|
249
183
|
// 获取指定id的page
|
|
250
184
|
getPageById(id) {
|
|
251
185
|
const path2 = (id.split("src/")[1] || "").replace(".vue", "");
|
|
252
186
|
return this.pages.find((i) => i === path2) || null;
|
|
253
187
|
}
|
|
254
|
-
transform(code, id) {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
return result;
|
|
258
|
-
});
|
|
188
|
+
async transform(code, id) {
|
|
189
|
+
const result = await transformVueFile.call(this, code, id);
|
|
190
|
+
return result;
|
|
259
191
|
}
|
|
260
|
-
}
|
|
192
|
+
}
|
|
261
193
|
|
|
262
|
-
// src/index.ts
|
|
263
194
|
function MpBackPlugin(userOptions = {}) {
|
|
264
195
|
let context;
|
|
265
196
|
const defaultOptions = {
|
|
266
197
|
preventDefault: false,
|
|
267
198
|
frequency: 1
|
|
268
199
|
};
|
|
269
|
-
const options =
|
|
200
|
+
const options = { ...defaultOptions, ...userOptions };
|
|
270
201
|
return {
|
|
271
202
|
name: "vite-plugin-mp-weixin-back",
|
|
272
203
|
enforce: "pre",
|
|
273
204
|
configResolved(config) {
|
|
274
|
-
context = new pageContext(
|
|
205
|
+
context = new pageContext({ ...options, mode: config.mode, root: config.root });
|
|
275
206
|
},
|
|
276
207
|
buildStart() {
|
|
277
208
|
context.getPagesJsonInfo();
|
|
@@ -289,14 +220,13 @@ function MpBackPlugin(userOptions = {}) {
|
|
|
289
220
|
return `export default function onPageBack() {}`;
|
|
290
221
|
}
|
|
291
222
|
},
|
|
292
|
-
transform(code, id) {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
return context.transform(code, id);
|
|
298
|
-
});
|
|
223
|
+
async transform(code, id) {
|
|
224
|
+
if (id.includes("node_modules") || !id.includes(".vue")) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
return context.transform(code, id);
|
|
299
228
|
}
|
|
300
229
|
};
|
|
301
230
|
}
|
|
302
|
-
|
|
231
|
+
|
|
232
|
+
module.exports = MpBackPlugin;
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
type UserOptions = Partial<Config>;
|
|
4
|
+
type Config = {
|
|
5
|
+
/**
|
|
6
|
+
* 是否阻止默认的回退事件,默认为 false
|
|
7
|
+
*/
|
|
8
|
+
preventDefault: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* 阻止次数,默认是 `1`
|
|
11
|
+
*/
|
|
12
|
+
frequency: number;
|
|
13
|
+
/**
|
|
14
|
+
* 页面回退时触发
|
|
15
|
+
*/
|
|
16
|
+
onPageBack?: (params: BackParams) => void;
|
|
17
|
+
};
|
|
18
|
+
type BackParams = {
|
|
19
|
+
/**
|
|
20
|
+
* 当前页面路径
|
|
21
|
+
*/
|
|
22
|
+
page: string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
declare function MpBackPlugin(userOptions?: UserOptions): Plugin;
|
|
26
|
+
|
|
27
|
+
export { MpBackPlugin as default };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import JSON5 from 'json5';
|
|
4
|
+
import generate from '@babel/generator';
|
|
5
|
+
import { parse } from '@vue/compiler-sfc';
|
|
6
|
+
import { babelParse, walkAST } from 'ast-kit';
|
|
7
|
+
|
|
8
|
+
const virtualFileId = "mp-weixin-back-helper";
|
|
9
|
+
|
|
10
|
+
function isArrowFunction(func) {
|
|
11
|
+
if (typeof func !== "function")
|
|
12
|
+
return false;
|
|
13
|
+
return !func.hasOwnProperty("prototype") && func.toString().includes("=>");
|
|
14
|
+
}
|
|
15
|
+
async function parseSFC(code) {
|
|
16
|
+
try {
|
|
17
|
+
return parse(code).descriptor;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw new Error(`\u89E3\u6790vue\u6587\u4EF6\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u6587\u4EF6\u662F\u5426\u6B63\u786E`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function transformVueFile(code, id) {
|
|
23
|
+
if (code.includes("<page-container")) {
|
|
24
|
+
return code;
|
|
25
|
+
}
|
|
26
|
+
if (!code.includes("<template")) {
|
|
27
|
+
return code;
|
|
28
|
+
}
|
|
29
|
+
const componentStr = '<page-container :show="__MP_BACK_SHOW_PAGE_CONTAINER__" :overlay="false" @beforeleave="onBeforeLeave" :z-index="1" :duration="false"></page-container>';
|
|
30
|
+
const sfc = await parseSFC(code);
|
|
31
|
+
const setupCode = sfc.scriptSetup?.loc.source;
|
|
32
|
+
const setupAst = babelParse(setupCode || "", sfc.scriptSetup?.lang);
|
|
33
|
+
let pageBackConfig = this.config;
|
|
34
|
+
let hasPageBack = false, hasImportRef = false, pageBackFnName = "onPageBack", callbackCode = ``;
|
|
35
|
+
if (setupAst) {
|
|
36
|
+
walkAST(setupAst, {
|
|
37
|
+
enter(node) {
|
|
38
|
+
if (node.type == "ImportDeclaration" && node.source.value.includes(virtualFileId)) {
|
|
39
|
+
const importSpecifier = node.specifiers[0];
|
|
40
|
+
hasPageBack = true;
|
|
41
|
+
pageBackFnName = importSpecifier.local.name;
|
|
42
|
+
}
|
|
43
|
+
if (node.type == "ImportDeclaration" && node.source.value === "vue") {
|
|
44
|
+
const importSpecifiers = node.specifiers;
|
|
45
|
+
for (let i = 0; i < importSpecifiers.length; i++) {
|
|
46
|
+
const element = importSpecifiers[i];
|
|
47
|
+
if (element.local.name == "ref") {
|
|
48
|
+
hasImportRef = true;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (node.type == "ExpressionStatement" && node.expression.type == "CallExpression" && node.expression.callee.loc?.identifierName == pageBackFnName) {
|
|
54
|
+
const callback = node.expression.arguments[0];
|
|
55
|
+
const backArguments = node.expression.arguments[1];
|
|
56
|
+
if (backArguments && backArguments.type == "ObjectExpression") {
|
|
57
|
+
const config = new Function(`return (${generate(backArguments).code});`)();
|
|
58
|
+
pageBackConfig = { ...pageBackConfig, ...config };
|
|
59
|
+
}
|
|
60
|
+
if (callback && (callback.type === "ArrowFunctionExpression" || callback.type === "FunctionExpression")) {
|
|
61
|
+
const body = callback.body;
|
|
62
|
+
if (body.type === "BlockStatement") {
|
|
63
|
+
body.body.forEach((statement) => {
|
|
64
|
+
callbackCode += generate(statement).code;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (!hasPageBack)
|
|
73
|
+
return;
|
|
74
|
+
if (!pageBackConfig.preventDefault) {
|
|
75
|
+
callbackCode += `uni.navigateBack({ delta: 1 });`;
|
|
76
|
+
}
|
|
77
|
+
const configBack = (() => {
|
|
78
|
+
if (!pageBackConfig.onPageBack)
|
|
79
|
+
return "";
|
|
80
|
+
if (typeof pageBackConfig.onPageBack !== "function") {
|
|
81
|
+
throw new Error("`onPageBack` must be a function");
|
|
82
|
+
}
|
|
83
|
+
const params = JSON.stringify({
|
|
84
|
+
page: this.getPageById(id)
|
|
85
|
+
});
|
|
86
|
+
const hasFunction = pageBackConfig.onPageBack.toString().includes("function");
|
|
87
|
+
if (isArrowFunction(pageBackConfig.onPageBack) || hasFunction) {
|
|
88
|
+
return `(${pageBackConfig.onPageBack})(${params});`;
|
|
89
|
+
}
|
|
90
|
+
return `(function ${pageBackConfig.onPageBack})()`;
|
|
91
|
+
})();
|
|
92
|
+
const beforeLeaveStr = `
|
|
93
|
+
${!hasImportRef ? "import { ref } from 'vue'" : ""}
|
|
94
|
+
let __MP_BACK_FREQUENCY__ = 1
|
|
95
|
+
const __MP_BACK_SHOW_PAGE_CONTAINER__ = ref(true);
|
|
96
|
+
const onBeforeLeave = () => {
|
|
97
|
+
console.log("__MP_BACK_FREQUENCY__", __MP_BACK_FREQUENCY__, ${pageBackConfig.frequency})
|
|
98
|
+
if (__MP_BACK_FREQUENCY__ < ${pageBackConfig.frequency}) {
|
|
99
|
+
__MP_BACK_SHOW_PAGE_CONTAINER__.value = false
|
|
100
|
+
setTimeout(() => {
|
|
101
|
+
__MP_BACK_SHOW_PAGE_CONTAINER__.value = true
|
|
102
|
+
}, 0);
|
|
103
|
+
__MP_BACK_FREQUENCY__++
|
|
104
|
+
}
|
|
105
|
+
// \u8FD0\u884C\u914D\u7F6E\u7684\u533F\u540D\u51FD\u6570
|
|
106
|
+
${configBack}
|
|
107
|
+
${callbackCode}
|
|
108
|
+
};
|
|
109
|
+
`;
|
|
110
|
+
const result = code.replace(
|
|
111
|
+
/(<template.*?>)([\s\S]*?)(<\/template>)([\s\S]*?)(<script\s+(?:lang="ts"\s+)?setup.*?>|$)/,
|
|
112
|
+
(match, templateStart, templateContent, templateEnd, middleContent, scriptSetup) => {
|
|
113
|
+
const hasScriptSetup = Boolean(scriptSetup);
|
|
114
|
+
const scriptStartTag = hasScriptSetup ? scriptSetup : "<script setup>";
|
|
115
|
+
const scriptEndTag = hasScriptSetup ? "" : "<\/script>";
|
|
116
|
+
const injectedTemplate = `${templateStart}${templateContent}
|
|
117
|
+
${componentStr}
|
|
118
|
+
${templateEnd}`;
|
|
119
|
+
const injectedScript = `
|
|
120
|
+
${middleContent}${scriptStartTag}
|
|
121
|
+
${beforeLeaveStr}
|
|
122
|
+
${scriptEndTag}`;
|
|
123
|
+
return injectedTemplate + injectedScript;
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
var __defProp = Object.defineProperty;
|
|
130
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
131
|
+
var __publicField = (obj, key, value) => {
|
|
132
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
133
|
+
return value;
|
|
134
|
+
};
|
|
135
|
+
class pageContext {
|
|
136
|
+
constructor(config) {
|
|
137
|
+
__publicField(this, "config");
|
|
138
|
+
__publicField(this, "pages", []);
|
|
139
|
+
this.config = config;
|
|
140
|
+
}
|
|
141
|
+
getPagesJsonPath() {
|
|
142
|
+
const pagesJsonPath = path.join(this.config.root, "src/pages.json");
|
|
143
|
+
return pagesJsonPath;
|
|
144
|
+
}
|
|
145
|
+
// 获取页面配置详情
|
|
146
|
+
async getPagesJsonInfo() {
|
|
147
|
+
const hasPagesJson = fs.existsSync(this.getPagesJsonPath());
|
|
148
|
+
if (!hasPagesJson)
|
|
149
|
+
return;
|
|
150
|
+
try {
|
|
151
|
+
const content = await fs.promises.readFile(this.getPagesJsonPath(), "utf-8");
|
|
152
|
+
const pagesContent = JSON5.parse(content);
|
|
153
|
+
const { pages, subpackages } = pagesContent;
|
|
154
|
+
if (pages) {
|
|
155
|
+
const mainPages = pages.reduce((acc, current) => {
|
|
156
|
+
acc.push(current.path);
|
|
157
|
+
return acc;
|
|
158
|
+
}, []);
|
|
159
|
+
this.pages.push(...mainPages);
|
|
160
|
+
}
|
|
161
|
+
if (subpackages) {
|
|
162
|
+
const root = subpackages.root;
|
|
163
|
+
const subPages = subpackages.pages.reduce((acc, current) => {
|
|
164
|
+
acc.push(`${root}/${current.path}`.replace("//", "/"));
|
|
165
|
+
return acc;
|
|
166
|
+
}, []);
|
|
167
|
+
this.pages.push(...subPages);
|
|
168
|
+
}
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.error("\u8BFB\u53D6pages.json\u6587\u4EF6\u5931\u8D25");
|
|
171
|
+
console.error(error);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// 获取指定id的page
|
|
175
|
+
getPageById(id) {
|
|
176
|
+
const path2 = (id.split("src/")[1] || "").replace(".vue", "");
|
|
177
|
+
return this.pages.find((i) => i === path2) || null;
|
|
178
|
+
}
|
|
179
|
+
async transform(code, id) {
|
|
180
|
+
const result = await transformVueFile.call(this, code, id);
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function MpBackPlugin(userOptions = {}) {
|
|
186
|
+
let context;
|
|
187
|
+
const defaultOptions = {
|
|
188
|
+
preventDefault: false,
|
|
189
|
+
frequency: 1
|
|
190
|
+
};
|
|
191
|
+
const options = { ...defaultOptions, ...userOptions };
|
|
192
|
+
return {
|
|
193
|
+
name: "vite-plugin-mp-weixin-back",
|
|
194
|
+
enforce: "pre",
|
|
195
|
+
configResolved(config) {
|
|
196
|
+
context = new pageContext({ ...options, mode: config.mode, root: config.root });
|
|
197
|
+
},
|
|
198
|
+
buildStart() {
|
|
199
|
+
context.getPagesJsonInfo();
|
|
200
|
+
},
|
|
201
|
+
resolveId(id) {
|
|
202
|
+
if (id === virtualFileId) {
|
|
203
|
+
return virtualFileId;
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
load(id) {
|
|
207
|
+
if (id.includes("node_modules")) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (id === virtualFileId) {
|
|
211
|
+
return `export default function onPageBack() {}`;
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
async transform(code, id) {
|
|
215
|
+
if (id.includes("node_modules") || !id.includes(".vue")) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
return context.transform(code, id);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export { MpBackPlugin as default };
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mp-weixin-back",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.5",
|
|
5
5
|
"description": "监听微信小程序的手势返回和页面默认导航栏的返回",
|
|
6
6
|
"main": "./dist/index.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"build": "
|
|
8
|
+
"build": "unbuild",
|
|
9
9
|
"test": "vitest"
|
|
10
10
|
},
|
|
11
11
|
"keywords": [
|
|
@@ -16,15 +16,25 @@
|
|
|
16
16
|
],
|
|
17
17
|
"exports": {
|
|
18
18
|
".": {
|
|
19
|
-
"
|
|
20
|
-
|
|
19
|
+
"import": {
|
|
20
|
+
"types": "./dist/index.d.mts",
|
|
21
|
+
"default": "./dist/index.mjs"
|
|
22
|
+
},
|
|
23
|
+
"require": {
|
|
24
|
+
"types": "./dist/index.d.cts",
|
|
25
|
+
"default": "./dist/index.cjs"
|
|
26
|
+
}
|
|
21
27
|
},
|
|
22
28
|
"./client": {
|
|
23
29
|
"types": "./client.d.ts"
|
|
24
30
|
}
|
|
25
31
|
},
|
|
26
|
-
"author": "",
|
|
32
|
+
"author": "DBAAZzz",
|
|
27
33
|
"license": "ISC",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/DBAAZzz/mp-weixin-back.git"
|
|
37
|
+
},
|
|
28
38
|
"dependencies": {
|
|
29
39
|
"@babel/generator": "^7.26.2",
|
|
30
40
|
"@babel/parser": "^7.26.2",
|
|
@@ -36,10 +46,8 @@
|
|
|
36
46
|
"ast-kit": "^1.3.1",
|
|
37
47
|
"happy-dom": "^15.11.6",
|
|
38
48
|
"json5": "^2.2.3",
|
|
39
|
-
"tsup": "^8.3.5",
|
|
40
49
|
"typescript": "^5.7.2",
|
|
41
|
-
"vitest": "^2.1.5"
|
|
42
|
-
"vue": "^3.5.13"
|
|
50
|
+
"vitest": "^2.1.5"
|
|
43
51
|
},
|
|
44
52
|
"peerDependencies": {
|
|
45
53
|
"@vue/compiler-sfc": "^2.7.0 || ^3.0.0",
|
|
@@ -47,5 +55,9 @@
|
|
|
47
55
|
},
|
|
48
56
|
"lint-staged": {
|
|
49
57
|
"*": "prettier --write"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"unbuild": "^2.0.0",
|
|
61
|
+
"vue": "^3.5.13"
|
|
50
62
|
}
|
|
51
63
|
}
|
package/src/context.ts
CHANGED
package/dist/index.js
DELETED
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __defProps = Object.defineProperties;
|
|
3
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
-
var __spreadValues = (a, b) => {
|
|
9
|
-
for (var prop in b || (b = {}))
|
|
10
|
-
if (__hasOwnProp.call(b, prop))
|
|
11
|
-
__defNormalProp(a, prop, b[prop]);
|
|
12
|
-
if (__getOwnPropSymbols)
|
|
13
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
-
if (__propIsEnum.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
}
|
|
17
|
-
return a;
|
|
18
|
-
};
|
|
19
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
var __async = (__this, __arguments, generator) => {
|
|
21
|
-
return new Promise((resolve, reject) => {
|
|
22
|
-
var fulfilled = (value) => {
|
|
23
|
-
try {
|
|
24
|
-
step(generator.next(value));
|
|
25
|
-
} catch (e) {
|
|
26
|
-
reject(e);
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
var rejected = (value) => {
|
|
30
|
-
try {
|
|
31
|
-
step(generator.throw(value));
|
|
32
|
-
} catch (e) {
|
|
33
|
-
reject(e);
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
37
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
38
|
-
});
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
// src/context.ts
|
|
42
|
-
import path from "path";
|
|
43
|
-
import fs from "fs";
|
|
44
|
-
import JSON5 from "json5";
|
|
45
|
-
|
|
46
|
-
// utils/index.ts
|
|
47
|
-
import generate from "@babel/generator";
|
|
48
|
-
import { parse } from "@vue/compiler-sfc";
|
|
49
|
-
import { babelParse, walkAST } from "ast-kit";
|
|
50
|
-
|
|
51
|
-
// utils/constant.ts
|
|
52
|
-
var virtualFileId = "mp-weixin-back-helper";
|
|
53
|
-
|
|
54
|
-
// utils/index.ts
|
|
55
|
-
function isArrowFunction(func) {
|
|
56
|
-
if (typeof func !== "function") return false;
|
|
57
|
-
return !func.hasOwnProperty("prototype") && func.toString().includes("=>");
|
|
58
|
-
}
|
|
59
|
-
function parseSFC(code) {
|
|
60
|
-
return __async(this, null, function* () {
|
|
61
|
-
try {
|
|
62
|
-
return parse(code).descriptor;
|
|
63
|
-
} catch (error) {
|
|
64
|
-
throw new Error(`\u89E3\u6790vue\u6587\u4EF6\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u6587\u4EF6\u662F\u5426\u6B63\u786E`);
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
function transformVueFile(code, id) {
|
|
69
|
-
return __async(this, null, function* () {
|
|
70
|
-
var _a, _b;
|
|
71
|
-
if (code.includes("<page-container")) {
|
|
72
|
-
return code;
|
|
73
|
-
}
|
|
74
|
-
if (!code.includes("<template")) {
|
|
75
|
-
return code;
|
|
76
|
-
}
|
|
77
|
-
const componentStr = '<page-container :show="__MP_BACK_SHOW_PAGE_CONTAINER__" :overlay="false" @beforeleave="onBeforeLeave" :z-index="1" :duration="false"></page-container>';
|
|
78
|
-
const sfc = yield parseSFC(code);
|
|
79
|
-
const setupCode = (_a = sfc.scriptSetup) == null ? void 0 : _a.loc.source;
|
|
80
|
-
const setupAst = babelParse(setupCode || "", (_b = sfc.scriptSetup) == null ? void 0 : _b.lang);
|
|
81
|
-
let pageBackConfig = this.config;
|
|
82
|
-
let hasPageBack = false, hasImportRef = false, pageBackFnName = "onPageBack", callbackCode = ``;
|
|
83
|
-
if (setupAst) {
|
|
84
|
-
walkAST(setupAst, {
|
|
85
|
-
enter(node) {
|
|
86
|
-
var _a2;
|
|
87
|
-
if (node.type == "ImportDeclaration" && node.source.value.includes(virtualFileId)) {
|
|
88
|
-
const importSpecifier = node.specifiers[0];
|
|
89
|
-
hasPageBack = true;
|
|
90
|
-
pageBackFnName = importSpecifier.local.name;
|
|
91
|
-
}
|
|
92
|
-
if (node.type == "ImportDeclaration" && node.source.value === "vue") {
|
|
93
|
-
const importSpecifiers = node.specifiers;
|
|
94
|
-
for (let i = 0; i < importSpecifiers.length; i++) {
|
|
95
|
-
const element = importSpecifiers[i];
|
|
96
|
-
if (element.local.name == "ref") {
|
|
97
|
-
hasImportRef = true;
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
if (node.type == "ExpressionStatement" && node.expression.type == "CallExpression" && ((_a2 = node.expression.callee.loc) == null ? void 0 : _a2.identifierName) == pageBackFnName) {
|
|
103
|
-
const callback = node.expression.arguments[0];
|
|
104
|
-
const backArguments = node.expression.arguments[1];
|
|
105
|
-
if (backArguments && backArguments.type == "ObjectExpression") {
|
|
106
|
-
const config = new Function(`return (${generate(backArguments).code});`)();
|
|
107
|
-
pageBackConfig = __spreadValues(__spreadValues({}, pageBackConfig), config);
|
|
108
|
-
}
|
|
109
|
-
if (callback && (callback.type === "ArrowFunctionExpression" || callback.type === "FunctionExpression")) {
|
|
110
|
-
const body = callback.body;
|
|
111
|
-
if (body.type === "BlockStatement") {
|
|
112
|
-
body.body.forEach((statement) => {
|
|
113
|
-
callbackCode += generate(statement).code;
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
if (!hasPageBack) return;
|
|
122
|
-
if (!pageBackConfig.preventDefault) {
|
|
123
|
-
callbackCode += `uni.navigateBack({ delta: 1 });`;
|
|
124
|
-
}
|
|
125
|
-
const configBack = (() => {
|
|
126
|
-
if (!pageBackConfig.onPageBack) return "";
|
|
127
|
-
if (typeof pageBackConfig.onPageBack !== "function") {
|
|
128
|
-
throw new Error("`onPageBack` must be a function");
|
|
129
|
-
}
|
|
130
|
-
const params = JSON.stringify({
|
|
131
|
-
page: this.getPageById(id)
|
|
132
|
-
});
|
|
133
|
-
const hasFunction = pageBackConfig.onPageBack.toString().includes("function");
|
|
134
|
-
if (isArrowFunction(pageBackConfig.onPageBack) || hasFunction) {
|
|
135
|
-
return `(${pageBackConfig.onPageBack})(${params});`;
|
|
136
|
-
}
|
|
137
|
-
return `(function ${pageBackConfig.onPageBack})()`;
|
|
138
|
-
})();
|
|
139
|
-
const beforeLeaveStr = `
|
|
140
|
-
${!hasImportRef ? "import { ref } from 'vue'" : ""}
|
|
141
|
-
let __MP_BACK_FREQUENCY__ = 1
|
|
142
|
-
const __MP_BACK_SHOW_PAGE_CONTAINER__ = ref(true);
|
|
143
|
-
const onBeforeLeave = () => {
|
|
144
|
-
console.log("__MP_BACK_FREQUENCY__", __MP_BACK_FREQUENCY__, ${pageBackConfig.frequency})
|
|
145
|
-
if (__MP_BACK_FREQUENCY__ < ${pageBackConfig.frequency}) {
|
|
146
|
-
__MP_BACK_SHOW_PAGE_CONTAINER__.value = false
|
|
147
|
-
setTimeout(() => {
|
|
148
|
-
__MP_BACK_SHOW_PAGE_CONTAINER__.value = true
|
|
149
|
-
}, 0);
|
|
150
|
-
__MP_BACK_FREQUENCY__++
|
|
151
|
-
}
|
|
152
|
-
// \u8FD0\u884C\u914D\u7F6E\u7684\u533F\u540D\u51FD\u6570
|
|
153
|
-
${configBack}
|
|
154
|
-
${callbackCode}
|
|
155
|
-
};
|
|
156
|
-
`;
|
|
157
|
-
const result = code.replace(
|
|
158
|
-
/(<template.*?>)([\s\S]*?)(<\/template>)([\s\S]*?)(<script\s+(?:lang="ts"\s+)?setup.*?>|$)/,
|
|
159
|
-
(match, templateStart, templateContent, templateEnd, middleContent, scriptSetup) => {
|
|
160
|
-
const hasScriptSetup = Boolean(scriptSetup);
|
|
161
|
-
const scriptStartTag = hasScriptSetup ? scriptSetup : "<script setup>";
|
|
162
|
-
const scriptEndTag = hasScriptSetup ? "" : "</script>";
|
|
163
|
-
const injectedTemplate = `${templateStart}${templateContent}
|
|
164
|
-
${componentStr}
|
|
165
|
-
${templateEnd}`;
|
|
166
|
-
const injectedScript = `
|
|
167
|
-
${middleContent}${scriptStartTag}
|
|
168
|
-
${beforeLeaveStr}
|
|
169
|
-
${scriptEndTag}`;
|
|
170
|
-
return injectedTemplate + injectedScript;
|
|
171
|
-
}
|
|
172
|
-
);
|
|
173
|
-
return result;
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// src/context.ts
|
|
178
|
-
var pageContext = class {
|
|
179
|
-
constructor(config) {
|
|
180
|
-
this.pages = [];
|
|
181
|
-
this.config = config;
|
|
182
|
-
}
|
|
183
|
-
getPagesJsonPath() {
|
|
184
|
-
const pagesJsonPath = path.join(this.config.root, "src/pages.json");
|
|
185
|
-
return pagesJsonPath;
|
|
186
|
-
}
|
|
187
|
-
// 获取页面配置详情
|
|
188
|
-
getPagesJsonInfo() {
|
|
189
|
-
return __async(this, null, function* () {
|
|
190
|
-
const hasPagesJson = fs.existsSync(this.getPagesJsonPath());
|
|
191
|
-
if (!hasPagesJson) return;
|
|
192
|
-
try {
|
|
193
|
-
const content = yield fs.promises.readFile(this.getPagesJsonPath(), "utf-8");
|
|
194
|
-
const pagesContent = JSON5.parse(content);
|
|
195
|
-
const { pages, subpackages } = pagesContent;
|
|
196
|
-
if (pages) {
|
|
197
|
-
const mainPages = pages.reduce((acc, current) => {
|
|
198
|
-
acc.push(current.path);
|
|
199
|
-
return acc;
|
|
200
|
-
}, []);
|
|
201
|
-
this.pages.push(...mainPages);
|
|
202
|
-
}
|
|
203
|
-
if (subpackages) {
|
|
204
|
-
const root = subpackages.root;
|
|
205
|
-
const subPages = subpackages.pages.reduce((acc, current) => {
|
|
206
|
-
acc.push(`${root}/${current.path}`.replace("//", "/"));
|
|
207
|
-
return acc;
|
|
208
|
-
}, []);
|
|
209
|
-
this.pages.push(...subPages);
|
|
210
|
-
}
|
|
211
|
-
} catch (error) {
|
|
212
|
-
throw new Error("\u8BF7\u6B63\u786E\u914D\u7F6E\u9879\u76EE\u7684pages.json\u6587\u4EF6");
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
// 获取指定id的page
|
|
217
|
-
getPageById(id) {
|
|
218
|
-
const path2 = (id.split("src/")[1] || "").replace(".vue", "");
|
|
219
|
-
return this.pages.find((i) => i === path2) || null;
|
|
220
|
-
}
|
|
221
|
-
transform(code, id) {
|
|
222
|
-
return __async(this, null, function* () {
|
|
223
|
-
const result = yield transformVueFile.call(this, code, id);
|
|
224
|
-
return result;
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
// src/index.ts
|
|
230
|
-
function MpBackPlugin(userOptions = {}) {
|
|
231
|
-
let context;
|
|
232
|
-
const defaultOptions = {
|
|
233
|
-
preventDefault: false,
|
|
234
|
-
frequency: 1
|
|
235
|
-
};
|
|
236
|
-
const options = __spreadValues(__spreadValues({}, defaultOptions), userOptions);
|
|
237
|
-
return {
|
|
238
|
-
name: "vite-plugin-mp-weixin-back",
|
|
239
|
-
enforce: "pre",
|
|
240
|
-
configResolved(config) {
|
|
241
|
-
context = new pageContext(__spreadProps(__spreadValues({}, options), { mode: config.mode, root: config.root }));
|
|
242
|
-
},
|
|
243
|
-
buildStart() {
|
|
244
|
-
context.getPagesJsonInfo();
|
|
245
|
-
},
|
|
246
|
-
resolveId(id) {
|
|
247
|
-
if (id === virtualFileId) {
|
|
248
|
-
return virtualFileId;
|
|
249
|
-
}
|
|
250
|
-
},
|
|
251
|
-
load(id) {
|
|
252
|
-
if (id.includes("node_modules")) {
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
if (id === virtualFileId) {
|
|
256
|
-
return `export default function onPageBack() {}`;
|
|
257
|
-
}
|
|
258
|
-
},
|
|
259
|
-
transform(code, id) {
|
|
260
|
-
return __async(this, null, function* () {
|
|
261
|
-
if (id.includes("node_modules") || !id.includes(".vue")) {
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
return context.transform(code, id);
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
var src_default = MpBackPlugin;
|
|
270
|
-
export {
|
|
271
|
-
src_default as default
|
|
272
|
-
};
|
package/tsup.config.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'tsup'
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
entry: ['src/index.ts'],
|
|
5
|
-
format: ['cjs', 'esm'],
|
|
6
|
-
sourcemap: false, // 生成 sourcemap
|
|
7
|
-
dts: {
|
|
8
|
-
resolve: true
|
|
9
|
-
},
|
|
10
|
-
clean: true, // 构建前清理 dist 目录
|
|
11
|
-
minify: false, // 是否压缩代码
|
|
12
|
-
target: 'es6',
|
|
13
|
-
external: ['vite'] // 标记 Vite 为外部依赖,避免打包到插件中
|
|
14
|
-
})
|
|
15
|
-
|