@uni-helper/vite-plugin-uni-pages 0.2.3 → 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/dist/index.cjs +124 -75
- package/dist/index.d.ts +10 -4
- package/dist/index.mjs +123 -76
- package/package.json +1 -1
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,8 +452,14 @@ 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
464
|
virtualModule() {
|
|
425
465
|
const pages = `export const pages = ${this.resolveRoutes()};`;
|
|
@@ -496,7 +536,9 @@ function VitePluginUniPages(userOptions = {}) {
|
|
|
496
536
|
async transform(code, id) {
|
|
497
537
|
if (!/\.vue$/.test(id))
|
|
498
538
|
return null;
|
|
499
|
-
const s = new MagicString__default(code.toString()
|
|
539
|
+
const s = new MagicString__default(code.toString(), {
|
|
540
|
+
filename: id
|
|
541
|
+
});
|
|
500
542
|
const routeBlockMatches = s.original.matchAll(
|
|
501
543
|
/<route[^>]*>([\s\S]*?)<\/route>/g
|
|
502
544
|
);
|
|
@@ -505,7 +547,12 @@ function VitePluginUniPages(userOptions = {}) {
|
|
|
505
547
|
const length = match[0].length;
|
|
506
548
|
s.remove(index, index + length);
|
|
507
549
|
}
|
|
508
|
-
return
|
|
550
|
+
return {
|
|
551
|
+
code: s.toString(),
|
|
552
|
+
map: s.generateMap({
|
|
553
|
+
source: code
|
|
554
|
+
})
|
|
555
|
+
};
|
|
509
556
|
},
|
|
510
557
|
configureServer(server) {
|
|
511
558
|
ctx.setupViteServer(server);
|
|
@@ -535,6 +582,7 @@ exports.extsToGlob = extsToGlob;
|
|
|
535
582
|
exports.getPageFiles = getPageFiles;
|
|
536
583
|
exports.getPagesConfigSourcePaths = getPagesConfigSourcePaths;
|
|
537
584
|
exports.getRouteBlock = getRouteBlock;
|
|
585
|
+
exports.getRouteSfcBlock = getRouteSfcBlock;
|
|
538
586
|
exports.invalidatePagesModule = invalidatePagesModule;
|
|
539
587
|
exports.isConfigFile = isConfigFile;
|
|
540
588
|
exports.isTargetFile = isTargetFile;
|
|
@@ -543,4 +591,5 @@ exports.parseCustomBlock = parseCustomBlock;
|
|
|
543
591
|
exports.parseSFC = parseSFC;
|
|
544
592
|
exports.resolveOptions = resolveOptions;
|
|
545
593
|
exports.resolvePageDirs = resolvePageDirs;
|
|
594
|
+
exports.useCachedPages = useCachedPages;
|
|
546
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,7 +660,7 @@ declare class PageContext {
|
|
|
660
660
|
setHomePage(result: PageMetaDatum[]): true | undefined;
|
|
661
661
|
mergePageMetaData(): Promise<void>;
|
|
662
662
|
mergeSubPageMetaData(): Promise<void>;
|
|
663
|
-
updatePagesJSON(): Promise<
|
|
663
|
+
updatePagesJSON(filepath?: string): Promise<boolean>;
|
|
664
664
|
virtualModule(): string;
|
|
665
665
|
resolveRoutes(): string;
|
|
666
666
|
resolveSubRoutes(): string;
|
|
@@ -674,6 +674,7 @@ declare const debug: {
|
|
|
674
674
|
pages: Debug.Debugger;
|
|
675
675
|
subPages: Debug.Debugger;
|
|
676
676
|
error: Debug.Debugger;
|
|
677
|
+
cache: Debug.Debugger;
|
|
677
678
|
};
|
|
678
679
|
declare function extsToGlob(extensions: string[]): string;
|
|
679
680
|
declare function isTargetFile(path: string): boolean;
|
|
@@ -685,6 +686,10 @@ declare function isConfigFile(path: string): boolean;
|
|
|
685
686
|
*/
|
|
686
687
|
declare function mergePageMetaDataArray(pageMetaData: PageMetaDatum[]): PageMetaDatum[];
|
|
687
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
|
+
};
|
|
688
693
|
|
|
689
694
|
interface CustomBlock {
|
|
690
695
|
attr: Record<string, any>;
|
|
@@ -806,8 +811,9 @@ declare function resolvePageDirs(dir: string, root: string, exclude: string[]):
|
|
|
806
811
|
|
|
807
812
|
declare function parseSFC(code: string): Promise<SFCDescriptor>;
|
|
808
813
|
declare function parseCustomBlock(block: SFCBlock, filePath: string, options: ResolvedOptions): CustomBlock | undefined;
|
|
809
|
-
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>;
|
|
810
816
|
|
|
811
817
|
declare function VitePluginUniPages(userOptions?: UserOptions): Plugin;
|
|
812
818
|
|
|
813
|
-
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,8 +438,14 @@ 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
450
|
virtualModule() {
|
|
411
451
|
const pages = `export const pages = ${this.resolveRoutes()};`;
|
|
@@ -482,7 +522,9 @@ function VitePluginUniPages(userOptions = {}) {
|
|
|
482
522
|
async transform(code, id) {
|
|
483
523
|
if (!/\.vue$/.test(id))
|
|
484
524
|
return null;
|
|
485
|
-
const s = new MagicString(code.toString()
|
|
525
|
+
const s = new MagicString(code.toString(), {
|
|
526
|
+
filename: id
|
|
527
|
+
});
|
|
486
528
|
const routeBlockMatches = s.original.matchAll(
|
|
487
529
|
/<route[^>]*>([\s\S]*?)<\/route>/g
|
|
488
530
|
);
|
|
@@ -491,7 +533,12 @@ function VitePluginUniPages(userOptions = {}) {
|
|
|
491
533
|
const length = match[0].length;
|
|
492
534
|
s.remove(index, index + length);
|
|
493
535
|
}
|
|
494
|
-
return
|
|
536
|
+
return {
|
|
537
|
+
code: s.toString(),
|
|
538
|
+
map: s.generateMap({
|
|
539
|
+
source: code
|
|
540
|
+
})
|
|
541
|
+
};
|
|
495
542
|
},
|
|
496
543
|
configureServer(server) {
|
|
497
544
|
ctx.setupViteServer(server);
|
|
@@ -507,4 +554,4 @@ function VitePluginUniPages(userOptions = {}) {
|
|
|
507
554
|
};
|
|
508
555
|
}
|
|
509
556
|
|
|
510
|
-
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 };
|