@uni-helper/vite-plugin-uni-pages 0.3.23 → 0.4.0
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/README.md +145 -65
- package/client.d.ts +1 -1
- package/dist/chunk-B4FMCO8f.mjs +28 -0
- package/dist/index.cjs +1274 -1142
- package/dist/index.d.cts +440 -3150
- package/dist/index.d.mts +440 -3150
- package/dist/index.mjs +1217 -1099
- package/package.json +23 -23
- package/dist/index.d.ts +0 -3220
package/dist/index.cjs
CHANGED
|
@@ -1,91 +1,111 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
//#region \0rolldown/runtime.js
|
|
6
|
+
var __create = Object.create;
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
11
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
14
|
+
key = keys[i];
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
16
|
+
get: ((k) => from[k]).bind(null, key),
|
|
17
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
//#endregion
|
|
27
|
+
let node_path = require("node:path");
|
|
28
|
+
node_path = __toESM(node_path, 1);
|
|
29
|
+
let node_process = require("node:process");
|
|
30
|
+
node_process = __toESM(node_process, 1);
|
|
31
|
+
let ast_kit = require("ast-kit");
|
|
32
|
+
let chokidar = require("chokidar");
|
|
33
|
+
chokidar = __toESM(chokidar, 1);
|
|
34
|
+
let magic_string = require("magic-string");
|
|
35
|
+
magic_string = __toESM(magic_string, 1);
|
|
36
|
+
let vite = require("vite");
|
|
37
|
+
let node_fs = require("node:fs");
|
|
38
|
+
node_fs = __toESM(node_fs, 1);
|
|
39
|
+
let _uni_helper_uni_env = require("@uni-helper/uni-env");
|
|
40
|
+
let comment_json = require("comment-json");
|
|
41
|
+
let debug = require("debug");
|
|
42
|
+
debug = __toESM(debug, 1);
|
|
43
|
+
let detect_indent = require("detect-indent");
|
|
44
|
+
detect_indent = __toESM(detect_indent, 1);
|
|
45
|
+
let detect_newline = require("detect-newline");
|
|
46
|
+
detect_newline = __toESM(detect_newline, 1);
|
|
47
|
+
let unconfig = require("unconfig");
|
|
48
|
+
let node_fs_promises = require("node:fs/promises");
|
|
49
|
+
let proper_lockfile = require("proper-lockfile");
|
|
50
|
+
proper_lockfile = __toESM(proper_lockfile, 1);
|
|
51
|
+
let tinyglobby = require("tinyglobby");
|
|
52
|
+
let write_file_atomic = require("write-file-atomic");
|
|
53
|
+
write_file_atomic = __toESM(write_file_atomic, 1);
|
|
54
|
+
let node_module = require("node:module");
|
|
55
|
+
let node_vm = require("node:vm");
|
|
56
|
+
node_vm = __toESM(node_vm, 1);
|
|
57
|
+
let _babel_generator = require("@babel/generator");
|
|
58
|
+
_babel_generator = __toESM(_babel_generator, 1);
|
|
59
|
+
let lodash_groupby = require("lodash.groupby");
|
|
60
|
+
lodash_groupby = __toESM(lodash_groupby, 1);
|
|
61
|
+
let typescript = require("typescript");
|
|
62
|
+
typescript = __toESM(typescript, 1);
|
|
63
|
+
let _babel_types = require("@babel/types");
|
|
64
|
+
_babel_types = __toESM(_babel_types, 1);
|
|
65
|
+
let _vue_compiler_sfc = require("@vue/compiler-sfc");
|
|
66
|
+
let _uni_helper_uni_pages_types = require("@uni-helper/uni-pages-types");
|
|
67
|
+
//#region src/constant.ts
|
|
68
|
+
/** Virtual module identifier for Vite module resolution */
|
|
65
69
|
const MODULE_ID_VIRTUAL = "virtual:uni-pages";
|
|
70
|
+
/** Resolved virtual module identifier with \0 prefix to avoid conflicts with other modules */
|
|
66
71
|
const RESOLVED_MODULE_ID_VIRTUAL = `\0${MODULE_ID_VIRTUAL}`;
|
|
72
|
+
/** Output filename, the uni-app page configuration file */
|
|
67
73
|
const OUTPUT_NAME = "pages.json";
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
/** Supported page file extensions */
|
|
75
|
+
const FILE_EXTENSIONS = [
|
|
76
|
+
"vue",
|
|
77
|
+
"nvue",
|
|
78
|
+
"uvue"
|
|
79
|
+
];
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region ../../node_modules/.pnpm/@antfu+utils@9.3.0/node_modules/@antfu/utils/dist/index.mjs
|
|
70
82
|
function slash(str) {
|
|
71
|
-
|
|
83
|
+
return str.replace(/\\/g, "/");
|
|
72
84
|
}
|
|
73
|
-
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/declaration.ts
|
|
87
|
+
/**
|
|
88
|
+
* Generate TypeScript declaration file content
|
|
89
|
+
* Provide type hints for uni-app navigation APIs (navigateTo, redirectTo, switchTab, reLaunch)
|
|
90
|
+
* Ensure page paths get type checking at compile time
|
|
91
|
+
*
|
|
92
|
+
* @param ctx - Page context instance
|
|
93
|
+
* @returns Declaration file code string
|
|
94
|
+
*/
|
|
74
95
|
function getDeclaration(ctx) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const code = `/* eslint-disable */
|
|
96
|
+
const subPagesPath = ctx.subPageMetaData.map((sub) => {
|
|
97
|
+
return sub.pages.map((v) => `"/${(0, vite.normalizePath)((0, node_path.join)(sub.root, v.path))}"`);
|
|
98
|
+
}).flat();
|
|
99
|
+
const tabsPagesPath = ctx.pagesGlobConfig?.tabBar?.list?.map((v) => {
|
|
100
|
+
return `"/${v.pagePath}"`;
|
|
101
|
+
}) ?? [];
|
|
102
|
+
return `/* eslint-disable */
|
|
83
103
|
/* prettier-ignore */
|
|
84
104
|
// @ts-nocheck
|
|
85
105
|
// Generated by vite-plugin-uni-pages
|
|
86
106
|
|
|
87
107
|
type _LocationUrl =
|
|
88
|
-
${
|
|
108
|
+
${[...ctx.pageMetaData.filter((page) => !tabsPagesPath.includes(page.path)).map((v) => `"/${v.path}"`), ...subPagesPath].join(" |\n ")};
|
|
89
109
|
|
|
90
110
|
interface NavigateToOptions {
|
|
91
111
|
url: _LocationUrl;
|
|
@@ -109,1111 +129,1212 @@ declare module "virtual:uni-pages" {
|
|
|
109
129
|
export type LocationUrl = _LocationUrl;
|
|
110
130
|
}
|
|
111
131
|
`;
|
|
112
|
-
return code;
|
|
113
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Write file, automatically create directories
|
|
135
|
+
* @param filePath - File path
|
|
136
|
+
* @param content - File content
|
|
137
|
+
*/
|
|
114
138
|
async function writeFile(filePath, content) {
|
|
115
|
-
|
|
116
|
-
|
|
139
|
+
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(filePath), { recursive: true });
|
|
140
|
+
return await (0, node_fs_promises.writeFile)(filePath, content, "utf-8");
|
|
117
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Write declaration file to disk
|
|
144
|
+
* Only writes when content changes to avoid unnecessary file operations
|
|
145
|
+
*
|
|
146
|
+
* @param ctx - Page context instance
|
|
147
|
+
* @param filepath - Declaration file output path
|
|
148
|
+
*/
|
|
118
149
|
async function writeDeclaration(ctx, filepath) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (code !== originalContent)
|
|
124
|
-
await writeFile(filepath, code);
|
|
150
|
+
const originalContent = (0, node_fs.existsSync)(filepath) ? await (0, node_fs_promises.readFile)(filepath, "utf-8") : "";
|
|
151
|
+
const code = getDeclaration(ctx);
|
|
152
|
+
if (!code) return;
|
|
153
|
+
if (code !== originalContent) await writeFile(filepath, code);
|
|
125
154
|
}
|
|
126
|
-
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region src/utils.ts
|
|
157
|
+
/**
|
|
158
|
+
* Invalidate virtual module to trigger HMR update
|
|
159
|
+
* When page configuration changes, the virtual module needs to be invalidated to regenerate content
|
|
160
|
+
*
|
|
161
|
+
* @param server - Vite dev server instance
|
|
162
|
+
*/
|
|
127
163
|
function invalidatePagesModule(server) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
164
|
+
const { moduleGraph } = server;
|
|
165
|
+
const mods = moduleGraph.getModulesByFile(RESOLVED_MODULE_ID_VIRTUAL);
|
|
166
|
+
if (mods) {
|
|
167
|
+
const seen = /* @__PURE__ */ new Set();
|
|
168
|
+
mods.forEach((mod) => {
|
|
169
|
+
moduleGraph.invalidateModule(mod, seen);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
136
172
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Debug logging utility
|
|
175
|
+
* Uses debug package for leveled log output
|
|
176
|
+
* Enable via environment variable DEBUG=vite-plugin-uni-pages:*
|
|
177
|
+
*/
|
|
178
|
+
const debug$1 = {
|
|
179
|
+
/** HMR related logs */
|
|
180
|
+
hmr: (0, debug.default)("vite-plugin-uni-pages:hmr"),
|
|
181
|
+
/** Configuration options related logs */
|
|
182
|
+
options: (0, debug.default)("vite-plugin-uni-pages:options"),
|
|
183
|
+
/** Main package page scanning logs */
|
|
184
|
+
pages: (0, debug.default)("vite-plugin-uni-pages:pages"),
|
|
185
|
+
/** Sub-package page scanning logs */
|
|
186
|
+
subPages: (0, debug.default)("vite-plugin-uni-pages:subPages"),
|
|
187
|
+
/** Error logs */
|
|
188
|
+
error: (0, debug.default)("vite-plugin-uni-pages:error"),
|
|
189
|
+
/** Cache related logs */
|
|
190
|
+
cache: (0, debug.default)("vite-plugin-uni-pages:cache"),
|
|
191
|
+
/** Declaration file generation logs */
|
|
192
|
+
declaration: (0, debug.default)("vite-plugin-uni-pages:declaration"),
|
|
193
|
+
/** definePage macro parsing logs */
|
|
194
|
+
definePage: (0, debug.default)("vite-plugin-uni-pages:definePage")
|
|
147
195
|
};
|
|
196
|
+
/**
|
|
197
|
+
* Convert file extensions array to glob pattern
|
|
198
|
+
* @param extensions - File extensions array
|
|
199
|
+
* @returns Glob pattern string
|
|
200
|
+
*/
|
|
148
201
|
function extsToGlob(extensions) {
|
|
149
|
-
|
|
202
|
+
return extensions.length > 1 ? `{${extensions.join(",")}}` : extensions[0] || "";
|
|
150
203
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
204
|
+
/**
|
|
205
|
+
* Check if file is a target page file
|
|
206
|
+
* Determine if the file extension is in the supported page file types list
|
|
207
|
+
*
|
|
208
|
+
* @param path - File path
|
|
209
|
+
* @returns Whether it's a target file
|
|
210
|
+
*/
|
|
211
|
+
function isTargetFile(path) {
|
|
212
|
+
const ext = path.split(".").pop();
|
|
213
|
+
return FILE_EXTENSIONS.includes(ext);
|
|
154
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* merge page meta data array by path and assign style
|
|
217
|
+
* @param pageMetaData page meta data array
|
|
218
|
+
* TODO: support merge middleware
|
|
219
|
+
*/
|
|
155
220
|
function mergePageMetaDataArray(pageMetaData) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
221
|
+
const pageMetaDataObj = (0, lodash_groupby.default)(pageMetaData, "path");
|
|
222
|
+
const result = [];
|
|
223
|
+
for (const path in pageMetaDataObj) {
|
|
224
|
+
const _pageMetaData = pageMetaDataObj[path];
|
|
225
|
+
const options = _pageMetaData[0];
|
|
226
|
+
for (const page of _pageMetaData) {
|
|
227
|
+
options.style = Object.assign(options.style ?? {}, page.style ?? {});
|
|
228
|
+
Object.assign(options, page);
|
|
229
|
+
}
|
|
230
|
+
result.push(options);
|
|
231
|
+
}
|
|
232
|
+
return result;
|
|
168
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* Convert TypeScript / JavaScript script code to object/function
|
|
236
|
+
*
|
|
237
|
+
* @param options - Configuration required for script execution
|
|
238
|
+
* @param options.imports - List of module import statements to include
|
|
239
|
+
* @param options.code - TypeScript code content to execute
|
|
240
|
+
* @param options.filename - Script filename for error location and context
|
|
241
|
+
* @returns Script execution result, if export is a function then execute and return its return value
|
|
242
|
+
*/
|
|
169
243
|
async function parseCode(options) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
// 定时器相关
|
|
222
|
-
setTimeout,
|
|
223
|
-
clearTimeout,
|
|
224
|
-
setInterval,
|
|
225
|
-
clearInterval,
|
|
226
|
-
setImmediate,
|
|
227
|
-
clearImmediate,
|
|
228
|
-
// 控制台相关
|
|
229
|
-
console,
|
|
230
|
-
// URL 处理
|
|
231
|
-
URL,
|
|
232
|
-
URLSearchParams,
|
|
233
|
-
// 进程和性能相关
|
|
234
|
-
performance,
|
|
235
|
-
// 全局对象引用
|
|
236
|
-
global: globalThis,
|
|
237
|
-
globalThis
|
|
238
|
-
};
|
|
239
|
-
const script = new vm__default.Script(jsCode, { filename });
|
|
240
|
-
await script.runInNewContext(vmContext, {
|
|
241
|
-
timeout: 1e3
|
|
242
|
-
// 设置超时避免长时间运行
|
|
243
|
-
});
|
|
244
|
-
const result = vmContext.exports.default || vmContext.exports;
|
|
245
|
-
return result;
|
|
246
|
-
} catch (error) {
|
|
247
|
-
throw new Error(`EXEC SCRIPT FAIL IN ${filename}: ${error.message}
|
|
248
|
-
|
|
249
|
-
${jsCode}
|
|
250
|
-
|
|
251
|
-
`);
|
|
252
|
-
}
|
|
244
|
+
const { imports = [], code, filename } = options;
|
|
245
|
+
let jsCode = "";
|
|
246
|
+
try {
|
|
247
|
+
const tmpCode = `${imports.join("\n")}\n export default ${code}`;
|
|
248
|
+
jsCode = typescript.transpileModule(tmpCode, {
|
|
249
|
+
compilerOptions: {
|
|
250
|
+
module: typescript.ModuleKind.CommonJS,
|
|
251
|
+
target: typescript.ScriptTarget.ES2022,
|
|
252
|
+
noEmit: true,
|
|
253
|
+
strict: false,
|
|
254
|
+
noImplicitAny: false,
|
|
255
|
+
strictNullChecks: false,
|
|
256
|
+
strictFunctionTypes: false,
|
|
257
|
+
strictBindCallApply: false,
|
|
258
|
+
strictPropertyInitialization: false,
|
|
259
|
+
noImplicitThis: false,
|
|
260
|
+
alwaysStrict: false,
|
|
261
|
+
allowJs: true,
|
|
262
|
+
checkJs: false,
|
|
263
|
+
skipLibCheck: true,
|
|
264
|
+
esModuleInterop: true,
|
|
265
|
+
removeComments: true
|
|
266
|
+
},
|
|
267
|
+
jsDocParsingMode: typescript.JSDocParsingMode.ParseNone
|
|
268
|
+
}).outputText;
|
|
269
|
+
const dir = node_path.default.dirname(filename);
|
|
270
|
+
const vmContext = {
|
|
271
|
+
module: {},
|
|
272
|
+
exports: {},
|
|
273
|
+
__filename: filename,
|
|
274
|
+
__dirname: dir,
|
|
275
|
+
require: (0, node_module.createRequire)(dir),
|
|
276
|
+
import: (id) => import(id),
|
|
277
|
+
setTimeout,
|
|
278
|
+
clearTimeout,
|
|
279
|
+
setInterval,
|
|
280
|
+
clearInterval,
|
|
281
|
+
setImmediate,
|
|
282
|
+
clearImmediate,
|
|
283
|
+
console,
|
|
284
|
+
URL,
|
|
285
|
+
URLSearchParams,
|
|
286
|
+
performance,
|
|
287
|
+
global: globalThis,
|
|
288
|
+
globalThis
|
|
289
|
+
};
|
|
290
|
+
await new node_vm.default.Script(jsCode, { filename }).runInNewContext(vmContext, { timeout: 1e3 });
|
|
291
|
+
return vmContext.exports.default || vmContext.exports;
|
|
292
|
+
} catch (error) {
|
|
293
|
+
throw new Error(`EXEC SCRIPT FAIL IN ${filename}: ${error.message} \n\n${jsCode}\n\n`);
|
|
294
|
+
}
|
|
253
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* Async sleep function
|
|
298
|
+
* @param ms - Sleep duration in milliseconds
|
|
299
|
+
* @returns Promise object
|
|
300
|
+
*/
|
|
254
301
|
function sleep(ms) {
|
|
255
|
-
|
|
302
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
256
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Get default export of a module
|
|
306
|
+
* Compatible with CommonJS and ES Module export styles
|
|
307
|
+
*
|
|
308
|
+
* @param expr - Module object
|
|
309
|
+
* @returns Default export value
|
|
310
|
+
*/
|
|
257
311
|
function getDefaultExport(expr) {
|
|
258
|
-
|
|
312
|
+
return expr.default === void 0 ? expr : expr.default;
|
|
259
313
|
}
|
|
260
|
-
|
|
261
|
-
|
|
314
|
+
/** Babel code generator for converting AST back to code */
|
|
315
|
+
const babelGenerate = getDefaultExport(_babel_generator.default);
|
|
316
|
+
function stripType(item) {
|
|
317
|
+
const { type, ...rest } = item;
|
|
318
|
+
return rest;
|
|
319
|
+
}
|
|
320
|
+
//#endregion
|
|
321
|
+
//#region src/files.ts
|
|
322
|
+
/**
|
|
323
|
+
* Resolves the files that are valid pages for the given context.
|
|
324
|
+
*/
|
|
262
325
|
function getPageFiles(path, options) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
});
|
|
270
|
-
return files;
|
|
326
|
+
const { exclude } = options;
|
|
327
|
+
return (0, tinyglobby.globSync)(`**/*.${extsToGlob(FILE_EXTENSIONS)}`, {
|
|
328
|
+
ignore: exclude,
|
|
329
|
+
onlyFiles: true,
|
|
330
|
+
cwd: path
|
|
331
|
+
});
|
|
271
332
|
}
|
|
333
|
+
/**
|
|
334
|
+
* Check the pages.json file at the specified path, create an empty pages.json file if it doesn't exist or is not a valid file
|
|
335
|
+
* @param path - File path to check
|
|
336
|
+
* @returns boolean - Whether the operation was successful
|
|
337
|
+
*/
|
|
272
338
|
function checkPagesJsonFileSync(path) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
339
|
+
/**
|
|
340
|
+
* Create an empty pages.json file
|
|
341
|
+
* @param path - File path
|
|
342
|
+
* @returns boolean - Whether the creation was successful
|
|
343
|
+
*/
|
|
344
|
+
const createEmptyFile = (path) => {
|
|
345
|
+
try {
|
|
346
|
+
node_fs.default.writeFileSync(path, JSON.stringify({ pages: [{ path: "" }] }, null, 2), { encoding: "utf-8" });
|
|
347
|
+
return true;
|
|
348
|
+
} catch {
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
/**
|
|
353
|
+
* Delete the file at the specified path
|
|
354
|
+
* @param path - File path
|
|
355
|
+
* @returns boolean - Whether the deletion was successful
|
|
356
|
+
*/
|
|
357
|
+
const unlinkFile = (path) => {
|
|
358
|
+
try {
|
|
359
|
+
node_fs.default.unlinkSync(path);
|
|
360
|
+
return true;
|
|
361
|
+
} catch {
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
try {
|
|
366
|
+
try {
|
|
367
|
+
node_fs.default.accessSync(path, node_fs.default.constants.F_OK);
|
|
368
|
+
} catch {
|
|
369
|
+
return createEmptyFile(path);
|
|
370
|
+
}
|
|
371
|
+
if (!node_fs.default.statSync(path).isFile()) {
|
|
372
|
+
if (!unlinkFile(path)) return false;
|
|
373
|
+
return createEmptyFile(path);
|
|
374
|
+
}
|
|
375
|
+
try {
|
|
376
|
+
node_fs.default.accessSync(path, node_fs.default.constants.R_OK | node_fs.default.constants.W_OK);
|
|
377
|
+
return true;
|
|
378
|
+
} catch {
|
|
379
|
+
if (!unlinkFile(path)) return false;
|
|
380
|
+
return createEmptyFile(path);
|
|
381
|
+
}
|
|
382
|
+
} catch {
|
|
383
|
+
return createEmptyFile(path);
|
|
384
|
+
}
|
|
318
385
|
}
|
|
386
|
+
/**
|
|
387
|
+
* Safely write file using file lock
|
|
388
|
+
* Avoid data corruption caused by concurrent writes through file lock
|
|
389
|
+
* Use atomic write to ensure file write integrity
|
|
390
|
+
*
|
|
391
|
+
* @param path - File path
|
|
392
|
+
* @param content - File content
|
|
393
|
+
* @param retry - Number of retries when lock acquisition fails, defaults to 3
|
|
394
|
+
*/
|
|
319
395
|
async function writeFileWithLock(path, content, retry = 3) {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
}
|
|
337
|
-
}
|
|
396
|
+
if (retry <= 0) {
|
|
397
|
+
debug$1.error(`${path} Failed to acquire file lock, write failed`);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
let release;
|
|
401
|
+
try {
|
|
402
|
+
try {
|
|
403
|
+
release = await proper_lockfile.default.lock(path, { realpath: false });
|
|
404
|
+
} catch {
|
|
405
|
+
await sleep(500);
|
|
406
|
+
return writeFileWithLock(path, content, retry - 1);
|
|
407
|
+
}
|
|
408
|
+
await (0, write_file_atomic.default)(path, content);
|
|
409
|
+
} finally {
|
|
410
|
+
if (release) await release();
|
|
411
|
+
}
|
|
338
412
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
dirs: resolvedDirs,
|
|
382
|
-
subPackages: resolvedSubDirs,
|
|
383
|
-
outDir,
|
|
384
|
-
exclude,
|
|
385
|
-
routeBlockLang,
|
|
386
|
-
root,
|
|
387
|
-
minify,
|
|
388
|
-
debug,
|
|
389
|
-
onBeforeLoadUserConfig,
|
|
390
|
-
onAfterLoadUserConfig,
|
|
391
|
-
onBeforeScanPages,
|
|
392
|
-
onAfterScanPages,
|
|
393
|
-
onBeforeMergePageMetaData,
|
|
394
|
-
onAfterMergePageMetaData,
|
|
395
|
-
onBeforeWriteFile,
|
|
396
|
-
onAfterWriteFile
|
|
397
|
-
};
|
|
398
|
-
return resolvedOptions;
|
|
413
|
+
//#endregion
|
|
414
|
+
//#region src/options.ts
|
|
415
|
+
/**
|
|
416
|
+
* Resolve user configuration options
|
|
417
|
+
* Merge user-provided configuration with default values and handle path resolution
|
|
418
|
+
*
|
|
419
|
+
* @param userOptions - User configuration options
|
|
420
|
+
* @param viteRoot - Vite project root directory
|
|
421
|
+
* @returns Resolved configuration options
|
|
422
|
+
*/
|
|
423
|
+
function resolveOptions(userOptions, viteRoot = node_process.default.cwd()) {
|
|
424
|
+
const { dts = true, configSource = "pages.config", homePage = ["pages/index", "pages/index/index"], mergePages = true, dir = "src/pages", subPackages = [], outDir = "src", exclude = [
|
|
425
|
+
"node_modules",
|
|
426
|
+
".git",
|
|
427
|
+
"**/__*__/**"
|
|
428
|
+
], minify = false, debug = false, onBeforeLoadUserConfig = () => {}, onAfterLoadUserConfig = () => {}, onBeforeScanPages = () => {}, onAfterScanPages = () => {}, onBeforeMergePageMetaData = () => {}, onAfterMergePageMetaData = () => {}, onBeforeWriteFile = () => {}, onAfterWriteFile = () => {} } = userOptions;
|
|
429
|
+
const root = viteRoot || slash(node_process.default.env.VITE_ROOT_DIR || node_process.default.cwd());
|
|
430
|
+
const resolvedDirs = resolvePageDirs(dir, root, exclude);
|
|
431
|
+
const resolvedSubDirs = subPackages.map((dir) => slash(dir));
|
|
432
|
+
const resolvedHomePage = typeof homePage === "string" ? [homePage] : homePage;
|
|
433
|
+
const resolvedConfigSource = typeof configSource === "string" ? [{ files: configSource }] : configSource;
|
|
434
|
+
return {
|
|
435
|
+
dts: !dts ? false : typeof dts === "string" ? dts : (0, node_path.resolve)(viteRoot, "uni-pages.d.ts"),
|
|
436
|
+
configSource: Array.isArray(resolvedConfigSource) ? resolvedConfigSource : [resolvedConfigSource],
|
|
437
|
+
homePage: resolvedHomePage,
|
|
438
|
+
mergePages,
|
|
439
|
+
dirs: resolvedDirs,
|
|
440
|
+
subPackages: resolvedSubDirs,
|
|
441
|
+
outDir,
|
|
442
|
+
exclude,
|
|
443
|
+
root,
|
|
444
|
+
minify,
|
|
445
|
+
debug,
|
|
446
|
+
onBeforeLoadUserConfig,
|
|
447
|
+
onAfterLoadUserConfig,
|
|
448
|
+
onBeforeScanPages,
|
|
449
|
+
onAfterScanPages,
|
|
450
|
+
onBeforeMergePageMetaData,
|
|
451
|
+
onAfterMergePageMetaData,
|
|
452
|
+
onBeforeWriteFile,
|
|
453
|
+
onAfterWriteFile
|
|
454
|
+
};
|
|
399
455
|
}
|
|
456
|
+
/**
|
|
457
|
+
* Resolves the page dirs for its for its given globs
|
|
458
|
+
*/
|
|
400
459
|
function resolvePageDirs(dir, root, exclude) {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
return dirs;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
function parseCustomBlock(block, filePath, routeBlockLang) {
|
|
412
|
-
const lang = block.lang ?? routeBlockLang;
|
|
413
|
-
const attr = {
|
|
414
|
-
type: "page",
|
|
415
|
-
...block.attrs
|
|
416
|
-
};
|
|
417
|
-
let content;
|
|
418
|
-
debug.routeBlock(`use ${lang} parser`);
|
|
419
|
-
if (lang === "json5") {
|
|
420
|
-
try {
|
|
421
|
-
content = JSON5__default.parse(block.content);
|
|
422
|
-
} catch (err) {
|
|
423
|
-
throw new Error(
|
|
424
|
-
`Invalid JSON5 format of <${block.type}> content in ${filePath}
|
|
425
|
-
${err.message}`
|
|
426
|
-
);
|
|
427
|
-
}
|
|
428
|
-
} else if (lang === "jsonc") {
|
|
429
|
-
try {
|
|
430
|
-
content = commentJson.parse(block.content);
|
|
431
|
-
} catch (err) {
|
|
432
|
-
throw new Error(
|
|
433
|
-
`Invalid JSONC format of <${block.type}> content in ${filePath}
|
|
434
|
-
${err.message}`
|
|
435
|
-
);
|
|
436
|
-
}
|
|
437
|
-
} else if (lang === "json") {
|
|
438
|
-
try {
|
|
439
|
-
content = JSON.parse(block.content);
|
|
440
|
-
} catch (err) {
|
|
441
|
-
throw new Error(
|
|
442
|
-
`Invalid JSON format of <${block.type}> content in ${filePath}
|
|
443
|
-
${err.message}`
|
|
444
|
-
);
|
|
445
|
-
}
|
|
446
|
-
} else if (lang === "yaml" || lang === "yml") {
|
|
447
|
-
try {
|
|
448
|
-
content = yaml.parse(block.content);
|
|
449
|
-
} catch (err) {
|
|
450
|
-
throw new Error(
|
|
451
|
-
`Invalid YAML format of <${block.type}> content in ${filePath}
|
|
452
|
-
${err.message}`
|
|
453
|
-
);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
return {
|
|
457
|
-
attr,
|
|
458
|
-
content: content ?? {}
|
|
459
|
-
};
|
|
460
|
-
}
|
|
461
|
-
function getRouteSfcBlock(sfc) {
|
|
462
|
-
return sfc?.customBlocks.find((b) => b.type === "route");
|
|
460
|
+
return (0, tinyglobby.globSync)(slash(dir), {
|
|
461
|
+
ignore: exclude,
|
|
462
|
+
onlyDirectories: true,
|
|
463
|
+
expandDirectories: false,
|
|
464
|
+
dot: true,
|
|
465
|
+
cwd: root
|
|
466
|
+
});
|
|
463
467
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
468
|
+
//#endregion
|
|
469
|
+
//#region src/page.ts
|
|
470
|
+
/**
|
|
471
|
+
* Page class representing a Vue page file
|
|
472
|
+
*
|
|
473
|
+
* Responsibilities:
|
|
474
|
+
* 1. Read page file content
|
|
475
|
+
* 2. Parse page metadata defined by definePage macro
|
|
476
|
+
* 3. Provide tabBar configuration information
|
|
477
|
+
* 4. Track page file change status
|
|
478
|
+
*/
|
|
479
|
+
var Page = class {
|
|
480
|
+
/** Page context instance */
|
|
481
|
+
ctx;
|
|
482
|
+
/** Page path information containing relative and absolute paths */
|
|
483
|
+
path;
|
|
484
|
+
/** Page URI used for pages.json path field */
|
|
485
|
+
uri;
|
|
486
|
+
/** Whether the page has changed, used for incremental update judgment */
|
|
487
|
+
changed = true;
|
|
488
|
+
/** Raw JSON string of page metadata for change detection */
|
|
489
|
+
raw = "";
|
|
490
|
+
/** Parsed page metadata */
|
|
491
|
+
meta;
|
|
492
|
+
/**
|
|
493
|
+
* Create a page instance
|
|
494
|
+
* @param ctx - Page context instance
|
|
495
|
+
* @param path - Page path information
|
|
496
|
+
*/
|
|
497
|
+
constructor(ctx, path) {
|
|
498
|
+
this.ctx = ctx;
|
|
499
|
+
this.path = path;
|
|
500
|
+
this.uri = (0, vite.normalizePath)(path.relativePath.replace((0, node_path.extname)(path.relativePath), ""));
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Get page metadata
|
|
504
|
+
* Parse configuration defined by definePage macro and return metadata for pages.json
|
|
505
|
+
*
|
|
506
|
+
* @param forceUpdate - Whether to force update, ignoring cache
|
|
507
|
+
* @returns Page metadata object
|
|
508
|
+
*/
|
|
509
|
+
async getPageMeta(forceUpdate = false) {
|
|
510
|
+
if (forceUpdate || !this.meta) await this.read();
|
|
511
|
+
const { path, tabBar: _, ...others } = this.meta || {};
|
|
512
|
+
return {
|
|
513
|
+
path: path ?? this.uri,
|
|
514
|
+
...others
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Get page tabBar configuration
|
|
519
|
+
* Extract tabBar related configuration from definePage macro
|
|
520
|
+
*
|
|
521
|
+
* @param forceUpdate - Whether to force update, ignoring cache
|
|
522
|
+
* @returns tabBar configuration object, or undefined if page doesn't define tabBar
|
|
523
|
+
*/
|
|
524
|
+
async getTabBar(forceUpdate = false) {
|
|
525
|
+
if (forceUpdate || !this.meta) await this.read();
|
|
526
|
+
const { tabBar } = this.meta || {};
|
|
527
|
+
if (tabBar === void 0) return;
|
|
528
|
+
return {
|
|
529
|
+
...tabBar,
|
|
530
|
+
pagePath: tabBar.pagePath || this.uri,
|
|
531
|
+
index: tabBar.index ?? 0
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Check if the page has changed
|
|
536
|
+
* @returns Whether the page has changed
|
|
537
|
+
*/
|
|
538
|
+
hasChanged() {
|
|
539
|
+
return this.changed;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Read page file and parse metadata
|
|
543
|
+
* Extract configuration defined by definePage macro from Vue SFC
|
|
544
|
+
*/
|
|
545
|
+
async read() {
|
|
546
|
+
let meta;
|
|
547
|
+
try {
|
|
548
|
+
meta = await this.readPageMetaFromFile();
|
|
549
|
+
} catch (err) {
|
|
550
|
+
debug$1.error(err);
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
let raw = "";
|
|
554
|
+
try {
|
|
555
|
+
raw = JSON.stringify(meta);
|
|
556
|
+
} catch {}
|
|
557
|
+
this.changed = this.raw !== raw;
|
|
558
|
+
this.meta = meta;
|
|
559
|
+
this.raw = raw;
|
|
560
|
+
}
|
|
561
|
+
async readPageMetaFromFile() {
|
|
562
|
+
try {
|
|
563
|
+
const meta = await tryPageMetaFromMacro(parseSFC(await node_fs.default.promises.readFile(this.path.absolutePath, { encoding: "utf-8" }), { filename: this.path.absolutePath }));
|
|
564
|
+
if (meta) return meta;
|
|
565
|
+
return { type: "page" };
|
|
566
|
+
} catch (err) {
|
|
567
|
+
throw new Error(`Read page meta fail in ${this.path.relativePath}\n${err.message}`);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
475
570
|
};
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
this.ctx = ctx;
|
|
485
|
-
this.path = path$1;
|
|
486
|
-
this.uri = vite.normalizePath(path$1.relativePath.replace(path.extname(path$1.relativePath), ""));
|
|
487
|
-
}
|
|
488
|
-
async getPageMeta(forceUpdate = false) {
|
|
489
|
-
if (forceUpdate || !this.meta) {
|
|
490
|
-
await this.read();
|
|
491
|
-
}
|
|
492
|
-
const { path, tabBar: _, ...others } = this.meta || {};
|
|
493
|
-
return {
|
|
494
|
-
path: path ?? this.uri,
|
|
495
|
-
...others
|
|
496
|
-
};
|
|
497
|
-
}
|
|
498
|
-
async getTabBar(forceUpdate = false) {
|
|
499
|
-
if (forceUpdate || !this.meta) {
|
|
500
|
-
await this.read();
|
|
501
|
-
}
|
|
502
|
-
const { tabBar } = this.meta;
|
|
503
|
-
if (tabBar === void 0) {
|
|
504
|
-
return void 0;
|
|
505
|
-
}
|
|
506
|
-
return {
|
|
507
|
-
...tabBar,
|
|
508
|
-
pagePath: tabBar.pagePath || this.uri,
|
|
509
|
-
index: tabBar.index || 0
|
|
510
|
-
};
|
|
511
|
-
}
|
|
512
|
-
hasChanged() {
|
|
513
|
-
return this.changed;
|
|
514
|
-
}
|
|
515
|
-
async read() {
|
|
516
|
-
let meta;
|
|
517
|
-
try {
|
|
518
|
-
meta = await this.readPageMetaFromFile();
|
|
519
|
-
} catch (err) {
|
|
520
|
-
debug.error(err);
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
let raw = "";
|
|
524
|
-
try {
|
|
525
|
-
raw = JSON.stringify(meta);
|
|
526
|
-
} catch {
|
|
527
|
-
}
|
|
528
|
-
this.changed = this.raw !== raw;
|
|
529
|
-
this.meta = meta;
|
|
530
|
-
this.raw = raw;
|
|
531
|
-
}
|
|
532
|
-
async readPageMetaFromFile() {
|
|
533
|
-
try {
|
|
534
|
-
const content = await fs__default.promises.readFile(this.path.absolutePath, { encoding: "utf-8" });
|
|
535
|
-
const sfc = parseSFC(content, { filename: this.path.absolutePath });
|
|
536
|
-
const meta = await tryPageMetaFromMacro(sfc);
|
|
537
|
-
if (meta) {
|
|
538
|
-
return meta;
|
|
539
|
-
}
|
|
540
|
-
return tryPageMetaFromCustomBlock(sfc, this.ctx.options.routeBlockLang);
|
|
541
|
-
} catch (err) {
|
|
542
|
-
throw new Error(`Read page meta fail in ${this.path.relativePath}
|
|
543
|
-
${err.message}`);
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
}
|
|
571
|
+
/**
|
|
572
|
+
* Parse Vue Single File Component (SFC)
|
|
573
|
+
* Compatible with different versions of @vue/compiler-sfc
|
|
574
|
+
*
|
|
575
|
+
* @param code - Vue SFC source code
|
|
576
|
+
* @param options - Parse options
|
|
577
|
+
* @returns SFC descriptor object
|
|
578
|
+
*/
|
|
547
579
|
function parseSFC(code, options) {
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
580
|
+
return (0, _vue_compiler_sfc.parse)(code, {
|
|
581
|
+
pad: "space",
|
|
582
|
+
...options
|
|
583
|
+
}).descriptor || (0, _vue_compiler_sfc.parse)({
|
|
584
|
+
source: code,
|
|
585
|
+
...options
|
|
586
|
+
});
|
|
555
587
|
}
|
|
588
|
+
/**
|
|
589
|
+
* Try to extract page metadata defined by definePage macro from SFC
|
|
590
|
+
* Support using definePage in script setup or regular script
|
|
591
|
+
*
|
|
592
|
+
* @param sfc - Vue SFC descriptor
|
|
593
|
+
* @returns Page metadata object, or undefined if definePage is not found
|
|
594
|
+
*/
|
|
556
595
|
async function tryPageMetaFromMacro(sfc) {
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
return {
|
|
576
|
-
type: "page",
|
|
577
|
-
...res
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
return void 0;
|
|
581
|
-
}
|
|
582
|
-
async function tryPageMetaFromCustomBlock(sfc, routeBlockLang) {
|
|
583
|
-
const block = getRouteSfcBlock(sfc);
|
|
584
|
-
const routeBlock = getRouteBlock(sfc.filename, block, routeBlockLang);
|
|
585
|
-
const pageMeta = {
|
|
586
|
-
type: routeBlock?.attr.type ?? "page"
|
|
587
|
-
};
|
|
588
|
-
if (routeBlock) {
|
|
589
|
-
try {
|
|
590
|
-
commentJson.assign(pageMeta, routeBlock.content);
|
|
591
|
-
} catch {
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
return pageMeta;
|
|
596
|
+
const sfcScript = sfc.scriptSetup || sfc.script;
|
|
597
|
+
if (!sfcScript) return;
|
|
598
|
+
const ast = (0, ast_kit.babelParse)(sfcScript.content, sfcScript.lang || "js", { plugins: [["importAttributes", { deprecatedAssertSyntax: true }]] });
|
|
599
|
+
const macro = findMacro(ast.body, sfc.filename);
|
|
600
|
+
if (macro) {
|
|
601
|
+
const imports = findImports(ast.body).filter((imp) => !!imp.specifiers.length).map((imp) => babelGenerate(imp).code);
|
|
602
|
+
const [macroOption] = macro.arguments;
|
|
603
|
+
const code = babelGenerate(macroOption).code;
|
|
604
|
+
const parsed = await parseCode({
|
|
605
|
+
imports,
|
|
606
|
+
code,
|
|
607
|
+
filename: sfc.filename
|
|
608
|
+
});
|
|
609
|
+
return {
|
|
610
|
+
type: "page",
|
|
611
|
+
...typeof parsed === "function" ? await Promise.resolve(parsed()) : await Promise.resolve(parsed)
|
|
612
|
+
};
|
|
613
|
+
}
|
|
595
614
|
}
|
|
615
|
+
/**
|
|
616
|
+
* Find definePage macro call in AST
|
|
617
|
+
* Support function expressions, arrow functions and object expressions as arguments
|
|
618
|
+
*
|
|
619
|
+
* @param stmts - AST statement array
|
|
620
|
+
* @param filename - Filename for error reporting
|
|
621
|
+
* @returns definePage call expression, or undefined if not found
|
|
622
|
+
*/
|
|
596
623
|
function findMacro(stmts, filename) {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
}
|
|
614
|
-
return macro;
|
|
624
|
+
let macro;
|
|
625
|
+
for (const stmt of stmts) {
|
|
626
|
+
let node = stmt;
|
|
627
|
+
if (stmt.type === "ExpressionStatement") node = stmt.expression;
|
|
628
|
+
if ((0, ast_kit.isCallOf)(node, "definePage")) {
|
|
629
|
+
macro = node;
|
|
630
|
+
break;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
if (!macro) return;
|
|
634
|
+
const [opt] = macro.arguments;
|
|
635
|
+
if (opt && !_babel_types.isFunctionExpression(opt) && !_babel_types.isArrowFunctionExpression(opt) && !_babel_types.isObjectExpression(opt)) {
|
|
636
|
+
debug$1.definePage(`definePage() 参数仅支持函数或对象:${filename}`);
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
return macro;
|
|
615
640
|
}
|
|
641
|
+
/**
|
|
642
|
+
* Extract all import declarations from AST
|
|
643
|
+
* Used to provide necessary imports when executing definePage arguments
|
|
644
|
+
*
|
|
645
|
+
* @param stmts - AST statement array
|
|
646
|
+
* @returns Import declaration array
|
|
647
|
+
*/
|
|
616
648
|
function findImports(stmts) {
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
imports.push(stmt);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
return imports;
|
|
649
|
+
const imports = [];
|
|
650
|
+
for (const stmt of stmts) if (_babel_types.isImportDeclaration(stmt)) imports.push(stmt);
|
|
651
|
+
return imports;
|
|
624
652
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
653
|
+
//#endregion
|
|
654
|
+
//#region src/context.ts
|
|
655
|
+
/**
|
|
656
|
+
* Page context class responsible for page scanning, config loading, page metadata merging and pages.json generation
|
|
657
|
+
*
|
|
658
|
+
* Core responsibilities:
|
|
659
|
+
* 1. Scan page directories and collect page files
|
|
660
|
+
* 2. Load user configuration files (pages.config.ts, etc.)
|
|
661
|
+
* 3. Parse page metadata (definePage macro)
|
|
662
|
+
* 4. Merge page configurations and generate pages.json
|
|
663
|
+
* 5. Provide virtual module and HMR support
|
|
664
|
+
*/
|
|
665
|
+
var PageContext = class {
|
|
666
|
+
_server;
|
|
667
|
+
/** Parsed configuration object from user config file (pages.config.ts) */
|
|
668
|
+
pagesGlobConfig;
|
|
669
|
+
/** Source path list of user configuration files */
|
|
670
|
+
pagesConfigSourcePaths = [];
|
|
671
|
+
/** Main package page map, key is the absolute path of the page file */
|
|
672
|
+
pages = /* @__PURE__ */ new Map();
|
|
673
|
+
/** Sub-package page map, key is the sub-package root directory, value is the page map under that sub-package */
|
|
674
|
+
subPages = /* @__PURE__ */ new Map();
|
|
675
|
+
/** Main package page metadata array for generating pages.json pages field */
|
|
676
|
+
pageMetaData = [];
|
|
677
|
+
/** Sub-package page metadata array for generating pages.json subPackages field */
|
|
678
|
+
subPageMetaData = [];
|
|
679
|
+
/** Generated pages.json file path */
|
|
680
|
+
resolvedPagesJSONPath = "";
|
|
681
|
+
resolvedPagesJSONIndent;
|
|
682
|
+
resolvedPagesJSONNewline;
|
|
683
|
+
resolvedPagesJSONEofNewline;
|
|
684
|
+
/** Original options passed by the user */
|
|
685
|
+
rawOptions;
|
|
686
|
+
/** Project root directory */
|
|
687
|
+
root;
|
|
688
|
+
/** Resolved configuration options */
|
|
689
|
+
options;
|
|
690
|
+
logger;
|
|
691
|
+
/** Whether to work with vite-plugin-uni-platform plugin */
|
|
692
|
+
withUniPlatform = false;
|
|
693
|
+
/** Cached previous pages.json content to avoid redundant writes */
|
|
694
|
+
lastPagesJson = "";
|
|
695
|
+
/**
|
|
696
|
+
* Create a PageContext instance
|
|
697
|
+
* @param userOptions - User configuration options
|
|
698
|
+
* @param viteRoot - Vite project root directory, defaults to current working directory
|
|
699
|
+
*/
|
|
700
|
+
constructor(userOptions, viteRoot = node_process.default.cwd()) {
|
|
701
|
+
this.rawOptions = userOptions;
|
|
702
|
+
this.root = slash(viteRoot);
|
|
703
|
+
debug$1.options("root", this.root);
|
|
704
|
+
this.options = resolveOptions(userOptions, this.root);
|
|
705
|
+
const debugOption = this.options.debug;
|
|
706
|
+
if (debugOption) {
|
|
707
|
+
const prefix = "vite-plugin-uni-pages:";
|
|
708
|
+
const suffix = typeof debugOption === "boolean" ? "*" : debugOption;
|
|
709
|
+
debug.default.enable(`${prefix}${suffix}`);
|
|
710
|
+
}
|
|
711
|
+
this.resolvedPagesJSONPath = node_path.default.join(this.root, this.options.outDir, OUTPUT_NAME);
|
|
712
|
+
debug$1.options(this.options);
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Set the Vite logger
|
|
716
|
+
* @param logger - Vite logger instance
|
|
717
|
+
*/
|
|
718
|
+
setLogger(logger) {
|
|
719
|
+
this.logger = logger;
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Load user page configuration file (e.g. pages.config.ts)
|
|
723
|
+
* Uses unconfig to load configuration, supporting multiple config file formats
|
|
724
|
+
*/
|
|
725
|
+
async loadUserPagesConfig() {
|
|
726
|
+
const configSource = this.options.configSource;
|
|
727
|
+
const { config, sources } = await (0, unconfig.loadConfig)({
|
|
728
|
+
cwd: this.root,
|
|
729
|
+
sources: configSource,
|
|
730
|
+
defaults: {}
|
|
731
|
+
});
|
|
732
|
+
this.pagesGlobConfig = config.default || config;
|
|
733
|
+
this.pagesConfigSourcePaths = sources;
|
|
734
|
+
debug$1.options(this.pagesGlobConfig);
|
|
735
|
+
}
|
|
736
|
+
/**
|
|
737
|
+
* Scan main package page directories and collect all page file paths
|
|
738
|
+
* Scan corresponding directories based on the configured dirs option
|
|
739
|
+
*/
|
|
740
|
+
async scanPages() {
|
|
741
|
+
const paths = this.options.dirs.map((dir) => {
|
|
742
|
+
return {
|
|
743
|
+
dir,
|
|
744
|
+
files: getPagePaths(dir, this.options)
|
|
745
|
+
};
|
|
746
|
+
}).map((page) => page.files).flat();
|
|
747
|
+
debug$1.pages(paths);
|
|
748
|
+
const pages = /* @__PURE__ */ new Map();
|
|
749
|
+
for (const path of paths) {
|
|
750
|
+
const page = this.pages.get(path.absolutePath) || new Page(this, path);
|
|
751
|
+
pages.set(path.absolutePath, page);
|
|
752
|
+
}
|
|
753
|
+
this.pages = pages;
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Scan sub-package page directories and collect all sub-package page file paths
|
|
757
|
+
* Scan corresponding directories based on the configured subPackages option
|
|
758
|
+
*/
|
|
759
|
+
async scanSubPages() {
|
|
760
|
+
const paths = {};
|
|
761
|
+
const subPages = /* @__PURE__ */ new Map();
|
|
762
|
+
for (const dir of this.options.subPackages) {
|
|
763
|
+
const pagePaths = getPagePaths(dir, this.options);
|
|
764
|
+
paths[dir] = pagePaths;
|
|
765
|
+
const pages = /* @__PURE__ */ new Map();
|
|
766
|
+
for (const path of pagePaths) {
|
|
767
|
+
const page = this.subPages.get(dir)?.get(path.absolutePath) || new Page(this, path);
|
|
768
|
+
pages.set(path.absolutePath, page);
|
|
769
|
+
}
|
|
770
|
+
subPages.set(dir, pages);
|
|
771
|
+
}
|
|
772
|
+
debug$1.subPages(JSON.stringify(paths, null, 2));
|
|
773
|
+
this.subPages = subPages;
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Set up Vite dev server for HMR and file watching
|
|
777
|
+
* @param server - Vite dev server instance
|
|
778
|
+
*/
|
|
779
|
+
setupViteServer(server) {
|
|
780
|
+
if (this._server === server) return;
|
|
781
|
+
this._server = server;
|
|
782
|
+
this.setupWatcher(server.watcher);
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Set up file watcher to monitor page file and config file changes
|
|
786
|
+
* Automatically update pages.json when page files or config files change
|
|
787
|
+
* @param watcher - chokidar file watcher instance
|
|
788
|
+
*/
|
|
789
|
+
async setupWatcher(watcher) {
|
|
790
|
+
watcher.add(this.pagesConfigSourcePaths);
|
|
791
|
+
const targetDirs = [...this.options.dirs, ...this.options.subPackages].map((v) => slash(node_path.default.resolve(this.root, v)));
|
|
792
|
+
const isInTargetDirs = (filePath) => targetDirs.some((v) => slash(node_path.default.resolve(this.root, filePath)).startsWith(v));
|
|
793
|
+
watcher.on("add", async (path) => {
|
|
794
|
+
path = slash(path);
|
|
795
|
+
if (!isTargetFile(path)) return;
|
|
796
|
+
if (!isInTargetDirs(path)) return;
|
|
797
|
+
debug$1.pages(`File added: ${path}`);
|
|
798
|
+
if (await this.updatePagesJSON()) this.onUpdate();
|
|
799
|
+
});
|
|
800
|
+
watcher.on("change", async (path) => {
|
|
801
|
+
path = slash(path);
|
|
802
|
+
if (!isTargetFile(path)) return;
|
|
803
|
+
if (!isInTargetDirs(path)) return;
|
|
804
|
+
debug$1.pages(`File changed: ${path}`);
|
|
805
|
+
debug$1.pages(targetDirs);
|
|
806
|
+
debug$1.pages(isInTargetDirs(path));
|
|
807
|
+
if (await this.updatePagesJSON(path)) this.onUpdate();
|
|
808
|
+
});
|
|
809
|
+
watcher.on("change", async (path) => {
|
|
810
|
+
if (this.pagesConfigSourcePaths.includes(path)) {
|
|
811
|
+
debug$1.pages(`Config source changed: ${path}`);
|
|
812
|
+
if (await this.updatePagesJSON()) this.onUpdate();
|
|
813
|
+
}
|
|
814
|
+
});
|
|
815
|
+
watcher.on("unlink", async (path) => {
|
|
816
|
+
path = slash(path);
|
|
817
|
+
if (!isTargetFile(path)) return;
|
|
818
|
+
if (!isInTargetDirs(path)) return;
|
|
819
|
+
debug$1.pages(`File removed: ${path}`);
|
|
820
|
+
if (await this.updatePagesJSON()) this.onUpdate();
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* Page update callback, triggered when page files or configuration changes
|
|
825
|
+
* Responsible for invalidating virtual modules and notifying the browser to do a full reload
|
|
826
|
+
*/
|
|
827
|
+
onUpdate() {
|
|
828
|
+
if (!this._server) return;
|
|
829
|
+
invalidatePagesModule(this._server);
|
|
830
|
+
debug$1.hmr("Reload generated pages.");
|
|
831
|
+
this._server.ws.send({ type: "full-reload" });
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* parse pages rules && set page type
|
|
835
|
+
* @param pages page path array
|
|
836
|
+
* @param type page type
|
|
837
|
+
* @param overrides custom page config
|
|
838
|
+
* @returns pages rules
|
|
839
|
+
*/
|
|
840
|
+
async parsePages(pages, type, overrides) {
|
|
841
|
+
const jobs = [];
|
|
842
|
+
for (const [_, page] of pages) jobs.push(page.getPageMeta());
|
|
843
|
+
const generatedPageMetaData = await Promise.all(jobs);
|
|
844
|
+
const customPageMetaData = overrides || [];
|
|
845
|
+
const result = customPageMetaData.length ? mergePageMetaDataArray(generatedPageMetaData.concat(customPageMetaData)) : generatedPageMetaData;
|
|
846
|
+
const parseMeta = Array.from(result.reduce((map, page) => {
|
|
847
|
+
map.set(page.path, page);
|
|
848
|
+
return map;
|
|
849
|
+
}, /* @__PURE__ */ new Map()).values());
|
|
850
|
+
return type === "main" ? this.setHomePage(parseMeta) : parseMeta;
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* set home page
|
|
854
|
+
* @param result pages rules array
|
|
855
|
+
* @returns pages rules
|
|
856
|
+
*/
|
|
857
|
+
setHomePage(result) {
|
|
858
|
+
if (!result.some(({ type }) => type === "home")) {
|
|
859
|
+
const basePath = slash(node_path.default.join(this.options.root, this.options.outDir));
|
|
860
|
+
const resolvedHomePages = this.options.homePage.map((v) => {
|
|
861
|
+
return slash(node_path.default.relative(basePath, slash(node_path.default.resolve(basePath, v))));
|
|
862
|
+
});
|
|
863
|
+
const matchHomePage = (itemPath, configPath) => {
|
|
864
|
+
if (itemPath === configPath) return true;
|
|
865
|
+
const normalizedItem = itemPath.replace(/\\/g, "/");
|
|
866
|
+
const normalizedConfig = configPath.replace(/\\/g, "/");
|
|
867
|
+
return normalizedItem.endsWith(`/${normalizedConfig}`);
|
|
868
|
+
};
|
|
869
|
+
if (!result.some((item) => {
|
|
870
|
+
const isFound = resolvedHomePages.some((expectedPath) => matchHomePage(item.path, expectedPath));
|
|
871
|
+
if (isFound) item.type = "home";
|
|
872
|
+
return isFound;
|
|
873
|
+
})) this.logger?.warn("No home page found, check the configuration of pages.config.ts, or add the `homePage` option to UniPages in vite.config.js, or add `definePage({ type: \"home\" })` in your vue page.", { timestamp: true });
|
|
874
|
+
}
|
|
875
|
+
result.sort((page) => page.type === "home" ? -1 : 0);
|
|
876
|
+
return result;
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Merge main package page metadata
|
|
880
|
+
* Filter out pages belonging to sub-packages, then parse page metadata and merge user configuration
|
|
881
|
+
*/
|
|
882
|
+
async mergePageMetaData() {
|
|
883
|
+
const subPageAbsolutePaths = Array.from(this.subPages.values()).flatMap((v) => Array.from(v.keys()));
|
|
884
|
+
for (const subPageAbsolutePath of subPageAbsolutePaths) this.pages.delete(subPageAbsolutePath);
|
|
885
|
+
const pageMetaData = await this.parsePages(this.pages, "main", this.pagesGlobConfig?.pages);
|
|
886
|
+
this.pageMetaData = pageMetaData;
|
|
887
|
+
debug$1.pages(this.pageMetaData);
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Merge sub-package page metadata
|
|
891
|
+
* Parse page metadata for each sub-package and handle sub-package configuration inheritance
|
|
892
|
+
* Preserves sub-package level properties like plugins from user config
|
|
893
|
+
*/
|
|
894
|
+
async mergeSubPageMetaData() {
|
|
895
|
+
const subPageMaps = {};
|
|
896
|
+
const subPlugins = {};
|
|
897
|
+
const subPackages = this.pagesGlobConfig?.subPackages || [];
|
|
898
|
+
for (const [dir, pages] of this.subPages) {
|
|
899
|
+
const basePath = slash(node_path.default.join(this.options.root, this.options.outDir));
|
|
900
|
+
const root = slash(node_path.default.relative(basePath, node_path.default.join(this.options.root, dir)));
|
|
901
|
+
const globPackage = subPackages?.find((v) => v.root === root);
|
|
902
|
+
subPageMaps[root] = await this.parsePages(pages, "sub", globPackage?.pages);
|
|
903
|
+
subPageMaps[root] = subPageMaps[root].map((page) => ({
|
|
904
|
+
...page,
|
|
905
|
+
path: slash(node_path.default.relative(root, page.path))
|
|
906
|
+
}));
|
|
907
|
+
if (globPackage?.plugins) subPlugins[root] = globPackage.plugins;
|
|
908
|
+
}
|
|
909
|
+
for (const { root, pages, plugins } of subPackages) if (root && !subPageMaps[root]) {
|
|
910
|
+
subPageMaps[root] = pages || [];
|
|
911
|
+
if (plugins) subPlugins[root] = plugins;
|
|
912
|
+
}
|
|
913
|
+
const subPageMetaData = Object.keys(subPageMaps).map((root) => ({
|
|
914
|
+
root,
|
|
915
|
+
pages: subPageMaps[root],
|
|
916
|
+
...subPlugins[root] && { plugins: subPlugins[root] }
|
|
917
|
+
})).filter((meta) => meta.pages.length > 0);
|
|
918
|
+
this.subPageMetaData = subPageMetaData;
|
|
919
|
+
debug$1.subPages(this.subPageMetaData);
|
|
920
|
+
}
|
|
921
|
+
/**
|
|
922
|
+
* Update pages.json file
|
|
923
|
+
* This is the core method responsible for coordinating the entire page configuration generation flow:
|
|
924
|
+
* 1. Check file changes (if filepath is specified)
|
|
925
|
+
* 2. Load user configuration
|
|
926
|
+
* 3. Scan page files
|
|
927
|
+
* 4. Merge page metadata
|
|
928
|
+
* 5. Generate and write pages.json
|
|
929
|
+
* @param filepath - Changed file path for incremental update judgment
|
|
930
|
+
* @returns Whether pages.json was successfully updated
|
|
931
|
+
*/
|
|
932
|
+
async updatePagesJSON(filepath) {
|
|
933
|
+
if (filepath) {
|
|
934
|
+
let page = this.pages.get(filepath);
|
|
935
|
+
if (!page) {
|
|
936
|
+
let subPage;
|
|
937
|
+
for (const [_, pages] of this.subPages) {
|
|
938
|
+
subPage = pages.get(filepath);
|
|
939
|
+
if (subPage) break;
|
|
940
|
+
}
|
|
941
|
+
page = subPage;
|
|
942
|
+
}
|
|
943
|
+
if (page) {
|
|
944
|
+
await page.read();
|
|
945
|
+
if (!page.hasChanged()) {
|
|
946
|
+
debug$1.cache(`The page meta on page ${filepath} did not send any changes, skipping`);
|
|
947
|
+
return false;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
checkPagesJsonFileSync(this.resolvedPagesJSONPath);
|
|
952
|
+
this.options.onBeforeLoadUserConfig(this);
|
|
953
|
+
await this.loadUserPagesConfig();
|
|
954
|
+
this.options.onAfterLoadUserConfig(this);
|
|
955
|
+
if (this.options.mergePages) {
|
|
956
|
+
this.options.onBeforeScanPages(this);
|
|
957
|
+
await this.scanPages();
|
|
958
|
+
await this.scanSubPages();
|
|
959
|
+
this.options.onAfterScanPages(this);
|
|
960
|
+
}
|
|
961
|
+
this.options.onBeforeMergePageMetaData(this);
|
|
962
|
+
await this.mergePageMetaData();
|
|
963
|
+
await this.mergeSubPageMetaData();
|
|
964
|
+
this.options.onAfterMergePageMetaData(this);
|
|
965
|
+
const pagesMap = /* @__PURE__ */ new Map();
|
|
966
|
+
(this.withUniPlatform ? this.pageMetaData.filter((v) => !/\..*$/.test(v.path) || v.path.includes(_uni_helper_uni_env.platform)).map((v) => {
|
|
967
|
+
v.path = v.path.replace(/\..*$/, "");
|
|
968
|
+
return v;
|
|
969
|
+
}) : this.pageMetaData).forEach((v) => pagesMap.set(v.path, v));
|
|
970
|
+
this.pageMetaData = [...pagesMap.values()];
|
|
971
|
+
this.options.onBeforeWriteFile(this);
|
|
972
|
+
const pagesJson = (0, comment_json.stringify)(await this.genratePagesJSON(), null, this.options.minify ? void 0 : await this.getIndent()) + (await this.getEndOfLine() ? await this.getNewline() : "");
|
|
973
|
+
this.generateDeclaration();
|
|
974
|
+
if (this.lastPagesJson === pagesJson) {
|
|
975
|
+
debug$1.pages("PagesJson Not have change");
|
|
976
|
+
return false;
|
|
977
|
+
}
|
|
978
|
+
await writeFileWithLock(this.resolvedPagesJSONPath, pagesJson);
|
|
979
|
+
this.lastPagesJson = pagesJson;
|
|
980
|
+
this.options.onAfterWriteFile(this);
|
|
981
|
+
return true;
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Generate virtual module content
|
|
985
|
+
* Returns JavaScript code containing pages and subPackages exports
|
|
986
|
+
* @returns Virtual module code string
|
|
987
|
+
*/
|
|
988
|
+
virtualModule() {
|
|
989
|
+
return [`export const pages = ${this.resolveRoutes()};`, `export const subPackages = ${this.resolveSubRoutes()};`].join("\n");
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* Resolve main package route data to JSON string
|
|
993
|
+
* @returns JSON string of main package page metadata
|
|
994
|
+
*/
|
|
995
|
+
resolveRoutes() {
|
|
996
|
+
return (0, comment_json.stringify)(this.pageMetaData.map(stripType), null, 2);
|
|
997
|
+
}
|
|
998
|
+
/**
|
|
999
|
+
* Resolve sub-package route data to JSON string
|
|
1000
|
+
* @returns JSON string of sub-package page metadata
|
|
1001
|
+
*/
|
|
1002
|
+
resolveSubRoutes() {
|
|
1003
|
+
return (0, comment_json.stringify)(this.subPageMetaData.map(({ pages, ...rest }) => ({
|
|
1004
|
+
...rest,
|
|
1005
|
+
pages: pages.map(stripType)
|
|
1006
|
+
})), null, 2);
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* Resolve tabBar configuration
|
|
1010
|
+
* Merges page-defined tabBar items with config-defined tabBar
|
|
1011
|
+
* @returns Merged tabBar configuration object, or undefined if no tabBar exists
|
|
1012
|
+
*/
|
|
1013
|
+
async resolveTabBar() {
|
|
1014
|
+
const tabBarItems = [];
|
|
1015
|
+
for (const [_, page] of this.pages) {
|
|
1016
|
+
const tabbar = await page.getTabBar();
|
|
1017
|
+
if (tabbar) tabBarItems.push(tabbar);
|
|
1018
|
+
}
|
|
1019
|
+
if (tabBarItems.length === 0) return this.pagesGlobConfig?.tabBar;
|
|
1020
|
+
const tabBar = {
|
|
1021
|
+
...this.pagesGlobConfig?.tabBar,
|
|
1022
|
+
list: this.pagesGlobConfig?.tabBar?.list || []
|
|
1023
|
+
};
|
|
1024
|
+
const pagePaths = /* @__PURE__ */ new Map();
|
|
1025
|
+
for (const item of tabBar.list) pagePaths.set(item.pagePath, true);
|
|
1026
|
+
tabBarItems.sort((a, b) => a.index - b.index);
|
|
1027
|
+
for (const item of tabBarItems) if (!pagePaths.has(item.pagePath)) {
|
|
1028
|
+
const { index: _, ...tabbar } = item;
|
|
1029
|
+
tabBar.list.push(tabbar);
|
|
1030
|
+
}
|
|
1031
|
+
return tabBar;
|
|
1032
|
+
}
|
|
1033
|
+
/**
|
|
1034
|
+
* Generate TypeScript declaration file
|
|
1035
|
+
* Generate type definitions for page paths to provide type hints during navigation
|
|
1036
|
+
*/
|
|
1037
|
+
generateDeclaration() {
|
|
1038
|
+
if (!this.options.dts) return;
|
|
1039
|
+
debug$1.declaration("generating");
|
|
1040
|
+
return writeDeclaration(this, this.options.dts);
|
|
1041
|
+
}
|
|
1042
|
+
async genratePagesJSON() {
|
|
1043
|
+
const { pages: oldPages, subPackages: oldSubPackages, tabBar: oldTabBar } = (0, comment_json.parse)(await node_fs.default.promises.readFile(this.resolvedPagesJSONPath, { encoding: "utf-8" }).catch(() => "") || "{}");
|
|
1044
|
+
const { pages: _pages, subPackages: _subPackages, tabBar: _tabBar, ...pageJson } = this.pagesGlobConfig || {};
|
|
1045
|
+
const currentPlatform = _uni_helper_uni_env.platform.toUpperCase();
|
|
1046
|
+
pageJson.pages = mergePlatformItems(oldPages, currentPlatform, this.pageMetaData, "path").map(stripType);
|
|
1047
|
+
if (pageJson.pages && pageJson.pages.length > 0) {
|
|
1048
|
+
const pagesArray = pageJson.pages;
|
|
1049
|
+
const homeIndex = pagesArray.findIndex((page) => page.type === "home");
|
|
1050
|
+
if (homeIndex > 0) {
|
|
1051
|
+
const [homePage] = pagesArray.splice(homeIndex, 1);
|
|
1052
|
+
pagesArray.unshift(homePage);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
pageJson.subPackages = oldSubPackages || new comment_json.CommentArray();
|
|
1056
|
+
const newSubPackages = /* @__PURE__ */ new Map();
|
|
1057
|
+
for (const item of this.subPageMetaData) newSubPackages.set(item.root, item);
|
|
1058
|
+
for (const existing of pageJson.subPackages) {
|
|
1059
|
+
const sub = newSubPackages.get(existing.root);
|
|
1060
|
+
if (sub) {
|
|
1061
|
+
existing.pages = mergePlatformItems(existing.pages, currentPlatform, sub.pages, "path").map(stripType);
|
|
1062
|
+
if (sub.plugins) existing.plugins = sub.plugins;
|
|
1063
|
+
newSubPackages.delete(existing.root);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
for (const [_, newSub] of newSubPackages) {
|
|
1067
|
+
const subPackage = {
|
|
1068
|
+
root: newSub.root,
|
|
1069
|
+
pages: mergePlatformItems(void 0, currentPlatform, newSub.pages, "path").map(stripType)
|
|
1070
|
+
};
|
|
1071
|
+
if (newSub.plugins) subPackage.plugins = newSub.plugins;
|
|
1072
|
+
pageJson.subPackages.push(subPackage);
|
|
1073
|
+
}
|
|
1074
|
+
const { list, ...tabBarOthers } = await this.resolveTabBar() || {};
|
|
1075
|
+
if (list) {
|
|
1076
|
+
const { list: oldList } = oldTabBar || {};
|
|
1077
|
+
const newList = mergePlatformItems(oldList, currentPlatform, list, "pagePath");
|
|
1078
|
+
pageJson.tabBar = {
|
|
1079
|
+
...tabBarOthers,
|
|
1080
|
+
list: newList
|
|
1081
|
+
};
|
|
1082
|
+
} else pageJson.tabBar = void 0;
|
|
1083
|
+
return pageJson;
|
|
1084
|
+
}
|
|
1085
|
+
async readInfoFromPagesJSON() {
|
|
1086
|
+
const resolvedPagesJSONContent = await node_fs.default.promises.readFile(this.resolvedPagesJSONPath, { encoding: "utf-8" }).catch(() => "");
|
|
1087
|
+
this.resolvedPagesJSONIndent = (0, detect_indent.default)(resolvedPagesJSONContent).indent || " ";
|
|
1088
|
+
this.resolvedPagesJSONNewline = (0, detect_newline.default)(resolvedPagesJSONContent) || "\n";
|
|
1089
|
+
this.resolvedPagesJSONEofNewline = (resolvedPagesJSONContent.at(-1) ?? "\n") === this.resolvedPagesJSONNewline;
|
|
1090
|
+
}
|
|
1091
|
+
async getIndent() {
|
|
1092
|
+
if (!this.resolvedPagesJSONIndent) await this.readInfoFromPagesJSON();
|
|
1093
|
+
return this.resolvedPagesJSONIndent;
|
|
1094
|
+
}
|
|
1095
|
+
async getNewline() {
|
|
1096
|
+
if (!this.resolvedPagesJSONNewline) await this.readInfoFromPagesJSON();
|
|
1097
|
+
return this.resolvedPagesJSONNewline;
|
|
1098
|
+
}
|
|
1099
|
+
async getEndOfLine() {
|
|
1100
|
+
if (!this.resolvedPagesJSONEofNewline) await this.readInfoFromPagesJSON();
|
|
1101
|
+
return this.resolvedPagesJSONEofNewline;
|
|
1102
|
+
}
|
|
631
1103
|
};
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
// abs path -> Page
|
|
639
|
-
__publicField(this, "subPages", /* @__PURE__ */ new Map());
|
|
640
|
-
// root -> abs path -> page
|
|
641
|
-
__publicField(this, "pageMetaData", []);
|
|
642
|
-
__publicField(this, "subPageMetaData", []);
|
|
643
|
-
__publicField(this, "resolvedPagesJSONPath", "");
|
|
644
|
-
__publicField(this, "resolvedPagesJSONIndent");
|
|
645
|
-
// ' '
|
|
646
|
-
__publicField(this, "resolvedPagesJSONNewline");
|
|
647
|
-
// '\n'
|
|
648
|
-
__publicField(this, "resolvedPagesJSONEofNewline");
|
|
649
|
-
// true
|
|
650
|
-
__publicField(this, "rawOptions");
|
|
651
|
-
__publicField(this, "root");
|
|
652
|
-
__publicField(this, "options");
|
|
653
|
-
__publicField(this, "logger");
|
|
654
|
-
__publicField(this, "withUniPlatform", false);
|
|
655
|
-
__publicField(this, "lastPagesJson", "");
|
|
656
|
-
this.rawOptions = userOptions;
|
|
657
|
-
this.root = slash(viteRoot);
|
|
658
|
-
debug.options("root", this.root);
|
|
659
|
-
this.options = resolveOptions(userOptions, this.root);
|
|
660
|
-
const debugOption = this.options.debug;
|
|
661
|
-
if (debugOption) {
|
|
662
|
-
const prefix = "vite-plugin-uni-pages:";
|
|
663
|
-
const suffix = typeof debugOption === "boolean" ? "*" : debugOption;
|
|
664
|
-
Debug__default.enable(`${prefix}${suffix}`);
|
|
665
|
-
}
|
|
666
|
-
this.resolvedPagesJSONPath = path__default.join(this.root, this.options.outDir, OUTPUT_NAME);
|
|
667
|
-
debug.options(this.options);
|
|
668
|
-
}
|
|
669
|
-
setLogger(logger) {
|
|
670
|
-
this.logger = logger;
|
|
671
|
-
}
|
|
672
|
-
async loadUserPagesConfig() {
|
|
673
|
-
const configSource = this.options.configSource;
|
|
674
|
-
const { config, sources } = await unconfig.loadConfig({ cwd: this.root, sources: configSource, defaults: {} });
|
|
675
|
-
this.pagesGlobConfig = config.default || config;
|
|
676
|
-
this.pagesConfigSourcePaths = sources;
|
|
677
|
-
debug.options(this.pagesGlobConfig);
|
|
678
|
-
}
|
|
679
|
-
async scanPages() {
|
|
680
|
-
const pageDirFiles = this.options.dirs.map((dir) => {
|
|
681
|
-
return { dir, files: getPagePaths(dir, this.options) };
|
|
682
|
-
});
|
|
683
|
-
const paths = pageDirFiles.map((page) => page.files).flat();
|
|
684
|
-
debug.pages(paths);
|
|
685
|
-
const pages = /* @__PURE__ */ new Map();
|
|
686
|
-
for (const path2 of paths) {
|
|
687
|
-
const page = this.pages.get(path2.absolutePath) || new Page(this, path2);
|
|
688
|
-
pages.set(path2.absolutePath, page);
|
|
689
|
-
}
|
|
690
|
-
this.pages = pages;
|
|
691
|
-
}
|
|
692
|
-
async scanSubPages() {
|
|
693
|
-
const paths = {};
|
|
694
|
-
const subPages = /* @__PURE__ */ new Map();
|
|
695
|
-
for (const dir of this.options.subPackages) {
|
|
696
|
-
const pagePaths = getPagePaths(dir, this.options);
|
|
697
|
-
paths[dir] = pagePaths;
|
|
698
|
-
const pages = /* @__PURE__ */ new Map();
|
|
699
|
-
for (const path2 of pagePaths) {
|
|
700
|
-
const page = this.subPages.get(dir)?.get(path2.absolutePath) || new Page(this, path2);
|
|
701
|
-
pages.set(path2.absolutePath, page);
|
|
702
|
-
}
|
|
703
|
-
subPages.set(dir, pages);
|
|
704
|
-
}
|
|
705
|
-
debug.subPages(JSON.stringify(paths, null, 2));
|
|
706
|
-
this.subPages = subPages;
|
|
707
|
-
}
|
|
708
|
-
setupViteServer(server) {
|
|
709
|
-
if (this._server === server)
|
|
710
|
-
return;
|
|
711
|
-
this._server = server;
|
|
712
|
-
this.setupWatcher(server.watcher);
|
|
713
|
-
}
|
|
714
|
-
async setupWatcher(watcher) {
|
|
715
|
-
watcher.add(this.pagesConfigSourcePaths);
|
|
716
|
-
const targetDirs = [...this.options.dirs, ...this.options.subPackages].map((v) => slash(path__default.resolve(this.root, v)));
|
|
717
|
-
const isInTargetDirs = (filePath) => targetDirs.some((v) => slash(path__default.resolve(this.root, filePath)).startsWith(v));
|
|
718
|
-
watcher.on("add", async (path2) => {
|
|
719
|
-
path2 = slash(path2);
|
|
720
|
-
if (!isTargetFile(path2))
|
|
721
|
-
return;
|
|
722
|
-
if (!isInTargetDirs(path2))
|
|
723
|
-
return;
|
|
724
|
-
debug.pages(`File added: ${path2}`);
|
|
725
|
-
if (await this.updatePagesJSON())
|
|
726
|
-
this.onUpdate();
|
|
727
|
-
});
|
|
728
|
-
watcher.on("change", async (path2) => {
|
|
729
|
-
path2 = slash(path2);
|
|
730
|
-
if (!isTargetFile(path2))
|
|
731
|
-
return;
|
|
732
|
-
if (!isInTargetDirs(path2))
|
|
733
|
-
return;
|
|
734
|
-
debug.pages(`File changed: ${path2}`);
|
|
735
|
-
debug.pages(targetDirs);
|
|
736
|
-
debug.pages(isInTargetDirs(path2));
|
|
737
|
-
if (await this.updatePagesJSON(path2))
|
|
738
|
-
this.onUpdate();
|
|
739
|
-
});
|
|
740
|
-
watcher.on("change", async (path2) => {
|
|
741
|
-
if (this.pagesConfigSourcePaths.includes(path2)) {
|
|
742
|
-
debug.pages(`Config source changed: ${path2}`);
|
|
743
|
-
if (await this.updatePagesJSON())
|
|
744
|
-
this.onUpdate();
|
|
745
|
-
}
|
|
746
|
-
});
|
|
747
|
-
watcher.on("unlink", async (path2) => {
|
|
748
|
-
path2 = slash(path2);
|
|
749
|
-
if (!isTargetFile(path2))
|
|
750
|
-
return;
|
|
751
|
-
if (!isInTargetDirs(path2))
|
|
752
|
-
return;
|
|
753
|
-
debug.pages(`File removed: ${path2}`);
|
|
754
|
-
if (await this.updatePagesJSON())
|
|
755
|
-
this.onUpdate();
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
onUpdate() {
|
|
759
|
-
if (!this._server)
|
|
760
|
-
return;
|
|
761
|
-
invalidatePagesModule(this._server);
|
|
762
|
-
debug.hmr("Reload generated pages.");
|
|
763
|
-
this._server.ws.send({
|
|
764
|
-
type: "full-reload"
|
|
765
|
-
});
|
|
766
|
-
}
|
|
767
|
-
/**
|
|
768
|
-
* parse pages rules && set page type
|
|
769
|
-
* @param pages page path array
|
|
770
|
-
* @param type page type
|
|
771
|
-
* @param overrides custom page config
|
|
772
|
-
* @returns pages rules
|
|
773
|
-
*/
|
|
774
|
-
async parsePages(pages, type, overrides) {
|
|
775
|
-
const jobs = [];
|
|
776
|
-
for (const [_, page] of pages) {
|
|
777
|
-
jobs.push(page.getPageMeta());
|
|
778
|
-
}
|
|
779
|
-
const generatedPageMetaData = await Promise.all(jobs);
|
|
780
|
-
const customPageMetaData = overrides || [];
|
|
781
|
-
const result = customPageMetaData.length ? mergePageMetaDataArray(generatedPageMetaData.concat(customPageMetaData)) : generatedPageMetaData;
|
|
782
|
-
const parseMeta = Array.from(
|
|
783
|
-
result.reduce((map, page) => {
|
|
784
|
-
map.set(page.path, page);
|
|
785
|
-
return map;
|
|
786
|
-
}, /* @__PURE__ */ new Map()).values()
|
|
787
|
-
);
|
|
788
|
-
return type === "main" ? this.setHomePage(parseMeta) : parseMeta;
|
|
789
|
-
}
|
|
790
|
-
/**
|
|
791
|
-
* set home page
|
|
792
|
-
* @param result pages rules array
|
|
793
|
-
* @returns pages rules
|
|
794
|
-
*/
|
|
795
|
-
setHomePage(result) {
|
|
796
|
-
const hasHome = result.some(({ type }) => type === "home");
|
|
797
|
-
if (!hasHome) {
|
|
798
|
-
const isFoundHome = result.some((item) => {
|
|
799
|
-
const isFound = this.options.homePage.find((v) => v === item.path);
|
|
800
|
-
if (isFound)
|
|
801
|
-
item.type = "home";
|
|
802
|
-
return isFound;
|
|
803
|
-
});
|
|
804
|
-
if (!isFoundHome) {
|
|
805
|
-
this.logger?.warn('No home page found, check the configuration of pages.config.ts, or add the `homePage` option to UniPages in vite.config.js, or add `type="home"` to the routeBlock of your vue page.', {
|
|
806
|
-
timestamp: true
|
|
807
|
-
});
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
result.sort((page) => page.type === "home" ? -1 : 0);
|
|
811
|
-
return result;
|
|
812
|
-
}
|
|
813
|
-
async mergePageMetaData() {
|
|
814
|
-
const subPageAbsolutePaths = Array.from(this.subPages.values()).flatMap((v) => Array.from(v.keys()));
|
|
815
|
-
for (const subPageAbsolutePath of subPageAbsolutePaths)
|
|
816
|
-
this.pages.delete(subPageAbsolutePath);
|
|
817
|
-
const pageMetaData = await this.parsePages(this.pages, "main", this.pagesGlobConfig?.pages);
|
|
818
|
-
this.pageMetaData = pageMetaData;
|
|
819
|
-
debug.pages(this.pageMetaData);
|
|
820
|
-
}
|
|
821
|
-
async mergeSubPageMetaData() {
|
|
822
|
-
const subPageMaps = {};
|
|
823
|
-
const subPackages = this.pagesGlobConfig?.subPackages || [];
|
|
824
|
-
for (const [dir, pages] of this.subPages) {
|
|
825
|
-
const basePath = slash(path__default.join(this.options.root, this.options.outDir));
|
|
826
|
-
const root = slash(path__default.relative(basePath, path__default.join(this.options.root, dir)));
|
|
827
|
-
const globPackage = subPackages?.find((v) => v.root === root);
|
|
828
|
-
subPageMaps[root] = await this.parsePages(pages, "sub", globPackage?.pages);
|
|
829
|
-
subPageMaps[root] = subPageMaps[root].map((page) => ({ ...page, path: slash(path__default.relative(root, page.path)) }));
|
|
830
|
-
}
|
|
831
|
-
for (const { root, pages } of subPackages) {
|
|
832
|
-
if (root && !subPageMaps[root])
|
|
833
|
-
subPageMaps[root] = pages || [];
|
|
834
|
-
}
|
|
835
|
-
const subPageMetaData = Object.keys(subPageMaps).map((root) => ({ root, pages: subPageMaps[root] })).filter((meta) => meta.pages.length > 0);
|
|
836
|
-
this.subPageMetaData = subPageMetaData;
|
|
837
|
-
debug.subPages(this.subPageMetaData);
|
|
838
|
-
}
|
|
839
|
-
async getTabBarMerged() {
|
|
840
|
-
const tabBarItems = [];
|
|
841
|
-
for (const [_, page] of this.pages) {
|
|
842
|
-
const tabbar = await page.getTabBar();
|
|
843
|
-
if (tabbar) {
|
|
844
|
-
tabBarItems.push(tabbar);
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
if (tabBarItems.length === 0) {
|
|
848
|
-
return this.pagesGlobConfig?.tabBar;
|
|
849
|
-
}
|
|
850
|
-
const tabBar = {
|
|
851
|
-
...this.pagesGlobConfig?.tabBar,
|
|
852
|
-
list: this.pagesGlobConfig?.tabBar?.list || []
|
|
853
|
-
};
|
|
854
|
-
const pagePaths = /* @__PURE__ */ new Map();
|
|
855
|
-
for (const item of tabBar.list) {
|
|
856
|
-
pagePaths.set(item.pagePath, true);
|
|
857
|
-
}
|
|
858
|
-
tabBarItems.sort((a, b) => a.index - b.index);
|
|
859
|
-
for (const item of tabBarItems) {
|
|
860
|
-
if (!pagePaths.has(item.pagePath)) {
|
|
861
|
-
const { index: _, ...tabbar } = item;
|
|
862
|
-
tabBar.list.push(tabbar);
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
return tabBar;
|
|
866
|
-
}
|
|
867
|
-
async updatePagesJSON(filepath) {
|
|
868
|
-
if (filepath) {
|
|
869
|
-
let page = this.pages.get(filepath);
|
|
870
|
-
if (!page) {
|
|
871
|
-
let subPage;
|
|
872
|
-
for (const [_, pages2] of this.subPages) {
|
|
873
|
-
subPage = pages2.get(filepath);
|
|
874
|
-
if (subPage) {
|
|
875
|
-
break;
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
page = subPage;
|
|
879
|
-
}
|
|
880
|
-
if (page) {
|
|
881
|
-
await page.read();
|
|
882
|
-
if (!page.hasChanged()) {
|
|
883
|
-
debug.cache(`The route block on page ${filepath} did not send any changes, skipping`);
|
|
884
|
-
return false;
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
checkPagesJsonFileSync(this.resolvedPagesJSONPath);
|
|
889
|
-
this.options.onBeforeLoadUserConfig(this);
|
|
890
|
-
await this.loadUserPagesConfig();
|
|
891
|
-
this.options.onAfterLoadUserConfig(this);
|
|
892
|
-
if (this.options.mergePages) {
|
|
893
|
-
this.options.onBeforeScanPages(this);
|
|
894
|
-
await this.scanPages();
|
|
895
|
-
await this.scanSubPages();
|
|
896
|
-
this.options.onAfterScanPages(this);
|
|
897
|
-
}
|
|
898
|
-
this.options.onBeforeMergePageMetaData(this);
|
|
899
|
-
await this.mergePageMetaData();
|
|
900
|
-
await this.mergeSubPageMetaData();
|
|
901
|
-
this.options.onAfterMergePageMetaData(this);
|
|
902
|
-
const pagesMap = /* @__PURE__ */ new Map();
|
|
903
|
-
const pages = this.withUniPlatform ? this.pageMetaData.filter((v) => !/\..*$/.test(v.path) || v.path.includes(uniEnv.platform)).map((v) => {
|
|
904
|
-
v.path = v.path.replace(/\..*$/, "");
|
|
905
|
-
return v;
|
|
906
|
-
}) : this.pageMetaData;
|
|
907
|
-
pages.forEach((v) => pagesMap.set(v.path, v));
|
|
908
|
-
this.pageMetaData = [...pagesMap.values()];
|
|
909
|
-
this.options.onBeforeWriteFile(this);
|
|
910
|
-
const data = await this.genratePagesJSON();
|
|
911
|
-
const pagesJson = commentJson.stringify(
|
|
912
|
-
data,
|
|
913
|
-
null,
|
|
914
|
-
this.options.minify ? void 0 : await this.getIndent()
|
|
915
|
-
) + (await this.getEndOfLine() ? await this.getNewline() : "");
|
|
916
|
-
this.generateDeclaration();
|
|
917
|
-
if (this.lastPagesJson === pagesJson) {
|
|
918
|
-
debug.pages("PagesJson Not have change");
|
|
919
|
-
return false;
|
|
920
|
-
}
|
|
921
|
-
await writeFileWithLock(this.resolvedPagesJSONPath, pagesJson);
|
|
922
|
-
this.lastPagesJson = pagesJson;
|
|
923
|
-
this.options.onAfterWriteFile(this);
|
|
924
|
-
return true;
|
|
925
|
-
}
|
|
926
|
-
virtualModule() {
|
|
927
|
-
const pages = `export const pages = ${this.resolveRoutes()};`;
|
|
928
|
-
const subPackages = `export const subPackages = ${this.resolveSubRoutes()};`;
|
|
929
|
-
return [pages, subPackages].join("\n");
|
|
930
|
-
}
|
|
931
|
-
resolveRoutes() {
|
|
932
|
-
return commentJson.stringify(this.pageMetaData, null, 2);
|
|
933
|
-
}
|
|
934
|
-
resolveSubRoutes() {
|
|
935
|
-
return commentJson.stringify(this.subPageMetaData, null, 2);
|
|
936
|
-
}
|
|
937
|
-
generateDeclaration() {
|
|
938
|
-
if (!this.options.dts)
|
|
939
|
-
return;
|
|
940
|
-
debug.declaration("generating");
|
|
941
|
-
return writeDeclaration(this, this.options.dts);
|
|
942
|
-
}
|
|
943
|
-
async genratePagesJSON() {
|
|
944
|
-
const content = await fs__default.promises.readFile(this.resolvedPagesJSONPath, { encoding: "utf-8" }).catch(() => "");
|
|
945
|
-
const { pages: oldPages, subPackages: oldSubPackages, tabBar: oldTabBar } = commentJson.parse(content || "{}");
|
|
946
|
-
const { pages: _, subPackages: __, tabBar: ___, ...pageJson } = this.pagesGlobConfig || {};
|
|
947
|
-
const currentPlatform = uniEnv.platform.toUpperCase();
|
|
948
|
-
pageJson.pages = mergePlatformItems(oldPages, currentPlatform, this.pageMetaData, "path");
|
|
949
|
-
pageJson.subPackages = oldSubPackages || new commentJson.CommentArray();
|
|
950
|
-
const newSubPackages = /* @__PURE__ */ new Map();
|
|
951
|
-
for (const item of this.subPageMetaData) {
|
|
952
|
-
newSubPackages.set(item.root, item);
|
|
953
|
-
}
|
|
954
|
-
for (const existing of pageJson.subPackages) {
|
|
955
|
-
const sub = newSubPackages.get(existing.root);
|
|
956
|
-
if (sub) {
|
|
957
|
-
existing.pages = mergePlatformItems(existing.pages, currentPlatform, sub.pages, "path");
|
|
958
|
-
newSubPackages.delete(existing.root);
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
for (const [_2, newSub] of newSubPackages) {
|
|
962
|
-
pageJson.subPackages.push({
|
|
963
|
-
root: newSub.root,
|
|
964
|
-
pages: mergePlatformItems(void 0, currentPlatform, newSub.pages, "path")
|
|
965
|
-
});
|
|
966
|
-
}
|
|
967
|
-
const { list, ...tabBarOthers } = await this.getTabBarMerged() || {};
|
|
968
|
-
if (list) {
|
|
969
|
-
const { list: oldList } = oldTabBar || {};
|
|
970
|
-
const newList = mergePlatformItems(oldList, currentPlatform, list, "pagePath");
|
|
971
|
-
pageJson.tabBar = {
|
|
972
|
-
...tabBarOthers,
|
|
973
|
-
// 每次都直接更新除 list 外的其他属性
|
|
974
|
-
list: newList
|
|
975
|
-
};
|
|
976
|
-
} else {
|
|
977
|
-
pageJson.tabBar = void 0;
|
|
978
|
-
}
|
|
979
|
-
return pageJson;
|
|
980
|
-
}
|
|
981
|
-
async readInfoFromPagesJSON() {
|
|
982
|
-
const resolvedPagesJSONContent = await fs__default.promises.readFile(this.resolvedPagesJSONPath, { encoding: "utf-8" }).catch(() => "");
|
|
983
|
-
this.resolvedPagesJSONIndent = detectIndent__default(resolvedPagesJSONContent).indent || " ";
|
|
984
|
-
this.resolvedPagesJSONNewline = detectNewline__default(resolvedPagesJSONContent) || "\n";
|
|
985
|
-
this.resolvedPagesJSONEofNewline = (resolvedPagesJSONContent.at(-1) ?? "\n") === this.resolvedPagesJSONNewline;
|
|
986
|
-
}
|
|
987
|
-
async getIndent() {
|
|
988
|
-
if (!this.resolvedPagesJSONIndent) {
|
|
989
|
-
await this.readInfoFromPagesJSON();
|
|
990
|
-
}
|
|
991
|
-
return this.resolvedPagesJSONIndent;
|
|
992
|
-
}
|
|
993
|
-
async getNewline() {
|
|
994
|
-
if (!this.resolvedPagesJSONNewline) {
|
|
995
|
-
await this.readInfoFromPagesJSON();
|
|
996
|
-
}
|
|
997
|
-
return this.resolvedPagesJSONNewline;
|
|
998
|
-
}
|
|
999
|
-
async getEndOfLine() {
|
|
1000
|
-
if (!this.resolvedPagesJSONEofNewline) {
|
|
1001
|
-
await this.readInfoFromPagesJSON();
|
|
1002
|
-
}
|
|
1003
|
-
return this.resolvedPagesJSONEofNewline;
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Get all page paths in the specified directory
|
|
1106
|
+
* @param dir - Page directory path
|
|
1107
|
+
* @param options - Resolved configuration options
|
|
1108
|
+
* @returns Page path array containing relative and absolute paths
|
|
1109
|
+
*/
|
|
1006
1110
|
function getPagePaths(dir, options) {
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
return pagePaths;
|
|
1111
|
+
const pagesDirPath = slash(node_path.default.resolve(options.root, dir));
|
|
1112
|
+
const basePath = slash(node_path.default.join(options.root, options.outDir));
|
|
1113
|
+
const files = getPageFiles(pagesDirPath, options);
|
|
1114
|
+
debug$1.pages(dir, files);
|
|
1115
|
+
return files.map((file) => slash(file)).map((file) => ({
|
|
1116
|
+
relativePath: node_path.default.relative(basePath, slash(node_path.default.resolve(pagesDirPath, file))),
|
|
1117
|
+
absolutePath: slash(node_path.default.resolve(pagesDirPath, file))
|
|
1118
|
+
}));
|
|
1016
1119
|
}
|
|
1120
|
+
/**
|
|
1121
|
+
* Merge multi-platform page configuration items
|
|
1122
|
+
* Handle conditional compilation comments (#ifdef / #endif), merge configuration items from different platforms into one array
|
|
1123
|
+
* Same configuration items will automatically merge platform identifiers, different configuration items will keep conditional compilation comments
|
|
1124
|
+
*
|
|
1125
|
+
* @param source - Existing configuration item array (from pages.json)
|
|
1126
|
+
* @param currentPlatform - Current platform identifier (e.g. H5, MP-WEIXIN)
|
|
1127
|
+
* @param items - New configuration item array
|
|
1128
|
+
* @param uniqueKeyName - Field name used to identify configuration item uniqueness (e.g. 'path' or 'pagePath')
|
|
1129
|
+
* @returns Merged configuration item array with conditional compilation comments
|
|
1130
|
+
*/
|
|
1017
1131
|
function mergePlatformItems(source, currentPlatform, items, uniqueKeyName) {
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1132
|
+
const src = source || new comment_json.CommentArray();
|
|
1133
|
+
currentPlatform = currentPlatform.toUpperCase();
|
|
1134
|
+
let lastPlatforms = [];
|
|
1135
|
+
for (const comment of src[Symbol.for("before:0")] || []) {
|
|
1136
|
+
const trimed = comment.value.trim();
|
|
1137
|
+
if (trimed.startsWith("GENERATED BY UNI-PAGES, PLATFORM:")) lastPlatforms = trimed.split(":")[1].split("||").map((s) => s.trim()).filter((s) => s !== currentPlatform).sort();
|
|
1138
|
+
}
|
|
1139
|
+
const tmpMap = /* @__PURE__ */ new Map();
|
|
1140
|
+
for (let i = 0; i < src.length; i++) {
|
|
1141
|
+
const item = src[i];
|
|
1142
|
+
const uniqueKey = item[uniqueKeyName];
|
|
1143
|
+
if (!uniqueKey) continue;
|
|
1144
|
+
const ifdefComment = src[Symbol.for(`before:${i}`)]?.find((c) => c.value.trim().startsWith("#ifdef"));
|
|
1145
|
+
let platforms = [...lastPlatforms];
|
|
1146
|
+
if (ifdefComment) {
|
|
1147
|
+
const match = ifdefComment.value.match(/#ifdef\s+(.+)/);
|
|
1148
|
+
if (match) platforms = match[1].split("||").map((p) => p.trim()).filter((s) => s !== currentPlatform).sort();
|
|
1149
|
+
}
|
|
1150
|
+
if (platforms.length === 0) continue;
|
|
1151
|
+
const existing = tmpMap.get(uniqueKey) || [];
|
|
1152
|
+
existing.push({
|
|
1153
|
+
item,
|
|
1154
|
+
itemStr: JSON.stringify(item),
|
|
1155
|
+
platforms,
|
|
1156
|
+
platformStr: platforms.join(" || ")
|
|
1157
|
+
});
|
|
1158
|
+
tmpMap.set(uniqueKey, existing);
|
|
1159
|
+
}
|
|
1160
|
+
for (const item of items) {
|
|
1161
|
+
const newItem = item;
|
|
1162
|
+
const uniqueKey = item[uniqueKeyName];
|
|
1163
|
+
if (!uniqueKey) continue;
|
|
1164
|
+
if (!tmpMap.has(uniqueKey)) {
|
|
1165
|
+
tmpMap.set(uniqueKey, [{
|
|
1166
|
+
item: newItem,
|
|
1167
|
+
itemStr: JSON.stringify(newItem),
|
|
1168
|
+
platforms: [currentPlatform],
|
|
1169
|
+
platformStr: currentPlatform
|
|
1170
|
+
}]);
|
|
1171
|
+
continue;
|
|
1172
|
+
}
|
|
1173
|
+
const existing = tmpMap.get(uniqueKey);
|
|
1174
|
+
const newItemStr = JSON.stringify(newItem);
|
|
1175
|
+
const equalObj = existing.find((val) => val.itemStr === newItemStr);
|
|
1176
|
+
if (equalObj) {
|
|
1177
|
+
equalObj.platforms.push(currentPlatform);
|
|
1178
|
+
equalObj.platforms.sort();
|
|
1179
|
+
equalObj.platformStr = equalObj.platforms.join(" || ");
|
|
1180
|
+
} else existing.push({
|
|
1181
|
+
item: newItem,
|
|
1182
|
+
itemStr: newItemStr,
|
|
1183
|
+
platforms: [currentPlatform],
|
|
1184
|
+
platformStr: currentPlatform
|
|
1185
|
+
});
|
|
1186
|
+
}
|
|
1187
|
+
const result = new comment_json.CommentArray();
|
|
1188
|
+
const platformUsage = {};
|
|
1189
|
+
tmpMap.forEach((val) => {
|
|
1190
|
+
Object.values(val).forEach((v) => {
|
|
1191
|
+
platformUsage[v.platformStr] = (platformUsage[v.platformStr] || 0) + 1;
|
|
1192
|
+
});
|
|
1193
|
+
});
|
|
1194
|
+
const usageKeys = Object.keys(platformUsage);
|
|
1195
|
+
const defaultPlatformStr = usageKeys.length ? usageKeys.reduce((a, b) => platformUsage[a] > platformUsage[b] ? a : b) : currentPlatform;
|
|
1196
|
+
result[Symbol.for("before:0")] = [{
|
|
1197
|
+
type: "LineComment",
|
|
1198
|
+
value: ` GENERATED BY UNI-PAGES, PLATFORM: ${defaultPlatformStr}`,
|
|
1199
|
+
inline: false,
|
|
1200
|
+
loc: {
|
|
1201
|
+
start: {
|
|
1202
|
+
line: 0,
|
|
1203
|
+
column: 0
|
|
1204
|
+
},
|
|
1205
|
+
end: {
|
|
1206
|
+
line: 0,
|
|
1207
|
+
column: 0
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
}];
|
|
1211
|
+
for (const [_, list] of tmpMap) for (const { item, platformStr } of list) {
|
|
1212
|
+
result.push(item);
|
|
1213
|
+
if (platformStr !== defaultPlatformStr) {
|
|
1214
|
+
result[Symbol.for(`before:${result.length - 1}`)] = [{
|
|
1215
|
+
type: "LineComment",
|
|
1216
|
+
value: ` #ifdef ${platformStr}`,
|
|
1217
|
+
inline: false,
|
|
1218
|
+
loc: {
|
|
1219
|
+
start: {
|
|
1220
|
+
line: 0,
|
|
1221
|
+
column: 0
|
|
1222
|
+
},
|
|
1223
|
+
end: {
|
|
1224
|
+
line: 0,
|
|
1225
|
+
column: 0
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
}];
|
|
1229
|
+
result[Symbol.for(`after:${result.length - 1}`)] = [{
|
|
1230
|
+
type: "LineComment",
|
|
1231
|
+
value: " #endif",
|
|
1232
|
+
inline: false,
|
|
1233
|
+
loc: {
|
|
1234
|
+
start: {
|
|
1235
|
+
line: 0,
|
|
1236
|
+
column: 0
|
|
1237
|
+
},
|
|
1238
|
+
end: {
|
|
1239
|
+
line: 0,
|
|
1240
|
+
column: 0
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
}];
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
return result;
|
|
1125
1247
|
}
|
|
1126
|
-
|
|
1248
|
+
//#endregion
|
|
1249
|
+
//#region src/config/index.ts
|
|
1250
|
+
/**
|
|
1251
|
+
* Define uni-pages configuration
|
|
1252
|
+
* Used in pages.config.ts configuration file to provide type hints and validation
|
|
1253
|
+
*
|
|
1254
|
+
* @param config - Page configuration object
|
|
1255
|
+
* @returns Configuration object
|
|
1256
|
+
*/
|
|
1127
1257
|
function defineUniPages(config) {
|
|
1128
|
-
|
|
1258
|
+
return config;
|
|
1129
1259
|
}
|
|
1130
|
-
|
|
1260
|
+
/**
|
|
1261
|
+
* vite-plugin-uni-pages plugin main entry
|
|
1262
|
+
*
|
|
1263
|
+
* Automatically scan page directories and generate pages.json configuration file
|
|
1264
|
+
* Support definePage macro for defining page metadata
|
|
1265
|
+
* Support multi-platform conditional compilation
|
|
1266
|
+
* Support sub-package configuration
|
|
1267
|
+
* Support TypeScript declaration file generation
|
|
1268
|
+
*
|
|
1269
|
+
* @param userOptions - User configuration options
|
|
1270
|
+
* @returns Vite plugin instance
|
|
1271
|
+
*/
|
|
1131
1272
|
function VitePluginUniPages(userOptions = {}) {
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
map: s.generateMap({
|
|
1196
|
-
source: id,
|
|
1197
|
-
includeContent: true,
|
|
1198
|
-
file: `${id}.map`
|
|
1199
|
-
})
|
|
1200
|
-
};
|
|
1201
|
-
}
|
|
1202
|
-
},
|
|
1203
|
-
configureServer(server) {
|
|
1204
|
-
ctx.setupViteServer(server);
|
|
1205
|
-
},
|
|
1206
|
-
resolveId(id) {
|
|
1207
|
-
if (id === MODULE_ID_VIRTUAL)
|
|
1208
|
-
return RESOLVED_MODULE_ID_VIRTUAL;
|
|
1209
|
-
},
|
|
1210
|
-
load(id) {
|
|
1211
|
-
if (id === RESOLVED_MODULE_ID_VIRTUAL)
|
|
1212
|
-
return ctx.virtualModule();
|
|
1213
|
-
}
|
|
1214
|
-
};
|
|
1273
|
+
let ctx;
|
|
1274
|
+
checkPagesJsonFileSync(node_path.default.join(node_process.default.env.VITE_ROOT_DIR || node_process.default.cwd(), userOptions.outDir ?? "src", OUTPUT_NAME));
|
|
1275
|
+
return {
|
|
1276
|
+
name: "vite-plugin-uni-pages",
|
|
1277
|
+
enforce: "pre",
|
|
1278
|
+
/**
|
|
1279
|
+
* Vite configResolved hook
|
|
1280
|
+
* Initialize PageContext, set logger, generate initial pages.json
|
|
1281
|
+
*/
|
|
1282
|
+
async configResolved(config) {
|
|
1283
|
+
ctx = new PageContext(userOptions, config.root);
|
|
1284
|
+
if (config.plugins.some((v) => v.name === "vite-plugin-uni-platform")) ctx.withUniPlatform = true;
|
|
1285
|
+
const logger = (0, vite.createLogger)(void 0, { prefix: "[vite-plugin-uni-pages]" });
|
|
1286
|
+
ctx.setLogger(logger);
|
|
1287
|
+
await ctx.updatePagesJSON();
|
|
1288
|
+
if (config.command === "build") {
|
|
1289
|
+
if (config.build.watch) ctx.setupWatcher(chokidar.default.watch([...ctx.options.dirs, ...ctx.options.subPackages]));
|
|
1290
|
+
}
|
|
1291
|
+
},
|
|
1292
|
+
/**
|
|
1293
|
+
* Code transform hook
|
|
1294
|
+
* Remove definePage macro calls from Vue SFC to avoid runtime errors
|
|
1295
|
+
*/
|
|
1296
|
+
async transform(code, id) {
|
|
1297
|
+
if (!FILE_EXTENSIONS.some((ext) => id.endsWith(ext))) return null;
|
|
1298
|
+
const sfc = parseSFC(code, { filename: id });
|
|
1299
|
+
let macro;
|
|
1300
|
+
if (sfc.scriptSetup) macro = findMacro((0, ast_kit.babelParse)(sfc.scriptSetup.content, sfc.scriptSetup.lang || "js").body, sfc.filename);
|
|
1301
|
+
if (!macro && sfc.script) macro = findMacro((0, ast_kit.babelParse)(sfc.script.content, sfc.script.lang || "js").body, sfc.filename);
|
|
1302
|
+
if (!macro) return null;
|
|
1303
|
+
const s = new magic_string.default(code);
|
|
1304
|
+
s.remove(macro.start, macro.end);
|
|
1305
|
+
if (s.hasChanged()) return {
|
|
1306
|
+
code: s.toString(),
|
|
1307
|
+
map: s.generateMap({
|
|
1308
|
+
source: id,
|
|
1309
|
+
includeContent: true,
|
|
1310
|
+
file: `${id}.map`
|
|
1311
|
+
})
|
|
1312
|
+
};
|
|
1313
|
+
},
|
|
1314
|
+
/**
|
|
1315
|
+
* Configure server hook
|
|
1316
|
+
* Set up file watching and HMR support
|
|
1317
|
+
*/
|
|
1318
|
+
configureServer(server) {
|
|
1319
|
+
ctx.setupViteServer(server);
|
|
1320
|
+
},
|
|
1321
|
+
/**
|
|
1322
|
+
* Module resolution hook
|
|
1323
|
+
* Resolve virtual module identifier to internal path
|
|
1324
|
+
*/
|
|
1325
|
+
resolveId(id) {
|
|
1326
|
+
if (id === "virtual:uni-pages") return RESOLVED_MODULE_ID_VIRTUAL;
|
|
1327
|
+
},
|
|
1328
|
+
/**
|
|
1329
|
+
* Module load hook
|
|
1330
|
+
* Return the code content of the virtual module
|
|
1331
|
+
*/
|
|
1332
|
+
load(id) {
|
|
1333
|
+
if (id === RESOLVED_MODULE_ID_VIRTUAL) return ctx.virtualModule();
|
|
1334
|
+
}
|
|
1335
|
+
};
|
|
1215
1336
|
}
|
|
1216
|
-
|
|
1337
|
+
//#endregion
|
|
1217
1338
|
exports.FILE_EXTENSIONS = FILE_EXTENSIONS;
|
|
1218
1339
|
exports.MODULE_ID_VIRTUAL = MODULE_ID_VIRTUAL;
|
|
1219
1340
|
exports.OUTPUT_NAME = OUTPUT_NAME;
|
|
@@ -1221,26 +1342,37 @@ exports.Page = Page;
|
|
|
1221
1342
|
exports.PageContext = PageContext;
|
|
1222
1343
|
exports.RESOLVED_MODULE_ID_VIRTUAL = RESOLVED_MODULE_ID_VIRTUAL;
|
|
1223
1344
|
exports.VitePluginUniPages = VitePluginUniPages;
|
|
1345
|
+
exports.default = VitePluginUniPages;
|
|
1224
1346
|
exports.babelGenerate = babelGenerate;
|
|
1225
1347
|
exports.checkPagesJsonFileSync = checkPagesJsonFileSync;
|
|
1226
|
-
exports.debug = debug;
|
|
1227
|
-
exports
|
|
1348
|
+
exports.debug = debug$1;
|
|
1349
|
+
Object.defineProperty(exports, "definePage", {
|
|
1350
|
+
enumerable: true,
|
|
1351
|
+
get: function() {
|
|
1352
|
+
return _uni_helper_uni_pages_types.definePage;
|
|
1353
|
+
}
|
|
1354
|
+
});
|
|
1228
1355
|
exports.defineUniPages = defineUniPages;
|
|
1229
1356
|
exports.extsToGlob = extsToGlob;
|
|
1230
1357
|
exports.findImports = findImports;
|
|
1231
1358
|
exports.findMacro = findMacro;
|
|
1232
1359
|
exports.getPageFiles = getPageFiles;
|
|
1233
|
-
exports.getRouteBlock = getRouteBlock;
|
|
1234
|
-
exports.getRouteSfcBlock = getRouteSfcBlock;
|
|
1235
1360
|
exports.invalidatePagesModule = invalidatePagesModule;
|
|
1236
1361
|
exports.isTargetFile = isTargetFile;
|
|
1237
1362
|
exports.mergePageMetaDataArray = mergePageMetaDataArray;
|
|
1238
1363
|
exports.parseCode = parseCode;
|
|
1239
|
-
exports.parseCustomBlock = parseCustomBlock;
|
|
1240
1364
|
exports.parseSFC = parseSFC;
|
|
1241
1365
|
exports.resolveOptions = resolveOptions;
|
|
1242
1366
|
exports.resolvePageDirs = resolvePageDirs;
|
|
1243
1367
|
exports.sleep = sleep;
|
|
1244
|
-
exports.
|
|
1368
|
+
exports.stripType = stripType;
|
|
1245
1369
|
exports.tryPageMetaFromMacro = tryPageMetaFromMacro;
|
|
1246
1370
|
exports.writeFileWithLock = writeFileWithLock;
|
|
1371
|
+
Object.keys(_uni_helper_uni_pages_types).forEach(function(k) {
|
|
1372
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
1373
|
+
enumerable: true,
|
|
1374
|
+
get: function() {
|
|
1375
|
+
return _uni_helper_uni_pages_types[k];
|
|
1376
|
+
}
|
|
1377
|
+
});
|
|
1378
|
+
});
|