@uni-helper/vite-plugin-uni-pages 0.3.2 → 0.3.4
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 +2 -2
- package/client.d.ts +5 -1
- package/dist/index.cjs +357 -168
- package/dist/index.d.cts +413 -376
- package/dist/index.d.mts +413 -376
- package/dist/index.d.ts +413 -376
- package/dist/index.mjs +335 -168
- package/index.d.ts +5 -0
- package/package.json +17 -8
package/dist/index.mjs
CHANGED
|
@@ -1,22 +1,34 @@
|
|
|
1
|
-
import path, { join, dirname, resolve } from 'node:path';
|
|
2
1
|
import { spawn } from 'node:child_process';
|
|
2
|
+
import path, { join, dirname, resolve, extname } from 'node:path';
|
|
3
3
|
import process from 'node:process';
|
|
4
|
-
import {
|
|
5
|
-
import MagicString from 'magic-string';
|
|
4
|
+
import { babelParse, isCallOf } from 'ast-kit';
|
|
6
5
|
import chokidar from 'chokidar';
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
6
|
+
import { lightYellow, bold, link, dim } from 'kolorist';
|
|
7
|
+
import MagicString from 'magic-string';
|
|
8
|
+
import { normalizePath, createLogger } from 'vite';
|
|
9
9
|
import { platform } from '@uni-helper/uni-env';
|
|
10
|
+
import { stringify, parse, assign } from 'comment-json';
|
|
11
|
+
import Debug from 'debug';
|
|
10
12
|
import detectIndent from 'detect-indent';
|
|
11
13
|
import detectNewline from 'detect-newline';
|
|
12
|
-
import {
|
|
13
|
-
import fs, { existsSync } from 'node:fs';
|
|
14
|
+
import { loadConfig } from 'unconfig';
|
|
15
|
+
import fs, { existsSync, readFileSync as readFileSync$1 } from 'node:fs';
|
|
14
16
|
import { readFile, mkdir, writeFile as writeFile$1 } from 'node:fs/promises';
|
|
17
|
+
import fg from 'fast-glob';
|
|
18
|
+
import { createRequire } from 'node:module';
|
|
19
|
+
import vm from 'node:vm';
|
|
20
|
+
import babelGenerator from '@babel/generator';
|
|
15
21
|
import groupBy from 'lodash.groupby';
|
|
22
|
+
import * as ts from 'typescript';
|
|
23
|
+
import * as t from '@babel/types';
|
|
24
|
+
import { parse as parse$2 } from '@vue/compiler-sfc';
|
|
16
25
|
import JSON5 from 'json5';
|
|
17
|
-
import { parse as parse$
|
|
18
|
-
|
|
19
|
-
|
|
26
|
+
import { parse as parse$1 } from 'yaml';
|
|
27
|
+
|
|
28
|
+
const MODULE_ID_VIRTUAL = "virtual:uni-pages";
|
|
29
|
+
const RESOLVED_MODULE_ID_VIRTUAL = `\0${MODULE_ID_VIRTUAL}`;
|
|
30
|
+
const OUTPUT_NAME = "pages.json";
|
|
31
|
+
const FILE_EXTENSIONS = ["vue", "nvue", "uvue"];
|
|
20
32
|
|
|
21
33
|
function slash(str) {
|
|
22
34
|
return str.replace(/\\/g, "/");
|
|
@@ -68,86 +80,6 @@ async function writeDeclaration(ctx, filepath) {
|
|
|
68
80
|
await writeFile(filepath, code);
|
|
69
81
|
}
|
|
70
82
|
|
|
71
|
-
const MODULE_ID_VIRTUAL = "virtual:uni-pages";
|
|
72
|
-
const RESOLVED_MODULE_ID_VIRTUAL = `\0${MODULE_ID_VIRTUAL}`;
|
|
73
|
-
const OUTPUT_NAME = "pages.json";
|
|
74
|
-
const FILE_EXTENSIONS = ["vue", "nvue", "uvue"];
|
|
75
|
-
|
|
76
|
-
async function parseSFC(code) {
|
|
77
|
-
try {
|
|
78
|
-
return parse(code, {
|
|
79
|
-
pad: "space"
|
|
80
|
-
}).descriptor || parse({
|
|
81
|
-
source: code
|
|
82
|
-
});
|
|
83
|
-
} catch (error) {
|
|
84
|
-
throw new Error(`[vite-plugin-uni-pages] Vue3's "@vue/compiler-sfc" is required.
|
|
85
|
-
Original error:
|
|
86
|
-
${error}`);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
function parseCustomBlock(block, filePath, options) {
|
|
90
|
-
const lang = block.lang ?? options.routeBlockLang;
|
|
91
|
-
const attr = {
|
|
92
|
-
type: "page",
|
|
93
|
-
...block.attrs
|
|
94
|
-
};
|
|
95
|
-
let content;
|
|
96
|
-
debug.routeBlock(`use ${lang} parser`);
|
|
97
|
-
if (lang === "json5") {
|
|
98
|
-
try {
|
|
99
|
-
content = JSON5.parse(block.content);
|
|
100
|
-
} catch (err) {
|
|
101
|
-
throw new Error(
|
|
102
|
-
`Invalid JSON5 format of <${block.type}> content in ${filePath}
|
|
103
|
-
${err.message}`
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
} else if (lang === "jsonc") {
|
|
107
|
-
try {
|
|
108
|
-
content = parse$1(block.content);
|
|
109
|
-
} catch (err) {
|
|
110
|
-
throw new Error(
|
|
111
|
-
`Invalid JSONC format of <${block.type}> content in ${filePath}
|
|
112
|
-
${err.message}`
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
} else if (lang === "json") {
|
|
116
|
-
try {
|
|
117
|
-
content = JSON.parse(block.content);
|
|
118
|
-
} catch (err) {
|
|
119
|
-
throw new Error(
|
|
120
|
-
`Invalid JSON format of <${block.type}> content in ${filePath}
|
|
121
|
-
${err.message}`
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
} else if (lang === "yaml" || lang === "yml") {
|
|
125
|
-
try {
|
|
126
|
-
content = parse$2(block.content);
|
|
127
|
-
} catch (err) {
|
|
128
|
-
throw new Error(
|
|
129
|
-
`Invalid YAML format of <${block.type}> content in ${filePath}
|
|
130
|
-
${err.message}`
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return {
|
|
135
|
-
attr,
|
|
136
|
-
content: content ?? {}
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
async function getRouteSfcBlock(path) {
|
|
140
|
-
const content = fs.readFileSync(path, "utf8");
|
|
141
|
-
const parsedSFC = await parseSFC(content);
|
|
142
|
-
const blockStr = parsedSFC?.customBlocks.find((b) => b.type === "route");
|
|
143
|
-
return blockStr;
|
|
144
|
-
}
|
|
145
|
-
async function getRouteBlock(path, blockStr, options) {
|
|
146
|
-
if (!blockStr)
|
|
147
|
-
return;
|
|
148
|
-
return parseCustomBlock(blockStr, path, options);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
83
|
function invalidatePagesModule(server) {
|
|
152
84
|
const { moduleGraph } = server;
|
|
153
85
|
const mods = moduleGraph.getModulesByFile(RESOLVED_MODULE_ID_VIRTUAL);
|
|
@@ -166,20 +98,21 @@ const debug = {
|
|
|
166
98
|
subPages: Debug("vite-plugin-uni-pages:subPages"),
|
|
167
99
|
error: Debug("vite-plugin-uni-pages:error"),
|
|
168
100
|
cache: Debug("vite-plugin-uni-pages:cache"),
|
|
169
|
-
declaration: Debug("vite-plugin-uni-pages:declaration")
|
|
101
|
+
declaration: Debug("vite-plugin-uni-pages:declaration"),
|
|
102
|
+
definePage: Debug("vite-plugin-uni-pages:definePage")
|
|
170
103
|
};
|
|
171
104
|
function extsToGlob(extensions) {
|
|
172
105
|
return extensions.length > 1 ? `{${extensions.join(",")}}` : extensions[0] || "";
|
|
173
106
|
}
|
|
174
|
-
function isTargetFile(
|
|
175
|
-
const ext =
|
|
107
|
+
function isTargetFile(path2) {
|
|
108
|
+
const ext = path2.split(".").pop();
|
|
176
109
|
return FILE_EXTENSIONS.includes(ext);
|
|
177
110
|
}
|
|
178
111
|
function mergePageMetaDataArray(pageMetaData) {
|
|
179
112
|
const pageMetaDataObj = groupBy(pageMetaData, "path");
|
|
180
113
|
const result = [];
|
|
181
|
-
for (const
|
|
182
|
-
const _pageMetaData = pageMetaDataObj[
|
|
114
|
+
for (const path2 in pageMetaDataObj) {
|
|
115
|
+
const _pageMetaData = pageMetaDataObj[path2];
|
|
183
116
|
const options = _pageMetaData[0];
|
|
184
117
|
for (const page of _pageMetaData) {
|
|
185
118
|
options.style = Object.assign(options.style ?? {}, page.style ?? {});
|
|
@@ -189,26 +122,64 @@ function mergePageMetaDataArray(pageMetaData) {
|
|
|
189
122
|
}
|
|
190
123
|
return result;
|
|
191
124
|
}
|
|
192
|
-
function
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
125
|
+
async function execScript(code, filename) {
|
|
126
|
+
const jsCode = ts.transpileModule(code, {
|
|
127
|
+
compilerOptions: {
|
|
128
|
+
module: ts.ModuleKind.CommonJS,
|
|
129
|
+
target: ts.ScriptTarget.ESNext
|
|
130
|
+
}
|
|
131
|
+
}).outputText;
|
|
132
|
+
const dir = path.dirname(filename);
|
|
133
|
+
const vmContext = {
|
|
134
|
+
require: createRequire(dir),
|
|
135
|
+
module: {},
|
|
136
|
+
exports: {},
|
|
137
|
+
__filename: filename,
|
|
138
|
+
__dirname: dir
|
|
139
|
+
};
|
|
140
|
+
const script = new vm.Script(jsCode);
|
|
141
|
+
try {
|
|
142
|
+
script.runInNewContext(vmContext);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
throw new Error(`${filename}: ${error.message}`);
|
|
199
145
|
}
|
|
200
|
-
|
|
201
|
-
|
|
146
|
+
const result = vmContext.exports.default || vmContext.exports;
|
|
147
|
+
if (typeof result === "function") {
|
|
148
|
+
return Promise.resolve(result());
|
|
202
149
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
150
|
+
return Promise.resolve(result);
|
|
151
|
+
}
|
|
152
|
+
function getDefaultExport(expr) {
|
|
153
|
+
return expr.default === void 0 ? expr : expr.default;
|
|
154
|
+
}
|
|
155
|
+
const babelGenerate = getDefaultExport(babelGenerator);
|
|
156
|
+
|
|
157
|
+
function getPageFiles(path, options) {
|
|
158
|
+
const { exclude } = options;
|
|
159
|
+
const ext = extsToGlob(FILE_EXTENSIONS);
|
|
160
|
+
const files = fg.sync(`**/*.${ext}`, {
|
|
161
|
+
ignore: exclude,
|
|
162
|
+
onlyFiles: true,
|
|
163
|
+
cwd: path
|
|
164
|
+
});
|
|
165
|
+
return files;
|
|
166
|
+
}
|
|
167
|
+
function checkPagesJsonFile(path) {
|
|
168
|
+
if (!fs.existsSync(path)) {
|
|
169
|
+
writeFileSync(path, stringify({ pages: [{ path: "" }] }, null, 2));
|
|
170
|
+
return false;
|
|
207
171
|
}
|
|
208
|
-
return
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
function readFileSync(path) {
|
|
175
|
+
try {
|
|
176
|
+
return fs.readFileSync(path, { encoding: "utf-8" });
|
|
177
|
+
} catch {
|
|
178
|
+
return "";
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function writeFileSync(path, content) {
|
|
182
|
+
fs.writeFileSync(path, content, { encoding: "utf-8" });
|
|
212
183
|
}
|
|
213
184
|
|
|
214
185
|
function resolveOptions(userOptions, viteRoot = process.cwd()) {
|
|
@@ -282,32 +253,190 @@ function resolvePageDirs(dir, root, exclude) {
|
|
|
282
253
|
return dirs;
|
|
283
254
|
}
|
|
284
255
|
|
|
285
|
-
function
|
|
286
|
-
const
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
});
|
|
293
|
-
|
|
256
|
+
function parseCustomBlock(block, filePath, routeBlockLang) {
|
|
257
|
+
const lang = block.lang ?? routeBlockLang;
|
|
258
|
+
const attr = {
|
|
259
|
+
type: "page",
|
|
260
|
+
...block.attrs
|
|
261
|
+
};
|
|
262
|
+
let content;
|
|
263
|
+
debug.routeBlock(`use ${lang} parser`);
|
|
264
|
+
if (lang === "json5") {
|
|
265
|
+
try {
|
|
266
|
+
content = JSON5.parse(block.content);
|
|
267
|
+
} catch (err) {
|
|
268
|
+
throw new Error(
|
|
269
|
+
`Invalid JSON5 format of <${block.type}> content in ${filePath}
|
|
270
|
+
${err.message}`
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
} else if (lang === "jsonc") {
|
|
274
|
+
try {
|
|
275
|
+
content = parse(block.content);
|
|
276
|
+
} catch (err) {
|
|
277
|
+
throw new Error(
|
|
278
|
+
`Invalid JSONC format of <${block.type}> content in ${filePath}
|
|
279
|
+
${err.message}`
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
} else if (lang === "json") {
|
|
283
|
+
try {
|
|
284
|
+
content = JSON.parse(block.content);
|
|
285
|
+
} catch (err) {
|
|
286
|
+
throw new Error(
|
|
287
|
+
`Invalid JSON format of <${block.type}> content in ${filePath}
|
|
288
|
+
${err.message}`
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
} else if (lang === "yaml" || lang === "yml") {
|
|
292
|
+
try {
|
|
293
|
+
content = parse$1(block.content);
|
|
294
|
+
} catch (err) {
|
|
295
|
+
throw new Error(
|
|
296
|
+
`Invalid YAML format of <${block.type}> content in ${filePath}
|
|
297
|
+
${err.message}`
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
attr,
|
|
303
|
+
content: content ?? {}
|
|
304
|
+
};
|
|
294
305
|
}
|
|
295
|
-
function
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
306
|
+
function getRouteSfcBlock(sfc) {
|
|
307
|
+
return sfc?.customBlocks.find((b) => b.type === "route");
|
|
308
|
+
}
|
|
309
|
+
function getRouteBlock(path, blockStr, routeBlockLang) {
|
|
310
|
+
if (!blockStr)
|
|
311
|
+
return;
|
|
312
|
+
return parseCustomBlock(blockStr, path, routeBlockLang);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
var __defProp$1 = Object.defineProperty;
|
|
316
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
317
|
+
var __publicField$1 = (obj, key, value) => {
|
|
318
|
+
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
319
|
+
return value;
|
|
320
|
+
};
|
|
321
|
+
class Page {
|
|
322
|
+
constructor(ctx, path) {
|
|
323
|
+
__publicField$1(this, "ctx");
|
|
324
|
+
__publicField$1(this, "path");
|
|
325
|
+
__publicField$1(this, "rawOptions", "");
|
|
326
|
+
__publicField$1(this, "options");
|
|
327
|
+
this.ctx = ctx;
|
|
328
|
+
this.path = path;
|
|
329
|
+
}
|
|
330
|
+
async getPageMeta(forceUpdate = false) {
|
|
331
|
+
if (forceUpdate || !this.options) {
|
|
332
|
+
await this.readPageMeta();
|
|
333
|
+
}
|
|
334
|
+
return this.options;
|
|
335
|
+
}
|
|
336
|
+
async hasChanged() {
|
|
337
|
+
const { hasChanged } = await this.readPageMeta();
|
|
338
|
+
return hasChanged;
|
|
339
|
+
}
|
|
340
|
+
async readPageMeta() {
|
|
341
|
+
try {
|
|
342
|
+
const { relativePath } = this.path;
|
|
343
|
+
const { path, ...others } = await this.readPageMetaFromFile();
|
|
344
|
+
this.options = {
|
|
345
|
+
path: path ?? normalizePath(relativePath.replace(extname(relativePath), "")),
|
|
346
|
+
...others
|
|
347
|
+
};
|
|
348
|
+
const raw = this.options ? JSON.stringify(this.options) : "";
|
|
349
|
+
const hasChanged = this.rawOptions !== raw;
|
|
350
|
+
this.rawOptions = raw;
|
|
351
|
+
return {
|
|
352
|
+
options: this.options,
|
|
353
|
+
hasChanged
|
|
354
|
+
};
|
|
355
|
+
} catch (err) {
|
|
356
|
+
throw new Error(`Read page options fail in ${this.path.relativePath}
|
|
357
|
+
${err.message}`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
async readPageMetaFromFile() {
|
|
361
|
+
const content = readFileSync$1(this.path.absolutePath, "utf-8");
|
|
362
|
+
const sfc = parseSFC(content, { filename: this.path.absolutePath });
|
|
363
|
+
const meta = await tryPageMetaFromMacro(sfc);
|
|
364
|
+
if (meta) {
|
|
365
|
+
return meta;
|
|
366
|
+
}
|
|
367
|
+
return tryPageMetaFromCustomBlock(sfc, this.ctx.options.routeBlockLang);
|
|
299
368
|
}
|
|
300
|
-
return true;
|
|
301
369
|
}
|
|
302
|
-
function
|
|
370
|
+
function parseSFC(code, options) {
|
|
303
371
|
try {
|
|
304
|
-
return
|
|
305
|
-
|
|
306
|
-
|
|
372
|
+
return parse$2(code, {
|
|
373
|
+
pad: "space",
|
|
374
|
+
...options
|
|
375
|
+
}).descriptor || parse$2({
|
|
376
|
+
source: code,
|
|
377
|
+
...options
|
|
378
|
+
});
|
|
379
|
+
} catch (error) {
|
|
380
|
+
throw new Error(`[vite-plugin-uni-pages] Vue3's "@vue/compiler-sfc" is required.
|
|
381
|
+
Original error:
|
|
382
|
+
${error}`);
|
|
307
383
|
}
|
|
308
384
|
}
|
|
309
|
-
function
|
|
310
|
-
|
|
385
|
+
async function tryPageMetaFromMacro(sfc) {
|
|
386
|
+
const sfcScript = sfc.scriptSetup || sfc.script;
|
|
387
|
+
if (!sfcScript) {
|
|
388
|
+
return void 0;
|
|
389
|
+
}
|
|
390
|
+
const ast = babelParse(sfcScript.content, sfcScript.lang || "js", {
|
|
391
|
+
plugins: [["importAttributes", { deprecatedAssertSyntax: true }]]
|
|
392
|
+
});
|
|
393
|
+
const macro = findMacro(ast.body, sfc.filename);
|
|
394
|
+
if (macro) {
|
|
395
|
+
const imports = findImports(ast.body).map((imp) => babelGenerate(imp).code);
|
|
396
|
+
const [macroOption] = macro.arguments;
|
|
397
|
+
const code = babelGenerate(macroOption).code;
|
|
398
|
+
let script = "";
|
|
399
|
+
const importScript = imports.join("");
|
|
400
|
+
script += importScript;
|
|
401
|
+
script += `export default ${code}`;
|
|
402
|
+
const result = await execScript(script, sfc.filename);
|
|
403
|
+
return result;
|
|
404
|
+
}
|
|
405
|
+
return void 0;
|
|
406
|
+
}
|
|
407
|
+
async function tryPageMetaFromCustomBlock(sfc, routeBlockLang) {
|
|
408
|
+
const block = getRouteSfcBlock(sfc);
|
|
409
|
+
const routeBlock = getRouteBlock(sfc.filename, block, routeBlockLang);
|
|
410
|
+
const pageMeta = {
|
|
411
|
+
type: routeBlock?.attr.type ?? "page"
|
|
412
|
+
};
|
|
413
|
+
if (routeBlock) {
|
|
414
|
+
assign(pageMeta, routeBlock.content);
|
|
415
|
+
}
|
|
416
|
+
return pageMeta;
|
|
417
|
+
}
|
|
418
|
+
function findMacro(stmts, filename) {
|
|
419
|
+
const nodes = stmts.map((raw) => {
|
|
420
|
+
let node = raw;
|
|
421
|
+
if (raw.type === "ExpressionStatement")
|
|
422
|
+
node = raw.expression;
|
|
423
|
+
return isCallOf(node, "definePage") ? node : void 0;
|
|
424
|
+
}).filter((node) => !!node);
|
|
425
|
+
if (!nodes.length)
|
|
426
|
+
return;
|
|
427
|
+
if (nodes.length > 1) {
|
|
428
|
+
throw new Error(`\u6BCF\u4E2A\u6587\u4EF6\u53EA\u5141\u8BB8\u8C03\u7528\u4E00\u6B21 definePage(): ${filename}`);
|
|
429
|
+
}
|
|
430
|
+
const macro = nodes[0];
|
|
431
|
+
const [opt] = macro.arguments;
|
|
432
|
+
if (opt && !t.isFunctionExpression(opt) && !t.isArrowFunctionExpression(opt) && !t.isObjectExpression(opt)) {
|
|
433
|
+
debug.definePage(`definePage() only accept argument in function or object: ${filename}`);
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
return macro;
|
|
437
|
+
}
|
|
438
|
+
function findImports(stmts) {
|
|
439
|
+
return stmts.map((node) => node.type === "ImportDeclaration" ? node : void 0).filter((node) => !!node);
|
|
311
440
|
}
|
|
312
441
|
|
|
313
442
|
var __defProp = Object.defineProperty;
|
|
@@ -317,14 +446,15 @@ var __publicField = (obj, key, value) => {
|
|
|
317
446
|
return value;
|
|
318
447
|
};
|
|
319
448
|
let lsatPagesJson = "";
|
|
320
|
-
const { setCache, hasChanged } = useCachedPages();
|
|
321
449
|
class PageContext {
|
|
322
450
|
constructor(userOptions, viteRoot = process.cwd()) {
|
|
323
451
|
__publicField(this, "_server");
|
|
324
452
|
__publicField(this, "pagesGlobConfig");
|
|
325
453
|
__publicField(this, "pagesConfigSourcePaths", []);
|
|
326
|
-
__publicField(this, "
|
|
327
|
-
|
|
454
|
+
__publicField(this, "pages", /* @__PURE__ */ new Map());
|
|
455
|
+
// abs path -> Page
|
|
456
|
+
__publicField(this, "subPages", /* @__PURE__ */ new Map());
|
|
457
|
+
// root -> abs path -> page
|
|
328
458
|
__publicField(this, "pageMetaData", []);
|
|
329
459
|
__publicField(this, "subPageMetaData", []);
|
|
330
460
|
__publicField(this, "resolvedPagesJSONPath", "");
|
|
@@ -367,17 +497,30 @@ class PageContext {
|
|
|
367
497
|
const pageDirFiles = this.options.dirs.map((dir) => {
|
|
368
498
|
return { dir, files: getPagePaths(dir, this.options) };
|
|
369
499
|
});
|
|
370
|
-
|
|
371
|
-
debug.pages(
|
|
500
|
+
const paths = pageDirFiles.map((page) => page.files).flat();
|
|
501
|
+
debug.pages(paths);
|
|
502
|
+
const pages = /* @__PURE__ */ new Map();
|
|
503
|
+
for (const path2 of paths) {
|
|
504
|
+
const page = this.pages.get(path2.absolutePath) || new Page(this, path2);
|
|
505
|
+
pages.set(path2.absolutePath, page);
|
|
506
|
+
}
|
|
507
|
+
this.pages = pages;
|
|
372
508
|
}
|
|
373
509
|
async scanSubPages() {
|
|
374
|
-
const
|
|
510
|
+
const paths = {};
|
|
511
|
+
const subPages = /* @__PURE__ */ new Map();
|
|
375
512
|
for (const dir of this.options.subPackages) {
|
|
376
513
|
const pagePaths = getPagePaths(dir, this.options);
|
|
377
|
-
|
|
514
|
+
paths[dir] = pagePaths;
|
|
515
|
+
const pages = /* @__PURE__ */ new Map();
|
|
516
|
+
for (const path2 of pagePaths) {
|
|
517
|
+
const page = this.subPages.get(dir)?.get(path2.absolutePath) || new Page(this, path2);
|
|
518
|
+
pages.set(path2.absolutePath, page);
|
|
519
|
+
}
|
|
520
|
+
subPages.set(dir, pages);
|
|
378
521
|
}
|
|
379
|
-
|
|
380
|
-
|
|
522
|
+
debug.subPages(JSON.stringify(paths, null, 2));
|
|
523
|
+
this.subPages = subPages;
|
|
381
524
|
}
|
|
382
525
|
setupViteServer(server) {
|
|
383
526
|
if (this._server === server)
|
|
@@ -438,20 +581,6 @@ class PageContext {
|
|
|
438
581
|
type: "full-reload"
|
|
439
582
|
});
|
|
440
583
|
}
|
|
441
|
-
async parsePage(page) {
|
|
442
|
-
const { relativePath, absolutePath } = page;
|
|
443
|
-
const routeSfcBlock = await getRouteSfcBlock(absolutePath);
|
|
444
|
-
const routeBlock = await getRouteBlock(absolutePath, routeSfcBlock, this.options);
|
|
445
|
-
setCache(absolutePath, routeSfcBlock);
|
|
446
|
-
const relativePathWithFileName = relativePath.replace(path.extname(relativePath), "");
|
|
447
|
-
const pageMetaDatum = {
|
|
448
|
-
path: normalizePath(relativePathWithFileName),
|
|
449
|
-
type: routeBlock?.attr.type ?? "page"
|
|
450
|
-
};
|
|
451
|
-
if (routeBlock)
|
|
452
|
-
assign(pageMetaDatum, routeBlock.content);
|
|
453
|
-
return pageMetaDatum;
|
|
454
|
-
}
|
|
455
584
|
/**
|
|
456
585
|
* parse pages rules && set page type
|
|
457
586
|
* @param pages page path array
|
|
@@ -460,7 +589,11 @@ class PageContext {
|
|
|
460
589
|
* @returns pages rules
|
|
461
590
|
*/
|
|
462
591
|
async parsePages(pages, type, overrides) {
|
|
463
|
-
const
|
|
592
|
+
const jobs = [];
|
|
593
|
+
for (const [_, page] of pages) {
|
|
594
|
+
jobs.push(page.getPageMeta());
|
|
595
|
+
}
|
|
596
|
+
const generatedPageMetaData = await Promise.all(jobs);
|
|
464
597
|
const customPageMetaData = overrides || [];
|
|
465
598
|
const result = customPageMetaData.length ? mergePageMetaDataArray(generatedPageMetaData.concat(customPageMetaData)) : generatedPageMetaData;
|
|
466
599
|
const parseMeta = result.filter(
|
|
@@ -492,14 +625,14 @@ class PageContext {
|
|
|
492
625
|
return result;
|
|
493
626
|
}
|
|
494
627
|
async mergePageMetaData() {
|
|
495
|
-
const pageMetaData = await this.parsePages(this.
|
|
628
|
+
const pageMetaData = await this.parsePages(this.pages, "main", this.pagesGlobConfig?.pages);
|
|
496
629
|
this.pageMetaData = pageMetaData;
|
|
497
630
|
debug.pages(this.pageMetaData);
|
|
498
631
|
}
|
|
499
632
|
async mergeSubPageMetaData() {
|
|
500
633
|
const subPageMaps = {};
|
|
501
634
|
const subPackages = this.pagesGlobConfig?.subPackages || [];
|
|
502
|
-
for (const [dir, pages] of
|
|
635
|
+
for (const [dir, pages] of this.subPages) {
|
|
503
636
|
const basePath = slash(path.join(this.options.root, this.options.outDir));
|
|
504
637
|
const root = slash(path.relative(basePath, path.join(this.options.root, dir)));
|
|
505
638
|
const globPackage = subPackages?.find((v) => v.root === root);
|
|
@@ -516,7 +649,18 @@ class PageContext {
|
|
|
516
649
|
}
|
|
517
650
|
async updatePagesJSON(filepath) {
|
|
518
651
|
if (filepath) {
|
|
519
|
-
|
|
652
|
+
let page = this.pages.get(filepath);
|
|
653
|
+
if (!page) {
|
|
654
|
+
let subPage;
|
|
655
|
+
for (const [_, pages2] of this.subPages) {
|
|
656
|
+
subPage = pages2.get(filepath);
|
|
657
|
+
if (subPage) {
|
|
658
|
+
break;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
page = subPage;
|
|
662
|
+
}
|
|
663
|
+
if (page && !await page.hasChanged()) {
|
|
520
664
|
debug.cache(`The route block on page ${filepath} did not send any changes, skipping`);
|
|
521
665
|
return false;
|
|
522
666
|
}
|
|
@@ -644,16 +788,39 @@ function VitePluginUniPages(userOptions = {}) {
|
|
|
644
788
|
},
|
|
645
789
|
// Applet do not support custom route block, so we need to remove the route block here
|
|
646
790
|
async transform(code, id) {
|
|
647
|
-
if (
|
|
791
|
+
if (!FILE_EXTENSIONS.find((ext) => id.endsWith(ext))) {
|
|
648
792
|
return null;
|
|
793
|
+
}
|
|
794
|
+
const sfc = parseSFC(code, { filename: id });
|
|
795
|
+
let macro;
|
|
796
|
+
if (sfc.scriptSetup) {
|
|
797
|
+
const ast = babelParse(sfc.scriptSetup.content, sfc.scriptSetup.lang || "js");
|
|
798
|
+
macro = findMacro(ast.body, sfc.filename);
|
|
799
|
+
}
|
|
800
|
+
if (!macro && sfc.script) {
|
|
801
|
+
const ast = babelParse(sfc.script.content, sfc.script.lang || "js");
|
|
802
|
+
macro = findMacro(ast.body, sfc.filename);
|
|
803
|
+
}
|
|
804
|
+
const routeBlock = sfc.customBlocks.find((block) => block.type === "route");
|
|
805
|
+
if (!macro && !routeBlock)
|
|
806
|
+
return null;
|
|
807
|
+
if (macro && routeBlock)
|
|
808
|
+
throw new Error(`\u4E0D\u652F\u6301\u6DF7\u5408\u4F7F\u7528 definePage() \u548C <route/> ${id}`);
|
|
649
809
|
const s = new MagicString(code);
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
)
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
s.
|
|
810
|
+
if (macro)
|
|
811
|
+
s.remove(macro.start, macro.end);
|
|
812
|
+
if (routeBlock) {
|
|
813
|
+
console.log(lightYellow("\u8B66\u544A\uFF1A"), `${bold("<route/>")} \u6807\u7B7E\u5DF2\u5E9F\u5F03\uFF0C\u5C06\u5728\u4E0B\u4E00\u4E2A\u7248\u672C\u4E2D\u79FB\u9664\uFF0C\u8BF7\u4F7F\u7528 definePage() \u4EE3\u66FF\uFF1B${link("\u67E5\u770B\u8FC1\u79FB\u6307\u5357", "https://uni-helper.js.org/vite-plugin-uni-pages/definePage")}\u3002`);
|
|
814
|
+
console.log(dim(id));
|
|
815
|
+
console.log();
|
|
816
|
+
const routeBlockMatches = s.original.matchAll(
|
|
817
|
+
/<route[^>]*>([\s\S]*?)<\/route>/g
|
|
818
|
+
);
|
|
819
|
+
for (const match of routeBlockMatches) {
|
|
820
|
+
const index = match.index;
|
|
821
|
+
const length = match[0].length;
|
|
822
|
+
s.remove(index, index + length);
|
|
823
|
+
}
|
|
657
824
|
}
|
|
658
825
|
if (s.hasChanged()) {
|
|
659
826
|
return {
|
|
@@ -680,4 +847,4 @@ function VitePluginUniPages(userOptions = {}) {
|
|
|
680
847
|
};
|
|
681
848
|
}
|
|
682
849
|
|
|
683
|
-
export { FILE_EXTENSIONS, MODULE_ID_VIRTUAL, OUTPUT_NAME, PageContext, RESOLVED_MODULE_ID_VIRTUAL, VitePluginUniPages, checkPagesJsonFile, debug, VitePluginUniPages as default, defineUniPages, extsToGlob, getPageFiles, getRouteBlock, getRouteSfcBlock, invalidatePagesModule, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, readFileSync, resolveOptions, resolvePageDirs,
|
|
850
|
+
export { FILE_EXTENSIONS, MODULE_ID_VIRTUAL, OUTPUT_NAME, Page, PageContext, RESOLVED_MODULE_ID_VIRTUAL, VitePluginUniPages, babelGenerate, checkPagesJsonFile, debug, VitePluginUniPages as default, defineUniPages, execScript, extsToGlob, findImports, findMacro, getPageFiles, getRouteBlock, getRouteSfcBlock, invalidatePagesModule, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, readFileSync, resolveOptions, resolvePageDirs, tryPageMetaFromCustomBlock, tryPageMetaFromMacro, writeFileSync };
|