@uni-helper/vite-plugin-uni-pages 0.2.2 → 0.2.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/client.d.ts +4 -5
- package/dist/index.cjs +131 -77
- package/dist/index.d.ts +12 -5
- package/dist/index.mjs +130 -78
- package/package.json +1 -1
package/client.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
declare module "virtual:uni-pages" {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}[];
|
|
2
|
+
import { PageMetaDatum } from "./src/types";
|
|
3
|
+
import { SubPackage } from "./src/config/types/index";
|
|
4
|
+
export const pages: PageMetaDatum[];
|
|
5
|
+
export const subPackages: SubPackage[];
|
|
7
6
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -36,6 +36,72 @@ const RESOLVED_MODULE_ID_VIRTUAL = `\0${MODULE_ID_VIRTUAL}`;
|
|
|
36
36
|
const OUTPUT_NAME = "pages.json";
|
|
37
37
|
const FILE_EXTENSIONS = ["vue", "nvue", "uvue"];
|
|
38
38
|
|
|
39
|
+
async function parseSFC(code) {
|
|
40
|
+
try {
|
|
41
|
+
return compilerSfc.parse(code, {
|
|
42
|
+
pad: "space"
|
|
43
|
+
}).descriptor || compilerSfc.parse({
|
|
44
|
+
source: code
|
|
45
|
+
});
|
|
46
|
+
} catch {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`[vite-plugin-uni-pages] Vue3's "@vue/compiler-sfc" is required.`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function parseCustomBlock(block, filePath, options) {
|
|
53
|
+
const lang = block.lang ?? options.routeBlockLang;
|
|
54
|
+
const attr = {
|
|
55
|
+
type: "page",
|
|
56
|
+
...block.attrs
|
|
57
|
+
};
|
|
58
|
+
let content;
|
|
59
|
+
debug.routeBlock(`use ${lang} parser`);
|
|
60
|
+
if (lang === "json5" || lang === "jsonc") {
|
|
61
|
+
try {
|
|
62
|
+
content = JSON5__default.parse(block.content);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`Invalid JSON5 format of <${block.type}> content in ${filePath}
|
|
66
|
+
${err.message}`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
} else if (lang === "json") {
|
|
70
|
+
try {
|
|
71
|
+
content = JSON.parse(block.content);
|
|
72
|
+
} catch (err) {
|
|
73
|
+
throw new Error(
|
|
74
|
+
`Invalid JSON format of <${block.type}> content in ${filePath}
|
|
75
|
+
${err.message}`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
} else if (lang === "yaml" || lang === "yml") {
|
|
79
|
+
try {
|
|
80
|
+
content = yaml.parse(block.content);
|
|
81
|
+
} catch (err) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`Invalid YAML format of <${block.type}> content in ${filePath}
|
|
84
|
+
${err.message}`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
attr,
|
|
90
|
+
content: content ?? {}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
async function getRouteSfcBlock(path) {
|
|
94
|
+
const content = fs__default.readFileSync(path, "utf8");
|
|
95
|
+
const parsedSFC = await parseSFC(content);
|
|
96
|
+
const blockStr = parsedSFC?.customBlocks.find((b) => b.type === "route");
|
|
97
|
+
return blockStr;
|
|
98
|
+
}
|
|
99
|
+
async function getRouteBlock(path, blockStr, options) {
|
|
100
|
+
if (!blockStr)
|
|
101
|
+
return;
|
|
102
|
+
return parseCustomBlock(blockStr, path, options);
|
|
103
|
+
}
|
|
104
|
+
|
|
39
105
|
function invalidatePagesModule(server) {
|
|
40
106
|
const { moduleGraph } = server;
|
|
41
107
|
const mods = moduleGraph.getModulesByFile(RESOLVED_MODULE_ID_VIRTUAL);
|
|
@@ -52,7 +118,8 @@ const debug = {
|
|
|
52
118
|
options: Debug__default("vite-plugin-uni-pages:options"),
|
|
53
119
|
pages: Debug__default("vite-plugin-uni-pages:pages"),
|
|
54
120
|
subPages: Debug__default("vite-plugin-uni-pages:subPages"),
|
|
55
|
-
error: Debug__default("vite-plugin-uni-pages:error")
|
|
121
|
+
error: Debug__default("vite-plugin-uni-pages:error"),
|
|
122
|
+
cache: Debug__default("vite-plugin-uni-pages:cache")
|
|
56
123
|
};
|
|
57
124
|
function extsToGlob(extensions) {
|
|
58
125
|
return extensions.length > 1 ? `{${extensions.join(",")}}` : extensions[0] || "";
|
|
@@ -85,6 +152,27 @@ async function getPagesConfigSourcePaths() {
|
|
|
85
152
|
absolute: true
|
|
86
153
|
});
|
|
87
154
|
}
|
|
155
|
+
function useCachedPages() {
|
|
156
|
+
const pages = /* @__PURE__ */ new Map();
|
|
157
|
+
function parseData(block) {
|
|
158
|
+
return {
|
|
159
|
+
content: block?.loc.source.trim() ?? "",
|
|
160
|
+
attr: block?.attrs ?? ""
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function setCache(filePath, routeBlock) {
|
|
164
|
+
pages.set(filePath, JSON.stringify(parseData(routeBlock)));
|
|
165
|
+
}
|
|
166
|
+
async function hasChanged(filePath, routeBlock) {
|
|
167
|
+
if (!routeBlock)
|
|
168
|
+
routeBlock = await getRouteSfcBlock(vite.normalizePath(filePath));
|
|
169
|
+
return !pages.has(filePath) || JSON.stringify(parseData(routeBlock)) !== pages.get(filePath);
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
setCache,
|
|
173
|
+
hasChanged
|
|
174
|
+
};
|
|
175
|
+
}
|
|
88
176
|
|
|
89
177
|
function resolveOptions(userOptions, viteRoot) {
|
|
90
178
|
const {
|
|
@@ -172,70 +260,8 @@ function writeFileSync(path, content) {
|
|
|
172
260
|
fs__default.writeFileSync(path, content, { encoding: "utf-8" });
|
|
173
261
|
}
|
|
174
262
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
return compilerSfc.parse(code, {
|
|
178
|
-
pad: "space"
|
|
179
|
-
}).descriptor || compilerSfc.parse({
|
|
180
|
-
source: code
|
|
181
|
-
});
|
|
182
|
-
} catch {
|
|
183
|
-
throw new Error(
|
|
184
|
-
`[vite-plugin-uni-pages] Vue3's "@vue/compiler-sfc" is required.`
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
function parseCustomBlock(block, filePath, options) {
|
|
189
|
-
const lang = block.lang ?? options.routeBlockLang;
|
|
190
|
-
const attr = {
|
|
191
|
-
type: "page",
|
|
192
|
-
...block.attrs
|
|
193
|
-
};
|
|
194
|
-
let content;
|
|
195
|
-
debug.routeBlock(`use ${lang} parser`);
|
|
196
|
-
if (lang === "json5" || lang === "jsonc") {
|
|
197
|
-
try {
|
|
198
|
-
content = JSON5__default.parse(block.content);
|
|
199
|
-
} catch (err) {
|
|
200
|
-
throw new Error(
|
|
201
|
-
`Invalid JSON5 format of <${block.type}> content in ${filePath}
|
|
202
|
-
${err.message}`
|
|
203
|
-
);
|
|
204
|
-
}
|
|
205
|
-
} else if (lang === "json") {
|
|
206
|
-
try {
|
|
207
|
-
content = JSON.parse(block.content);
|
|
208
|
-
} catch (err) {
|
|
209
|
-
throw new Error(
|
|
210
|
-
`Invalid JSON format of <${block.type}> content in ${filePath}
|
|
211
|
-
${err.message}`
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
} else if (lang === "yaml" || lang === "yml") {
|
|
215
|
-
try {
|
|
216
|
-
content = yaml.parse(block.content);
|
|
217
|
-
} catch (err) {
|
|
218
|
-
throw new Error(
|
|
219
|
-
`Invalid YAML format of <${block.type}> content in ${filePath}
|
|
220
|
-
${err.message}`
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
return {
|
|
225
|
-
attr,
|
|
226
|
-
content: content ?? {}
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
async function getRouteBlock(path, options) {
|
|
230
|
-
const content = fs__default.readFileSync(path, "utf8");
|
|
231
|
-
const parsedSFC = await parseSFC(content);
|
|
232
|
-
const blockStr = parsedSFC?.customBlocks.find((b) => b.type === "route");
|
|
233
|
-
if (!blockStr)
|
|
234
|
-
return;
|
|
235
|
-
const result = parseCustomBlock(blockStr, path, options);
|
|
236
|
-
return result;
|
|
237
|
-
}
|
|
238
|
-
|
|
263
|
+
let lsatPagesJson = "";
|
|
264
|
+
const { setCache, hasChanged } = useCachedPages();
|
|
239
265
|
class PageContext {
|
|
240
266
|
constructor(userOptions, viteRoot = process.cwd()) {
|
|
241
267
|
this.pagesPath = [];
|
|
@@ -300,24 +326,24 @@ class PageContext {
|
|
|
300
326
|
if (!isTargetFile(path2))
|
|
301
327
|
return;
|
|
302
328
|
debug.pages(`File added: ${path2}`);
|
|
303
|
-
this.updatePagesJSON()
|
|
304
|
-
|
|
329
|
+
if (await this.updatePagesJSON())
|
|
330
|
+
this.onUpdate();
|
|
305
331
|
});
|
|
306
332
|
watcher.on("change", async (path2) => {
|
|
307
333
|
path2 = slash(path2);
|
|
308
334
|
if (!isTargetFile(path2) && !isConfigFile(path2))
|
|
309
335
|
return;
|
|
310
336
|
debug.pages(`File changed: ${path2}`);
|
|
311
|
-
this.updatePagesJSON()
|
|
312
|
-
|
|
337
|
+
if (await this.updatePagesJSON(path2))
|
|
338
|
+
this.onUpdate();
|
|
313
339
|
});
|
|
314
340
|
watcher.on("unlink", async (path2) => {
|
|
315
341
|
path2 = slash(path2);
|
|
316
342
|
if (!isTargetFile(path2))
|
|
317
343
|
return;
|
|
318
344
|
debug.pages(`File removed: ${path2}`);
|
|
319
|
-
this.updatePagesJSON()
|
|
320
|
-
|
|
345
|
+
if (await this.updatePagesJSON())
|
|
346
|
+
this.onUpdate();
|
|
321
347
|
});
|
|
322
348
|
}
|
|
323
349
|
onUpdate() {
|
|
@@ -331,7 +357,9 @@ class PageContext {
|
|
|
331
357
|
}
|
|
332
358
|
async parsePage(page) {
|
|
333
359
|
const { relativePath, absolutePath } = page;
|
|
334
|
-
const
|
|
360
|
+
const routeSfcBlock = await getRouteSfcBlock(absolutePath);
|
|
361
|
+
const routeBlock = await getRouteBlock(absolutePath, routeSfcBlock, this.options);
|
|
362
|
+
setCache(absolutePath, routeSfcBlock);
|
|
335
363
|
const relativePathWithFileName = relativePath.replace(path__default.extname(relativePath), "");
|
|
336
364
|
const pageMetaDatum = {
|
|
337
365
|
path: vite.normalizePath(relativePathWithFileName),
|
|
@@ -396,7 +424,13 @@ class PageContext {
|
|
|
396
424
|
this.subPageMetaData = subPageMetaData;
|
|
397
425
|
debug.subPages(this.subPageMetaData);
|
|
398
426
|
}
|
|
399
|
-
async updatePagesJSON() {
|
|
427
|
+
async updatePagesJSON(filepath) {
|
|
428
|
+
if (filepath) {
|
|
429
|
+
if (!await hasChanged(filepath)) {
|
|
430
|
+
debug.cache(`The route block on page ${filepath} did not send any changes, skipping`);
|
|
431
|
+
return false;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
400
434
|
checkPagesJsonFile(this.resolvedPagesJSONPath);
|
|
401
435
|
this.options.onBeforeLoadUserConfig(this);
|
|
402
436
|
await this.loadUserPagesConfig();
|
|
@@ -418,15 +452,26 @@ class PageContext {
|
|
|
418
452
|
subPackages: this.subPageMetaData
|
|
419
453
|
};
|
|
420
454
|
const pagesJson = JSON.stringify(data, null, this.options.minify ? void 0 : 2);
|
|
455
|
+
if (lsatPagesJson === pagesJson) {
|
|
456
|
+
debug.pages("PagesJson Not have change");
|
|
457
|
+
return false;
|
|
458
|
+
}
|
|
421
459
|
writeFileSync(this.resolvedPagesJSONPath, pagesJson);
|
|
460
|
+
lsatPagesJson = pagesJson;
|
|
422
461
|
this.options.onAfterWriteFile(this);
|
|
462
|
+
return true;
|
|
423
463
|
}
|
|
424
|
-
|
|
425
|
-
|
|
464
|
+
virtualModule() {
|
|
465
|
+
const pages = `export const pages = ${this.resolveRoutes()};`;
|
|
466
|
+
const subPackages = `export const subPackages = ${this.resolveSubRoutes()};`;
|
|
467
|
+
return [pages, subPackages].join("\n");
|
|
426
468
|
}
|
|
427
469
|
resolveRoutes() {
|
|
428
470
|
return JSON.stringify(this.pageMetaData, null, 2);
|
|
429
471
|
}
|
|
472
|
+
resolveSubRoutes() {
|
|
473
|
+
return JSON.stringify(this.subPageMetaData, null, 2);
|
|
474
|
+
}
|
|
430
475
|
}
|
|
431
476
|
function getPagePaths(dir, options) {
|
|
432
477
|
const pagesDirPath = slash(path__default.resolve(options.root, dir));
|
|
@@ -491,7 +536,9 @@ function VitePluginUniPages(userOptions = {}) {
|
|
|
491
536
|
async transform(code, id) {
|
|
492
537
|
if (!/\.vue$/.test(id))
|
|
493
538
|
return null;
|
|
494
|
-
const s = new MagicString__default(code.toString()
|
|
539
|
+
const s = new MagicString__default(code.toString(), {
|
|
540
|
+
filename: id
|
|
541
|
+
});
|
|
495
542
|
const routeBlockMatches = s.original.matchAll(
|
|
496
543
|
/<route[^>]*>([\s\S]*?)<\/route>/g
|
|
497
544
|
);
|
|
@@ -500,7 +547,12 @@ function VitePluginUniPages(userOptions = {}) {
|
|
|
500
547
|
const length = match[0].length;
|
|
501
548
|
s.remove(index, index + length);
|
|
502
549
|
}
|
|
503
|
-
return
|
|
550
|
+
return {
|
|
551
|
+
code: s.toString(),
|
|
552
|
+
map: s.generateMap({
|
|
553
|
+
source: code
|
|
554
|
+
})
|
|
555
|
+
};
|
|
504
556
|
},
|
|
505
557
|
configureServer(server) {
|
|
506
558
|
ctx.setupViteServer(server);
|
|
@@ -530,6 +582,7 @@ exports.extsToGlob = extsToGlob;
|
|
|
530
582
|
exports.getPageFiles = getPageFiles;
|
|
531
583
|
exports.getPagesConfigSourcePaths = getPagesConfigSourcePaths;
|
|
532
584
|
exports.getRouteBlock = getRouteBlock;
|
|
585
|
+
exports.getRouteSfcBlock = getRouteSfcBlock;
|
|
533
586
|
exports.invalidatePagesModule = invalidatePagesModule;
|
|
534
587
|
exports.isConfigFile = isConfigFile;
|
|
535
588
|
exports.isTargetFile = isTargetFile;
|
|
@@ -538,4 +591,5 @@ exports.parseCustomBlock = parseCustomBlock;
|
|
|
538
591
|
exports.parseSFC = parseSFC;
|
|
539
592
|
exports.resolveOptions = resolveOptions;
|
|
540
593
|
exports.resolvePageDirs = resolvePageDirs;
|
|
594
|
+
exports.useCachedPages = useCachedPages;
|
|
541
595
|
exports.writeFileSync = writeFileSync;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Logger, ViteDevServer, Plugin } from 'vite';
|
|
2
2
|
import { FSWatcher } from 'chokidar';
|
|
3
3
|
import Debug from 'debug';
|
|
4
|
-
import {
|
|
4
|
+
import { SFCBlock, SFCDescriptor } from '@vue/compiler-sfc';
|
|
5
5
|
|
|
6
6
|
interface EasyCom {
|
|
7
7
|
autoscan: boolean;
|
|
@@ -660,9 +660,10 @@ declare class PageContext {
|
|
|
660
660
|
setHomePage(result: PageMetaDatum[]): true | undefined;
|
|
661
661
|
mergePageMetaData(): Promise<void>;
|
|
662
662
|
mergeSubPageMetaData(): Promise<void>;
|
|
663
|
-
updatePagesJSON(): Promise<
|
|
664
|
-
virtualModule():
|
|
663
|
+
updatePagesJSON(filepath?: string): Promise<boolean>;
|
|
664
|
+
virtualModule(): string;
|
|
665
665
|
resolveRoutes(): string;
|
|
666
|
+
resolveSubRoutes(): string;
|
|
666
667
|
}
|
|
667
668
|
|
|
668
669
|
declare function invalidatePagesModule(server: ViteDevServer): void;
|
|
@@ -673,6 +674,7 @@ declare const debug: {
|
|
|
673
674
|
pages: Debug.Debugger;
|
|
674
675
|
subPages: Debug.Debugger;
|
|
675
676
|
error: Debug.Debugger;
|
|
677
|
+
cache: Debug.Debugger;
|
|
676
678
|
};
|
|
677
679
|
declare function extsToGlob(extensions: string[]): string;
|
|
678
680
|
declare function isTargetFile(path: string): boolean;
|
|
@@ -684,6 +686,10 @@ declare function isConfigFile(path: string): boolean;
|
|
|
684
686
|
*/
|
|
685
687
|
declare function mergePageMetaDataArray(pageMetaData: PageMetaDatum[]): PageMetaDatum[];
|
|
686
688
|
declare function getPagesConfigSourcePaths(): Promise<string[]>;
|
|
689
|
+
declare function useCachedPages(): {
|
|
690
|
+
setCache: (filePath: string, routeBlock?: SFCBlock) => void;
|
|
691
|
+
hasChanged: (filePath: string, routeBlock?: SFCBlock) => Promise<boolean>;
|
|
692
|
+
};
|
|
687
693
|
|
|
688
694
|
interface CustomBlock {
|
|
689
695
|
attr: Record<string, any>;
|
|
@@ -805,8 +811,9 @@ declare function resolvePageDirs(dir: string, root: string, exclude: string[]):
|
|
|
805
811
|
|
|
806
812
|
declare function parseSFC(code: string): Promise<SFCDescriptor>;
|
|
807
813
|
declare function parseCustomBlock(block: SFCBlock, filePath: string, options: ResolvedOptions): CustomBlock | undefined;
|
|
808
|
-
declare function
|
|
814
|
+
declare function getRouteSfcBlock(path: string): Promise<SFCBlock | undefined>;
|
|
815
|
+
declare function getRouteBlock(path: string, blockStr: SFCBlock | undefined, options: ResolvedOptions): Promise<CustomBlock | undefined>;
|
|
809
816
|
|
|
810
817
|
declare function VitePluginUniPages(userOptions?: UserOptions): Plugin;
|
|
811
818
|
|
|
812
|
-
export { Condition, ConditionItem, CustomBlock, EasyCom, FILE_EXTENSIONS, GlobalStyle, IconFont, MODULE_ID_VIRTUAL, MidButton, OUTPUT_NAME, Options, PageContext, PageMetaDatum, PagePath, PagesConfig, PreloadRule, RESOLVED_MODULE_ID_VIRTUAL, ResolvedOptions, SubPackage, SubPageMetaDatum, TabBar, TabBarItem, TheWindow, UniIdRouter, UserOptions, UserPagesConfig, VitePluginUniPages, checkPagesJsonFile, debug, debugType, VitePluginUniPages as default, defineUniPages, extsToGlob, getPageFiles, getPagesConfigSourcePaths, getRouteBlock, invalidatePagesModule, isConfigFile, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, resolveOptions, resolvePageDirs, writeFileSync };
|
|
819
|
+
export { Condition, ConditionItem, CustomBlock, EasyCom, FILE_EXTENSIONS, GlobalStyle, IconFont, MODULE_ID_VIRTUAL, MidButton, OUTPUT_NAME, Options, PageContext, PageMetaDatum, PagePath, PagesConfig, PreloadRule, RESOLVED_MODULE_ID_VIRTUAL, ResolvedOptions, SubPackage, SubPageMetaDatum, TabBar, TabBarItem, TheWindow, UniIdRouter, UserOptions, UserPagesConfig, VitePluginUniPages, checkPagesJsonFile, debug, debugType, VitePluginUniPages as default, defineUniPages, extsToGlob, getPageFiles, getPagesConfigSourcePaths, getRouteBlock, getRouteSfcBlock, invalidatePagesModule, isConfigFile, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, resolveOptions, resolvePageDirs, useCachedPages, writeFileSync };
|
package/dist/index.mjs
CHANGED
|
@@ -22,6 +22,72 @@ const RESOLVED_MODULE_ID_VIRTUAL = `\0${MODULE_ID_VIRTUAL}`;
|
|
|
22
22
|
const OUTPUT_NAME = "pages.json";
|
|
23
23
|
const FILE_EXTENSIONS = ["vue", "nvue", "uvue"];
|
|
24
24
|
|
|
25
|
+
async function parseSFC(code) {
|
|
26
|
+
try {
|
|
27
|
+
return parse(code, {
|
|
28
|
+
pad: "space"
|
|
29
|
+
}).descriptor || parse({
|
|
30
|
+
source: code
|
|
31
|
+
});
|
|
32
|
+
} catch {
|
|
33
|
+
throw new Error(
|
|
34
|
+
`[vite-plugin-uni-pages] Vue3's "@vue/compiler-sfc" is required.`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function parseCustomBlock(block, filePath, options) {
|
|
39
|
+
const lang = block.lang ?? options.routeBlockLang;
|
|
40
|
+
const attr = {
|
|
41
|
+
type: "page",
|
|
42
|
+
...block.attrs
|
|
43
|
+
};
|
|
44
|
+
let content;
|
|
45
|
+
debug.routeBlock(`use ${lang} parser`);
|
|
46
|
+
if (lang === "json5" || lang === "jsonc") {
|
|
47
|
+
try {
|
|
48
|
+
content = JSON5.parse(block.content);
|
|
49
|
+
} catch (err) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Invalid JSON5 format of <${block.type}> content in ${filePath}
|
|
52
|
+
${err.message}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
} else if (lang === "json") {
|
|
56
|
+
try {
|
|
57
|
+
content = JSON.parse(block.content);
|
|
58
|
+
} catch (err) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`Invalid JSON format of <${block.type}> content in ${filePath}
|
|
61
|
+
${err.message}`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
} else if (lang === "yaml" || lang === "yml") {
|
|
65
|
+
try {
|
|
66
|
+
content = parse$1(block.content);
|
|
67
|
+
} catch (err) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
`Invalid YAML format of <${block.type}> content in ${filePath}
|
|
70
|
+
${err.message}`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
attr,
|
|
76
|
+
content: content ?? {}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
async function getRouteSfcBlock(path) {
|
|
80
|
+
const content = fs.readFileSync(path, "utf8");
|
|
81
|
+
const parsedSFC = await parseSFC(content);
|
|
82
|
+
const blockStr = parsedSFC?.customBlocks.find((b) => b.type === "route");
|
|
83
|
+
return blockStr;
|
|
84
|
+
}
|
|
85
|
+
async function getRouteBlock(path, blockStr, options) {
|
|
86
|
+
if (!blockStr)
|
|
87
|
+
return;
|
|
88
|
+
return parseCustomBlock(blockStr, path, options);
|
|
89
|
+
}
|
|
90
|
+
|
|
25
91
|
function invalidatePagesModule(server) {
|
|
26
92
|
const { moduleGraph } = server;
|
|
27
93
|
const mods = moduleGraph.getModulesByFile(RESOLVED_MODULE_ID_VIRTUAL);
|
|
@@ -38,7 +104,8 @@ const debug = {
|
|
|
38
104
|
options: Debug("vite-plugin-uni-pages:options"),
|
|
39
105
|
pages: Debug("vite-plugin-uni-pages:pages"),
|
|
40
106
|
subPages: Debug("vite-plugin-uni-pages:subPages"),
|
|
41
|
-
error: Debug("vite-plugin-uni-pages:error")
|
|
107
|
+
error: Debug("vite-plugin-uni-pages:error"),
|
|
108
|
+
cache: Debug("vite-plugin-uni-pages:cache")
|
|
42
109
|
};
|
|
43
110
|
function extsToGlob(extensions) {
|
|
44
111
|
return extensions.length > 1 ? `{${extensions.join(",")}}` : extensions[0] || "";
|
|
@@ -71,6 +138,27 @@ async function getPagesConfigSourcePaths() {
|
|
|
71
138
|
absolute: true
|
|
72
139
|
});
|
|
73
140
|
}
|
|
141
|
+
function useCachedPages() {
|
|
142
|
+
const pages = /* @__PURE__ */ new Map();
|
|
143
|
+
function parseData(block) {
|
|
144
|
+
return {
|
|
145
|
+
content: block?.loc.source.trim() ?? "",
|
|
146
|
+
attr: block?.attrs ?? ""
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function setCache(filePath, routeBlock) {
|
|
150
|
+
pages.set(filePath, JSON.stringify(parseData(routeBlock)));
|
|
151
|
+
}
|
|
152
|
+
async function hasChanged(filePath, routeBlock) {
|
|
153
|
+
if (!routeBlock)
|
|
154
|
+
routeBlock = await getRouteSfcBlock(normalizePath(filePath));
|
|
155
|
+
return !pages.has(filePath) || JSON.stringify(parseData(routeBlock)) !== pages.get(filePath);
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
setCache,
|
|
159
|
+
hasChanged
|
|
160
|
+
};
|
|
161
|
+
}
|
|
74
162
|
|
|
75
163
|
function resolveOptions(userOptions, viteRoot) {
|
|
76
164
|
const {
|
|
@@ -158,70 +246,8 @@ function writeFileSync(path, content) {
|
|
|
158
246
|
fs.writeFileSync(path, content, { encoding: "utf-8" });
|
|
159
247
|
}
|
|
160
248
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return parse(code, {
|
|
164
|
-
pad: "space"
|
|
165
|
-
}).descriptor || parse({
|
|
166
|
-
source: code
|
|
167
|
-
});
|
|
168
|
-
} catch {
|
|
169
|
-
throw new Error(
|
|
170
|
-
`[vite-plugin-uni-pages] Vue3's "@vue/compiler-sfc" is required.`
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
function parseCustomBlock(block, filePath, options) {
|
|
175
|
-
const lang = block.lang ?? options.routeBlockLang;
|
|
176
|
-
const attr = {
|
|
177
|
-
type: "page",
|
|
178
|
-
...block.attrs
|
|
179
|
-
};
|
|
180
|
-
let content;
|
|
181
|
-
debug.routeBlock(`use ${lang} parser`);
|
|
182
|
-
if (lang === "json5" || lang === "jsonc") {
|
|
183
|
-
try {
|
|
184
|
-
content = JSON5.parse(block.content);
|
|
185
|
-
} catch (err) {
|
|
186
|
-
throw new Error(
|
|
187
|
-
`Invalid JSON5 format of <${block.type}> content in ${filePath}
|
|
188
|
-
${err.message}`
|
|
189
|
-
);
|
|
190
|
-
}
|
|
191
|
-
} else if (lang === "json") {
|
|
192
|
-
try {
|
|
193
|
-
content = JSON.parse(block.content);
|
|
194
|
-
} catch (err) {
|
|
195
|
-
throw new Error(
|
|
196
|
-
`Invalid JSON format of <${block.type}> content in ${filePath}
|
|
197
|
-
${err.message}`
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
} else if (lang === "yaml" || lang === "yml") {
|
|
201
|
-
try {
|
|
202
|
-
content = parse$1(block.content);
|
|
203
|
-
} catch (err) {
|
|
204
|
-
throw new Error(
|
|
205
|
-
`Invalid YAML format of <${block.type}> content in ${filePath}
|
|
206
|
-
${err.message}`
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return {
|
|
211
|
-
attr,
|
|
212
|
-
content: content ?? {}
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
async function getRouteBlock(path, options) {
|
|
216
|
-
const content = fs.readFileSync(path, "utf8");
|
|
217
|
-
const parsedSFC = await parseSFC(content);
|
|
218
|
-
const blockStr = parsedSFC?.customBlocks.find((b) => b.type === "route");
|
|
219
|
-
if (!blockStr)
|
|
220
|
-
return;
|
|
221
|
-
const result = parseCustomBlock(blockStr, path, options);
|
|
222
|
-
return result;
|
|
223
|
-
}
|
|
224
|
-
|
|
249
|
+
let lsatPagesJson = "";
|
|
250
|
+
const { setCache, hasChanged } = useCachedPages();
|
|
225
251
|
class PageContext {
|
|
226
252
|
constructor(userOptions, viteRoot = process.cwd()) {
|
|
227
253
|
this.pagesPath = [];
|
|
@@ -286,24 +312,24 @@ class PageContext {
|
|
|
286
312
|
if (!isTargetFile(path2))
|
|
287
313
|
return;
|
|
288
314
|
debug.pages(`File added: ${path2}`);
|
|
289
|
-
this.updatePagesJSON()
|
|
290
|
-
|
|
315
|
+
if (await this.updatePagesJSON())
|
|
316
|
+
this.onUpdate();
|
|
291
317
|
});
|
|
292
318
|
watcher.on("change", async (path2) => {
|
|
293
319
|
path2 = slash(path2);
|
|
294
320
|
if (!isTargetFile(path2) && !isConfigFile(path2))
|
|
295
321
|
return;
|
|
296
322
|
debug.pages(`File changed: ${path2}`);
|
|
297
|
-
this.updatePagesJSON()
|
|
298
|
-
|
|
323
|
+
if (await this.updatePagesJSON(path2))
|
|
324
|
+
this.onUpdate();
|
|
299
325
|
});
|
|
300
326
|
watcher.on("unlink", async (path2) => {
|
|
301
327
|
path2 = slash(path2);
|
|
302
328
|
if (!isTargetFile(path2))
|
|
303
329
|
return;
|
|
304
330
|
debug.pages(`File removed: ${path2}`);
|
|
305
|
-
this.updatePagesJSON()
|
|
306
|
-
|
|
331
|
+
if (await this.updatePagesJSON())
|
|
332
|
+
this.onUpdate();
|
|
307
333
|
});
|
|
308
334
|
}
|
|
309
335
|
onUpdate() {
|
|
@@ -317,7 +343,9 @@ class PageContext {
|
|
|
317
343
|
}
|
|
318
344
|
async parsePage(page) {
|
|
319
345
|
const { relativePath, absolutePath } = page;
|
|
320
|
-
const
|
|
346
|
+
const routeSfcBlock = await getRouteSfcBlock(absolutePath);
|
|
347
|
+
const routeBlock = await getRouteBlock(absolutePath, routeSfcBlock, this.options);
|
|
348
|
+
setCache(absolutePath, routeSfcBlock);
|
|
321
349
|
const relativePathWithFileName = relativePath.replace(path.extname(relativePath), "");
|
|
322
350
|
const pageMetaDatum = {
|
|
323
351
|
path: normalizePath(relativePathWithFileName),
|
|
@@ -382,7 +410,13 @@ class PageContext {
|
|
|
382
410
|
this.subPageMetaData = subPageMetaData;
|
|
383
411
|
debug.subPages(this.subPageMetaData);
|
|
384
412
|
}
|
|
385
|
-
async updatePagesJSON() {
|
|
413
|
+
async updatePagesJSON(filepath) {
|
|
414
|
+
if (filepath) {
|
|
415
|
+
if (!await hasChanged(filepath)) {
|
|
416
|
+
debug.cache(`The route block on page ${filepath} did not send any changes, skipping`);
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
386
420
|
checkPagesJsonFile(this.resolvedPagesJSONPath);
|
|
387
421
|
this.options.onBeforeLoadUserConfig(this);
|
|
388
422
|
await this.loadUserPagesConfig();
|
|
@@ -404,15 +438,26 @@ class PageContext {
|
|
|
404
438
|
subPackages: this.subPageMetaData
|
|
405
439
|
};
|
|
406
440
|
const pagesJson = JSON.stringify(data, null, this.options.minify ? void 0 : 2);
|
|
441
|
+
if (lsatPagesJson === pagesJson) {
|
|
442
|
+
debug.pages("PagesJson Not have change");
|
|
443
|
+
return false;
|
|
444
|
+
}
|
|
407
445
|
writeFileSync(this.resolvedPagesJSONPath, pagesJson);
|
|
446
|
+
lsatPagesJson = pagesJson;
|
|
408
447
|
this.options.onAfterWriteFile(this);
|
|
448
|
+
return true;
|
|
409
449
|
}
|
|
410
|
-
|
|
411
|
-
|
|
450
|
+
virtualModule() {
|
|
451
|
+
const pages = `export const pages = ${this.resolveRoutes()};`;
|
|
452
|
+
const subPackages = `export const subPackages = ${this.resolveSubRoutes()};`;
|
|
453
|
+
return [pages, subPackages].join("\n");
|
|
412
454
|
}
|
|
413
455
|
resolveRoutes() {
|
|
414
456
|
return JSON.stringify(this.pageMetaData, null, 2);
|
|
415
457
|
}
|
|
458
|
+
resolveSubRoutes() {
|
|
459
|
+
return JSON.stringify(this.subPageMetaData, null, 2);
|
|
460
|
+
}
|
|
416
461
|
}
|
|
417
462
|
function getPagePaths(dir, options) {
|
|
418
463
|
const pagesDirPath = slash(path.resolve(options.root, dir));
|
|
@@ -477,7 +522,9 @@ function VitePluginUniPages(userOptions = {}) {
|
|
|
477
522
|
async transform(code, id) {
|
|
478
523
|
if (!/\.vue$/.test(id))
|
|
479
524
|
return null;
|
|
480
|
-
const s = new MagicString(code.toString()
|
|
525
|
+
const s = new MagicString(code.toString(), {
|
|
526
|
+
filename: id
|
|
527
|
+
});
|
|
481
528
|
const routeBlockMatches = s.original.matchAll(
|
|
482
529
|
/<route[^>]*>([\s\S]*?)<\/route>/g
|
|
483
530
|
);
|
|
@@ -486,7 +533,12 @@ function VitePluginUniPages(userOptions = {}) {
|
|
|
486
533
|
const length = match[0].length;
|
|
487
534
|
s.remove(index, index + length);
|
|
488
535
|
}
|
|
489
|
-
return
|
|
536
|
+
return {
|
|
537
|
+
code: s.toString(),
|
|
538
|
+
map: s.generateMap({
|
|
539
|
+
source: code
|
|
540
|
+
})
|
|
541
|
+
};
|
|
490
542
|
},
|
|
491
543
|
configureServer(server) {
|
|
492
544
|
ctx.setupViteServer(server);
|
|
@@ -502,4 +554,4 @@ function VitePluginUniPages(userOptions = {}) {
|
|
|
502
554
|
};
|
|
503
555
|
}
|
|
504
556
|
|
|
505
|
-
export { FILE_EXTENSIONS, MODULE_ID_VIRTUAL, OUTPUT_NAME, PageContext, RESOLVED_MODULE_ID_VIRTUAL, VitePluginUniPages, checkPagesJsonFile, debug, VitePluginUniPages as default, defineUniPages, extsToGlob, getPageFiles, getPagesConfigSourcePaths, getRouteBlock, invalidatePagesModule, isConfigFile, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, resolveOptions, resolvePageDirs, writeFileSync };
|
|
557
|
+
export { FILE_EXTENSIONS, MODULE_ID_VIRTUAL, OUTPUT_NAME, PageContext, RESOLVED_MODULE_ID_VIRTUAL, VitePluginUniPages, checkPagesJsonFile, debug, VitePluginUniPages as default, defineUniPages, extsToGlob, getPageFiles, getPagesConfigSourcePaths, getRouteBlock, getRouteSfcBlock, invalidatePagesModule, isConfigFile, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, resolveOptions, resolvePageDirs, useCachedPages, writeFileSync };
|