@uni-helper/vite-plugin-uni-pages 0.3.16 → 0.3.17

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 CHANGED
@@ -235,6 +235,9 @@ ${jsCode}
235
235
  `);
236
236
  }
237
237
  }
238
+ function sleep(ms) {
239
+ return new Promise((resolve) => setTimeout(resolve, ms));
240
+ }
238
241
  function getDefaultExport(expr) {
239
242
  return expr.default === void 0 ? expr : expr.default;
240
243
  }
@@ -250,33 +253,73 @@ function getPageFiles(path, options) {
250
253
  });
251
254
  return files;
252
255
  }
253
- async function checkPagesJsonFile(path) {
256
+ function checkPagesJsonFileSync(path) {
254
257
  const createEmptyFile = (path2) => {
255
- return fs__default.promises.writeFile(path2, JSON.stringify({ pages: [{ path: "" }] }, null, 2), { encoding: "utf-8" }).then(() => true).catch(() => false);
258
+ try {
259
+ fs__default.writeFileSync(
260
+ path2,
261
+ JSON.stringify({ pages: [{ path: "" }] }, null, 2),
262
+ { encoding: "utf-8" }
263
+ );
264
+ return true;
265
+ } catch {
266
+ return false;
267
+ }
256
268
  };
257
- const unlink = (path2) => {
258
- return fs__default.promises.unlink(path2).then(() => true).catch(() => false);
269
+ const unlinkFile = (path2) => {
270
+ try {
271
+ fs__default.unlinkSync(path2);
272
+ return true;
273
+ } catch {
274
+ return false;
275
+ }
259
276
  };
260
277
  try {
261
- const stat = await fs__default.promises.stat(path);
278
+ try {
279
+ fs__default.accessSync(path, fs__default.constants.F_OK);
280
+ } catch {
281
+ return createEmptyFile(path);
282
+ }
283
+ const stat = fs__default.statSync(path);
262
284
  if (!stat.isFile()) {
263
- if (!await unlink(path)) {
285
+ if (!unlinkFile(path)) {
264
286
  return false;
265
287
  }
266
288
  return createEmptyFile(path);
267
289
  }
268
- const access = await fs__default.promises.access(path, fs__default.constants.W_OK | fs__default.constants.R_OK).then(() => true).catch(() => false);
269
- if (!access) {
270
- if (!await unlink(path)) {
290
+ try {
291
+ fs__default.accessSync(path, fs__default.constants.R_OK | fs__default.constants.W_OK);
292
+ return true;
293
+ } catch {
294
+ if (!unlinkFile(path)) {
271
295
  return false;
272
296
  }
273
297
  return createEmptyFile(path);
274
298
  }
275
- return true;
276
299
  } catch {
277
300
  return createEmptyFile(path);
278
301
  }
279
302
  }
303
+ async function writeFileWithLock(path, content, retry = 3) {
304
+ if (retry <= 0) {
305
+ debug.error(`${path} \u83B7\u53D6\u6587\u4EF6\u9501\u5931\u8D25\uFF0C\u5199\u5165\u5931\u8D25`);
306
+ return;
307
+ }
308
+ let relase;
309
+ try {
310
+ try {
311
+ relase = await lockfile__default.lock(path, { realpath: false });
312
+ } catch {
313
+ await sleep(500);
314
+ return writeFileWithLock(path, content, retry - 1);
315
+ }
316
+ await fs__default.promises.writeFile(path, content, { encoding: "utf-8" });
317
+ } finally {
318
+ if (relase) {
319
+ await relase();
320
+ }
321
+ }
322
+ }
280
323
 
281
324
  function resolveOptions(userOptions, viteRoot = process__default.cwd()) {
282
325
  const {
@@ -569,7 +612,6 @@ var __publicField = (obj, key, value) => {
569
612
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
570
613
  return value;
571
614
  };
572
- let lsatPagesJson = "";
573
615
  class PageContext {
574
616
  constructor(userOptions, viteRoot = process__default.cwd()) {
575
617
  __publicField(this, "_server");
@@ -593,6 +635,7 @@ class PageContext {
593
635
  __publicField(this, "options");
594
636
  __publicField(this, "logger");
595
637
  __publicField(this, "withUniPlatform", false);
638
+ __publicField(this, "lastPagesJson", "");
596
639
  this.rawOptions = userOptions;
597
640
  this.root = slash(viteRoot);
598
641
  debug.options("root", this.root);
@@ -819,7 +862,7 @@ class PageContext {
819
862
  }
820
863
  }
821
864
  }
822
- await checkPagesJsonFile(this.resolvedPagesJSONPath);
865
+ checkPagesJsonFileSync(this.resolvedPagesJSONPath);
823
866
  this.options.onBeforeLoadUserConfig(this);
824
867
  await this.loadUserPagesConfig();
825
868
  this.options.onAfterLoadUserConfig(this);
@@ -841,29 +884,19 @@ class PageContext {
841
884
  pages.forEach((v) => pagesMap.set(v.path, v));
842
885
  this.pageMetaData = [...pagesMap.values()];
843
886
  this.options.onBeforeWriteFile(this);
844
- const data = {
845
- ...this.pagesGlobConfig,
846
- pages: this.pageMetaData,
847
- subPackages: this.subPageMetaData,
848
- tabBar: await this.getTabBarMerged()
849
- };
887
+ const data = await this.genratePagesJSON();
850
888
  const pagesJson = commentJson.stringify(
851
889
  data,
852
890
  null,
853
891
  this.options.minify ? void 0 : await this.getIndent()
854
892
  ) + (await this.getEndOfLine() ? await this.getNewline() : "");
855
893
  this.generateDeclaration();
856
- if (lsatPagesJson === pagesJson) {
894
+ if (this.lastPagesJson === pagesJson) {
857
895
  debug.pages("PagesJson Not have change");
858
896
  return false;
859
897
  }
860
- const relase = await lockfile__default.lock(this.resolvedPagesJSONPath, { realpath: false });
861
- try {
862
- await fs__default.promises.writeFile(this.resolvedPagesJSONPath, pagesJson, { encoding: "utf-8" });
863
- } finally {
864
- await relase();
865
- }
866
- lsatPagesJson = pagesJson;
898
+ await writeFileWithLock(this.resolvedPagesJSONPath, pagesJson);
899
+ this.lastPagesJson = pagesJson;
867
900
  this.options.onAfterWriteFile(this);
868
901
  return true;
869
902
  }
@@ -884,6 +917,64 @@ class PageContext {
884
917
  debug.declaration("generating");
885
918
  return writeDeclaration(this, this.options.dts);
886
919
  }
920
+ async writePagesJSONFile(pagesJson, retry = 3) {
921
+ if (retry <= 0) {
922
+ debug.error(`${this.resolvedPagesJSONPath} \u83B7\u53D6\u6587\u4EF6\u9501\u5931\u8D25\uFF0C\u5199\u5165\u5931\u8D25`);
923
+ return;
924
+ }
925
+ let relase;
926
+ try {
927
+ try {
928
+ relase = await lockfile__default.lock(this.resolvedPagesJSONPath, { realpath: false });
929
+ } catch {
930
+ return this.writePagesJSONFile(pagesJson, retry - 1);
931
+ }
932
+ await fs__default.promises.writeFile(this.resolvedPagesJSONPath, pagesJson, { encoding: "utf-8" });
933
+ } finally {
934
+ if (relase) {
935
+ await relase();
936
+ }
937
+ }
938
+ }
939
+ async genratePagesJSON() {
940
+ const content = await fs__default.promises.readFile(this.resolvedPagesJSONPath, { encoding: "utf-8" }).catch(() => "");
941
+ let pageJson = commentJson.parse(content || "{}");
942
+ const { pages: _, subPackages: __, tabBar: ___, ...others } = this.pagesGlobConfig || {};
943
+ pageJson = Object.assign(pageJson, {
944
+ ...others
945
+ });
946
+ const currentPlatform = uniEnv.platform.toUpperCase();
947
+ pageJson.pages = mergePlatformItems(pageJson?.pages, currentPlatform, this.pageMetaData, "path");
948
+ pageJson.subPackages = pageJson?.subPackages || new commentJson.CommentArray();
949
+ const newSubPackages = /* @__PURE__ */ new Map();
950
+ for (const item of this.subPageMetaData) {
951
+ newSubPackages.set(item.root, item);
952
+ }
953
+ for (const existing of pageJson.subPackages) {
954
+ const sub = newSubPackages.get(existing.root);
955
+ if (sub) {
956
+ existing.pages = mergePlatformItems(existing.pages, currentPlatform, sub.pages, "path");
957
+ newSubPackages.delete(existing.root);
958
+ }
959
+ }
960
+ for (const [_2, newSub] of newSubPackages) {
961
+ pageJson.subPackages.push({
962
+ root: newSub.root,
963
+ pages: mergePlatformItems(void 0, currentPlatform, newSub.pages, "path")
964
+ });
965
+ }
966
+ const tabBar = await this.getTabBarMerged();
967
+ if (tabBar) {
968
+ const list = mergePlatformItems(pageJson?.tabBar?.list, currentPlatform, tabBar.list, "pagePath");
969
+ if (pageJson?.tabBar?.list) {
970
+ pageJson.tabBar.list = list;
971
+ } else {
972
+ pageJson.tabBar = pageJson.tabBar || {};
973
+ pageJson.tabBar.list = list;
974
+ }
975
+ }
976
+ return pageJson;
977
+ }
887
978
  async readInfoFromPagesJSON() {
888
979
  const resolvedPagesJSONContent = await fs__default.promises.readFile(this.resolvedPagesJSONPath, { encoding: "utf-8" }).catch(() => "");
889
980
  this.resolvedPagesJSONIndent = detectIndent__default(resolvedPagesJSONContent).indent || " ";
@@ -920,19 +1011,125 @@ function getPagePaths(dir, options) {
920
1011
  }));
921
1012
  return pagePaths;
922
1013
  }
1014
+ function mergePlatformItems(source, currentPlatform, items, uniqueKeyName) {
1015
+ const src = source || new commentJson.CommentArray();
1016
+ currentPlatform = currentPlatform.toUpperCase();
1017
+ let lastPlatforms = [];
1018
+ for (const comment of src[Symbol.for("before:0")] || []) {
1019
+ const trimed = comment.value.trim();
1020
+ if (trimed.startsWith("GENERATED BY UNI-PAGES, PLATFORM:")) {
1021
+ lastPlatforms = trimed.split(":")[1].split("||").map((s) => s.trim()).filter((s) => s !== currentPlatform).sort();
1022
+ }
1023
+ }
1024
+ const tmpMap = /* @__PURE__ */ new Map();
1025
+ for (let i = 0; i < src.length; i++) {
1026
+ const item = src[i];
1027
+ const uniqueKey = item[uniqueKeyName];
1028
+ if (!uniqueKey) {
1029
+ continue;
1030
+ }
1031
+ const beforeComments = src[Symbol.for(`before:${i}`)];
1032
+ const ifdefComment = beforeComments?.find((c) => c.value.trim().startsWith("#ifdef"));
1033
+ let platforms = [...lastPlatforms];
1034
+ if (ifdefComment) {
1035
+ const match = ifdefComment.value.match(/#ifdef\s+(.+)/);
1036
+ if (match) {
1037
+ platforms = match[1].split("||").map((p) => p.trim()).filter((s) => s !== currentPlatform).sort();
1038
+ }
1039
+ }
1040
+ if (platforms.length === 0) {
1041
+ continue;
1042
+ }
1043
+ const existing = tmpMap.get(uniqueKey) || [];
1044
+ existing.push({ item, platforms, platformStr: platforms.join(" || ") });
1045
+ tmpMap.set(uniqueKey, existing);
1046
+ }
1047
+ for (const item of items) {
1048
+ const newItem = item;
1049
+ const uniqueKey = item[uniqueKeyName];
1050
+ if (!uniqueKey) {
1051
+ continue;
1052
+ }
1053
+ if (!tmpMap.has(uniqueKey)) {
1054
+ tmpMap.set(uniqueKey, [{
1055
+ item: newItem,
1056
+ platforms: [currentPlatform],
1057
+ platformStr: currentPlatform
1058
+ }]);
1059
+ continue;
1060
+ }
1061
+ const existing = tmpMap.get(uniqueKey);
1062
+ const newItemStr = JSON.stringify(newItem);
1063
+ const equalObj = existing.find((val) => JSON.stringify(val.item) === newItemStr);
1064
+ if (equalObj) {
1065
+ equalObj.platforms.push(currentPlatform);
1066
+ equalObj.platformStr = equalObj.platforms.join(" || ");
1067
+ } else {
1068
+ existing.push({
1069
+ item: newItem,
1070
+ platforms: [currentPlatform],
1071
+ platformStr: currentPlatform
1072
+ });
1073
+ }
1074
+ }
1075
+ const result = new commentJson.CommentArray();
1076
+ const platformUsage = {};
1077
+ tmpMap.forEach((val) => {
1078
+ Object.values(val).forEach((v) => {
1079
+ platformUsage[v.platformStr] = (platformUsage[v.platformStr] || 0) + 1;
1080
+ });
1081
+ });
1082
+ const usageKeys = Object.keys(platformUsage);
1083
+ const defaultPlatformStr = usageKeys.length ? usageKeys.reduce((a, b) => platformUsage[a] > platformUsage[b] ? a : b) : currentPlatform;
1084
+ result[Symbol.for("before:0")] = [{
1085
+ type: "LineComment",
1086
+ value: ` GENERATED BY UNI-PAGES, PLATFORM: ${defaultPlatformStr}`,
1087
+ inline: false,
1088
+ loc: {
1089
+ start: { line: 0, column: 0 },
1090
+ end: { line: 0, column: 0 }
1091
+ }
1092
+ }];
1093
+ for (const [_, list] of tmpMap) {
1094
+ for (const { item, platformStr } of list) {
1095
+ result.push(item);
1096
+ if (platformStr !== defaultPlatformStr) {
1097
+ result[Symbol.for(`before:${result.length - 1}`)] = [{
1098
+ type: "LineComment",
1099
+ value: ` #ifdef ${platformStr}`,
1100
+ inline: false,
1101
+ loc: {
1102
+ start: { line: 0, column: 0 },
1103
+ end: { line: 0, column: 0 }
1104
+ }
1105
+ }];
1106
+ result[Symbol.for(`after:${result.length - 1}`)] = [{
1107
+ type: "LineComment",
1108
+ value: " #endif",
1109
+ inline: false,
1110
+ loc: {
1111
+ start: { line: 0, column: 0 },
1112
+ end: { line: 0, column: 0 }
1113
+ }
1114
+ }];
1115
+ }
1116
+ }
1117
+ }
1118
+ return result;
1119
+ }
923
1120
 
924
1121
  function defineUniPages(config) {
925
1122
  return config;
926
1123
  }
927
1124
 
928
- async function VitePluginUniPages(userOptions = {}) {
1125
+ function VitePluginUniPages(userOptions = {}) {
929
1126
  let ctx;
930
1127
  const resolvedPagesJSONPath = path__default.join(
931
1128
  process__default.env.VITE_ROOT_DIR || process__default.cwd(),
932
1129
  userOptions.outDir ?? "src",
933
1130
  OUTPUT_NAME
934
1131
  );
935
- await checkPagesJsonFile(resolvedPagesJSONPath);
1132
+ checkPagesJsonFileSync(resolvedPagesJSONPath);
936
1133
  return {
937
1134
  name: "vite-plugin-uni-pages",
938
1135
  enforce: "pre",
@@ -1019,7 +1216,7 @@ exports.PageContext = PageContext;
1019
1216
  exports.RESOLVED_MODULE_ID_VIRTUAL = RESOLVED_MODULE_ID_VIRTUAL;
1020
1217
  exports.VitePluginUniPages = VitePluginUniPages;
1021
1218
  exports.babelGenerate = babelGenerate;
1022
- exports.checkPagesJsonFile = checkPagesJsonFile;
1219
+ exports.checkPagesJsonFileSync = checkPagesJsonFileSync;
1023
1220
  exports.debug = debug;
1024
1221
  exports.default = VitePluginUniPages;
1025
1222
  exports.defineUniPages = defineUniPages;
@@ -1037,5 +1234,7 @@ exports.parseCustomBlock = parseCustomBlock;
1037
1234
  exports.parseSFC = parseSFC;
1038
1235
  exports.resolveOptions = resolveOptions;
1039
1236
  exports.resolvePageDirs = resolvePageDirs;
1237
+ exports.sleep = sleep;
1040
1238
  exports.tryPageMetaFromCustomBlock = tryPageMetaFromCustomBlock;
1041
1239
  exports.tryPageMetaFromMacro = tryPageMetaFromMacro;
1240
+ exports.writeFileWithLock = writeFileWithLock;
package/dist/index.d.cts CHANGED
@@ -2964,6 +2964,7 @@ declare class PageContext {
2964
2964
  options: ResolvedOptions;
2965
2965
  logger?: Logger;
2966
2966
  withUniPlatform: boolean;
2967
+ private lastPagesJson;
2967
2968
  constructor(userOptions: UserOptions, viteRoot?: string);
2968
2969
  setLogger(logger: Logger): void;
2969
2970
  loadUserPagesConfig(): Promise<void>;
@@ -2994,6 +2995,8 @@ declare class PageContext {
2994
2995
  resolveRoutes(): string;
2995
2996
  resolveSubRoutes(): string;
2996
2997
  generateDeclaration(): Promise<void> | undefined;
2998
+ private writePagesJSONFile;
2999
+ private genratePagesJSON;
2997
3000
  private readInfoFromPagesJSON;
2998
3001
  private getIndent;
2999
3002
  private getNewline;
@@ -3034,6 +3037,7 @@ declare function execScript(options: {
3034
3037
  code: string;
3035
3038
  filename: string;
3036
3039
  }): Promise<any>;
3040
+ declare function sleep(ms: number): Promise<unknown>;
3037
3041
  declare const babelGenerate: typeof babelGenerator;
3038
3042
 
3039
3043
  interface CustomBlock {
@@ -3195,11 +3199,12 @@ declare function getRouteBlock(path: string, blockStr: SFCBlock | undefined, rou
3195
3199
  */
3196
3200
  declare function getPageFiles(path: string, options: ResolvedOptions): string[];
3197
3201
  /**
3198
- * 检查指定路径的pages.json文件,如果文件不存在或不是有效文件则创建一个空的pages.json文件
3202
+ * 检查指定路径的 pages.json 文件,如果文件不存在或不是有效文件则创建一个空的 pages.json 文件
3199
3203
  * @param path - 要检查的文件路径
3200
- * @returns Promise<void> - 无返回值的异步函数
3204
+ * @returns boolean - 返回操作是否成功
3201
3205
  */
3202
- declare function checkPagesJsonFile(path: fs.PathLike): Promise<boolean>;
3206
+ declare function checkPagesJsonFileSync(path: fs.PathLike): boolean;
3207
+ declare function writeFileWithLock(path: string, content: string, retry?: number): Promise<void>;
3203
3208
 
3204
3209
  declare function resolveOptions(userOptions: UserOptions, viteRoot?: string): ResolvedOptions;
3205
3210
  /**
@@ -3207,7 +3212,7 @@ declare function resolveOptions(userOptions: UserOptions, viteRoot?: string): Re
3207
3212
  */
3208
3213
  declare function resolvePageDirs(dir: string, root: string, exclude: string[]): string[];
3209
3214
 
3210
- declare function VitePluginUniPages(userOptions?: UserOptions): Promise<Plugin>;
3215
+ declare function VitePluginUniPages(userOptions?: UserOptions): Plugin;
3211
3216
 
3212
- export { FILE_EXTENSIONS, MODULE_ID_VIRTUAL, OUTPUT_NAME, Page, PageContext, RESOLVED_MODULE_ID_VIRTUAL, VitePluginUniPages, babelGenerate, checkPagesJsonFile, debug, VitePluginUniPages as default, definePage, defineUniPages, execScript, extsToGlob, findImports, findMacro, getPageFiles, getRouteBlock, getRouteSfcBlock, invalidatePagesModule, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, resolveOptions, resolvePageDirs, tryPageMetaFromCustomBlock, tryPageMetaFromMacro };
3217
+ export { FILE_EXTENSIONS, MODULE_ID_VIRTUAL, OUTPUT_NAME, Page, PageContext, RESOLVED_MODULE_ID_VIRTUAL, VitePluginUniPages, babelGenerate, checkPagesJsonFileSync, debug, VitePluginUniPages as default, definePage, defineUniPages, execScript, extsToGlob, findImports, findMacro, getPageFiles, getRouteBlock, getRouteSfcBlock, invalidatePagesModule, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, resolveOptions, resolvePageDirs, sleep, tryPageMetaFromCustomBlock, tryPageMetaFromMacro, writeFileWithLock };
3213
3218
  export type { Condition, ConditionItem, ConfigSource, CustomBlock, DefinePage, EasyCom, GlobalStyle, MaybeCallable, MaybePromise, MaybePromiseCallable, Options, PageMetaDatum, PagePath, PagesConfig, ResolvedOptions, RouteBlockLang, SubPackage, SubPackages, SubPageMetaDatum, TabBar, TabBarIconFont, TabBarItem, TabBarMidButton, TheWindow, UniIdRouter, UserOptions, UserPageMeta, UserPagesConfig, UserTabBarItem, debugType };
package/dist/index.d.mts CHANGED
@@ -2964,6 +2964,7 @@ declare class PageContext {
2964
2964
  options: ResolvedOptions;
2965
2965
  logger?: Logger;
2966
2966
  withUniPlatform: boolean;
2967
+ private lastPagesJson;
2967
2968
  constructor(userOptions: UserOptions, viteRoot?: string);
2968
2969
  setLogger(logger: Logger): void;
2969
2970
  loadUserPagesConfig(): Promise<void>;
@@ -2994,6 +2995,8 @@ declare class PageContext {
2994
2995
  resolveRoutes(): string;
2995
2996
  resolveSubRoutes(): string;
2996
2997
  generateDeclaration(): Promise<void> | undefined;
2998
+ private writePagesJSONFile;
2999
+ private genratePagesJSON;
2997
3000
  private readInfoFromPagesJSON;
2998
3001
  private getIndent;
2999
3002
  private getNewline;
@@ -3034,6 +3037,7 @@ declare function execScript(options: {
3034
3037
  code: string;
3035
3038
  filename: string;
3036
3039
  }): Promise<any>;
3040
+ declare function sleep(ms: number): Promise<unknown>;
3037
3041
  declare const babelGenerate: typeof babelGenerator;
3038
3042
 
3039
3043
  interface CustomBlock {
@@ -3195,11 +3199,12 @@ declare function getRouteBlock(path: string, blockStr: SFCBlock | undefined, rou
3195
3199
  */
3196
3200
  declare function getPageFiles(path: string, options: ResolvedOptions): string[];
3197
3201
  /**
3198
- * 检查指定路径的pages.json文件,如果文件不存在或不是有效文件则创建一个空的pages.json文件
3202
+ * 检查指定路径的 pages.json 文件,如果文件不存在或不是有效文件则创建一个空的 pages.json 文件
3199
3203
  * @param path - 要检查的文件路径
3200
- * @returns Promise<void> - 无返回值的异步函数
3204
+ * @returns boolean - 返回操作是否成功
3201
3205
  */
3202
- declare function checkPagesJsonFile(path: fs.PathLike): Promise<boolean>;
3206
+ declare function checkPagesJsonFileSync(path: fs.PathLike): boolean;
3207
+ declare function writeFileWithLock(path: string, content: string, retry?: number): Promise<void>;
3203
3208
 
3204
3209
  declare function resolveOptions(userOptions: UserOptions, viteRoot?: string): ResolvedOptions;
3205
3210
  /**
@@ -3207,7 +3212,7 @@ declare function resolveOptions(userOptions: UserOptions, viteRoot?: string): Re
3207
3212
  */
3208
3213
  declare function resolvePageDirs(dir: string, root: string, exclude: string[]): string[];
3209
3214
 
3210
- declare function VitePluginUniPages(userOptions?: UserOptions): Promise<Plugin>;
3215
+ declare function VitePluginUniPages(userOptions?: UserOptions): Plugin;
3211
3216
 
3212
- export { FILE_EXTENSIONS, MODULE_ID_VIRTUAL, OUTPUT_NAME, Page, PageContext, RESOLVED_MODULE_ID_VIRTUAL, VitePluginUniPages, babelGenerate, checkPagesJsonFile, debug, VitePluginUniPages as default, definePage, defineUniPages, execScript, extsToGlob, findImports, findMacro, getPageFiles, getRouteBlock, getRouteSfcBlock, invalidatePagesModule, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, resolveOptions, resolvePageDirs, tryPageMetaFromCustomBlock, tryPageMetaFromMacro };
3217
+ export { FILE_EXTENSIONS, MODULE_ID_VIRTUAL, OUTPUT_NAME, Page, PageContext, RESOLVED_MODULE_ID_VIRTUAL, VitePluginUniPages, babelGenerate, checkPagesJsonFileSync, debug, VitePluginUniPages as default, definePage, defineUniPages, execScript, extsToGlob, findImports, findMacro, getPageFiles, getRouteBlock, getRouteSfcBlock, invalidatePagesModule, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, resolveOptions, resolvePageDirs, sleep, tryPageMetaFromCustomBlock, tryPageMetaFromMacro, writeFileWithLock };
3213
3218
  export type { Condition, ConditionItem, ConfigSource, CustomBlock, DefinePage, EasyCom, GlobalStyle, MaybeCallable, MaybePromise, MaybePromiseCallable, Options, PageMetaDatum, PagePath, PagesConfig, ResolvedOptions, RouteBlockLang, SubPackage, SubPackages, SubPageMetaDatum, TabBar, TabBarIconFont, TabBarItem, TabBarMidButton, TheWindow, UniIdRouter, UserOptions, UserPageMeta, UserPagesConfig, UserTabBarItem, debugType };
package/dist/index.d.ts CHANGED
@@ -2964,6 +2964,7 @@ declare class PageContext {
2964
2964
  options: ResolvedOptions;
2965
2965
  logger?: Logger;
2966
2966
  withUniPlatform: boolean;
2967
+ private lastPagesJson;
2967
2968
  constructor(userOptions: UserOptions, viteRoot?: string);
2968
2969
  setLogger(logger: Logger): void;
2969
2970
  loadUserPagesConfig(): Promise<void>;
@@ -2994,6 +2995,8 @@ declare class PageContext {
2994
2995
  resolveRoutes(): string;
2995
2996
  resolveSubRoutes(): string;
2996
2997
  generateDeclaration(): Promise<void> | undefined;
2998
+ private writePagesJSONFile;
2999
+ private genratePagesJSON;
2997
3000
  private readInfoFromPagesJSON;
2998
3001
  private getIndent;
2999
3002
  private getNewline;
@@ -3034,6 +3037,7 @@ declare function execScript(options: {
3034
3037
  code: string;
3035
3038
  filename: string;
3036
3039
  }): Promise<any>;
3040
+ declare function sleep(ms: number): Promise<unknown>;
3037
3041
  declare const babelGenerate: typeof babelGenerator;
3038
3042
 
3039
3043
  interface CustomBlock {
@@ -3195,11 +3199,12 @@ declare function getRouteBlock(path: string, blockStr: SFCBlock | undefined, rou
3195
3199
  */
3196
3200
  declare function getPageFiles(path: string, options: ResolvedOptions): string[];
3197
3201
  /**
3198
- * 检查指定路径的pages.json文件,如果文件不存在或不是有效文件则创建一个空的pages.json文件
3202
+ * 检查指定路径的 pages.json 文件,如果文件不存在或不是有效文件则创建一个空的 pages.json 文件
3199
3203
  * @param path - 要检查的文件路径
3200
- * @returns Promise<void> - 无返回值的异步函数
3204
+ * @returns boolean - 返回操作是否成功
3201
3205
  */
3202
- declare function checkPagesJsonFile(path: fs.PathLike): Promise<boolean>;
3206
+ declare function checkPagesJsonFileSync(path: fs.PathLike): boolean;
3207
+ declare function writeFileWithLock(path: string, content: string, retry?: number): Promise<void>;
3203
3208
 
3204
3209
  declare function resolveOptions(userOptions: UserOptions, viteRoot?: string): ResolvedOptions;
3205
3210
  /**
@@ -3207,7 +3212,7 @@ declare function resolveOptions(userOptions: UserOptions, viteRoot?: string): Re
3207
3212
  */
3208
3213
  declare function resolvePageDirs(dir: string, root: string, exclude: string[]): string[];
3209
3214
 
3210
- declare function VitePluginUniPages(userOptions?: UserOptions): Promise<Plugin>;
3215
+ declare function VitePluginUniPages(userOptions?: UserOptions): Plugin;
3211
3216
 
3212
- export { FILE_EXTENSIONS, MODULE_ID_VIRTUAL, OUTPUT_NAME, Page, PageContext, RESOLVED_MODULE_ID_VIRTUAL, VitePluginUniPages, babelGenerate, checkPagesJsonFile, debug, VitePluginUniPages as default, definePage, defineUniPages, execScript, extsToGlob, findImports, findMacro, getPageFiles, getRouteBlock, getRouteSfcBlock, invalidatePagesModule, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, resolveOptions, resolvePageDirs, tryPageMetaFromCustomBlock, tryPageMetaFromMacro };
3217
+ export { FILE_EXTENSIONS, MODULE_ID_VIRTUAL, OUTPUT_NAME, Page, PageContext, RESOLVED_MODULE_ID_VIRTUAL, VitePluginUniPages, babelGenerate, checkPagesJsonFileSync, debug, VitePluginUniPages as default, definePage, defineUniPages, execScript, extsToGlob, findImports, findMacro, getPageFiles, getRouteBlock, getRouteSfcBlock, invalidatePagesModule, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, resolveOptions, resolvePageDirs, sleep, tryPageMetaFromCustomBlock, tryPageMetaFromMacro, writeFileWithLock };
3213
3218
  export type { Condition, ConditionItem, ConfigSource, CustomBlock, DefinePage, EasyCom, GlobalStyle, MaybeCallable, MaybePromise, MaybePromiseCallable, Options, PageMetaDatum, PagePath, PagesConfig, ResolvedOptions, RouteBlockLang, SubPackage, SubPackages, SubPageMetaDatum, TabBar, TabBarIconFont, TabBarItem, TabBarMidButton, TheWindow, UniIdRouter, UserOptions, UserPageMeta, UserPagesConfig, UserTabBarItem, debugType };
package/dist/index.mjs CHANGED
@@ -7,7 +7,7 @@ import MagicString from 'magic-string';
7
7
  import { normalizePath, createLogger } from 'vite';
8
8
  import fs, { existsSync } from 'node:fs';
9
9
  import { platform } from '@uni-helper/uni-env';
10
- import { parse, assign, stringify } from 'comment-json';
10
+ import { parse, assign, stringify, CommentArray } from 'comment-json';
11
11
  import Debug from 'debug';
12
12
  import detectIndent from 'detect-indent';
13
13
  import detectNewline from 'detect-newline';
@@ -200,6 +200,9 @@ ${jsCode}
200
200
  `);
201
201
  }
202
202
  }
203
+ function sleep(ms) {
204
+ return new Promise((resolve) => setTimeout(resolve, ms));
205
+ }
203
206
  function getDefaultExport(expr) {
204
207
  return expr.default === void 0 ? expr : expr.default;
205
208
  }
@@ -215,33 +218,73 @@ function getPageFiles(path, options) {
215
218
  });
216
219
  return files;
217
220
  }
218
- async function checkPagesJsonFile(path) {
221
+ function checkPagesJsonFileSync(path) {
219
222
  const createEmptyFile = (path2) => {
220
- return fs.promises.writeFile(path2, JSON.stringify({ pages: [{ path: "" }] }, null, 2), { encoding: "utf-8" }).then(() => true).catch(() => false);
223
+ try {
224
+ fs.writeFileSync(
225
+ path2,
226
+ JSON.stringify({ pages: [{ path: "" }] }, null, 2),
227
+ { encoding: "utf-8" }
228
+ );
229
+ return true;
230
+ } catch {
231
+ return false;
232
+ }
221
233
  };
222
- const unlink = (path2) => {
223
- return fs.promises.unlink(path2).then(() => true).catch(() => false);
234
+ const unlinkFile = (path2) => {
235
+ try {
236
+ fs.unlinkSync(path2);
237
+ return true;
238
+ } catch {
239
+ return false;
240
+ }
224
241
  };
225
242
  try {
226
- const stat = await fs.promises.stat(path);
243
+ try {
244
+ fs.accessSync(path, fs.constants.F_OK);
245
+ } catch {
246
+ return createEmptyFile(path);
247
+ }
248
+ const stat = fs.statSync(path);
227
249
  if (!stat.isFile()) {
228
- if (!await unlink(path)) {
250
+ if (!unlinkFile(path)) {
229
251
  return false;
230
252
  }
231
253
  return createEmptyFile(path);
232
254
  }
233
- const access = await fs.promises.access(path, fs.constants.W_OK | fs.constants.R_OK).then(() => true).catch(() => false);
234
- if (!access) {
235
- if (!await unlink(path)) {
255
+ try {
256
+ fs.accessSync(path, fs.constants.R_OK | fs.constants.W_OK);
257
+ return true;
258
+ } catch {
259
+ if (!unlinkFile(path)) {
236
260
  return false;
237
261
  }
238
262
  return createEmptyFile(path);
239
263
  }
240
- return true;
241
264
  } catch {
242
265
  return createEmptyFile(path);
243
266
  }
244
267
  }
268
+ async function writeFileWithLock(path, content, retry = 3) {
269
+ if (retry <= 0) {
270
+ debug.error(`${path} \u83B7\u53D6\u6587\u4EF6\u9501\u5931\u8D25\uFF0C\u5199\u5165\u5931\u8D25`);
271
+ return;
272
+ }
273
+ let relase;
274
+ try {
275
+ try {
276
+ relase = await lockfile.lock(path, { realpath: false });
277
+ } catch {
278
+ await sleep(500);
279
+ return writeFileWithLock(path, content, retry - 1);
280
+ }
281
+ await fs.promises.writeFile(path, content, { encoding: "utf-8" });
282
+ } finally {
283
+ if (relase) {
284
+ await relase();
285
+ }
286
+ }
287
+ }
245
288
 
246
289
  function resolveOptions(userOptions, viteRoot = process.cwd()) {
247
290
  const {
@@ -534,7 +577,6 @@ var __publicField = (obj, key, value) => {
534
577
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
535
578
  return value;
536
579
  };
537
- let lsatPagesJson = "";
538
580
  class PageContext {
539
581
  constructor(userOptions, viteRoot = process.cwd()) {
540
582
  __publicField(this, "_server");
@@ -558,6 +600,7 @@ class PageContext {
558
600
  __publicField(this, "options");
559
601
  __publicField(this, "logger");
560
602
  __publicField(this, "withUniPlatform", false);
603
+ __publicField(this, "lastPagesJson", "");
561
604
  this.rawOptions = userOptions;
562
605
  this.root = slash(viteRoot);
563
606
  debug.options("root", this.root);
@@ -784,7 +827,7 @@ class PageContext {
784
827
  }
785
828
  }
786
829
  }
787
- await checkPagesJsonFile(this.resolvedPagesJSONPath);
830
+ checkPagesJsonFileSync(this.resolvedPagesJSONPath);
788
831
  this.options.onBeforeLoadUserConfig(this);
789
832
  await this.loadUserPagesConfig();
790
833
  this.options.onAfterLoadUserConfig(this);
@@ -806,29 +849,19 @@ class PageContext {
806
849
  pages.forEach((v) => pagesMap.set(v.path, v));
807
850
  this.pageMetaData = [...pagesMap.values()];
808
851
  this.options.onBeforeWriteFile(this);
809
- const data = {
810
- ...this.pagesGlobConfig,
811
- pages: this.pageMetaData,
812
- subPackages: this.subPageMetaData,
813
- tabBar: await this.getTabBarMerged()
814
- };
852
+ const data = await this.genratePagesJSON();
815
853
  const pagesJson = stringify(
816
854
  data,
817
855
  null,
818
856
  this.options.minify ? void 0 : await this.getIndent()
819
857
  ) + (await this.getEndOfLine() ? await this.getNewline() : "");
820
858
  this.generateDeclaration();
821
- if (lsatPagesJson === pagesJson) {
859
+ if (this.lastPagesJson === pagesJson) {
822
860
  debug.pages("PagesJson Not have change");
823
861
  return false;
824
862
  }
825
- const relase = await lockfile.lock(this.resolvedPagesJSONPath, { realpath: false });
826
- try {
827
- await fs.promises.writeFile(this.resolvedPagesJSONPath, pagesJson, { encoding: "utf-8" });
828
- } finally {
829
- await relase();
830
- }
831
- lsatPagesJson = pagesJson;
863
+ await writeFileWithLock(this.resolvedPagesJSONPath, pagesJson);
864
+ this.lastPagesJson = pagesJson;
832
865
  this.options.onAfterWriteFile(this);
833
866
  return true;
834
867
  }
@@ -849,6 +882,64 @@ class PageContext {
849
882
  debug.declaration("generating");
850
883
  return writeDeclaration(this, this.options.dts);
851
884
  }
885
+ async writePagesJSONFile(pagesJson, retry = 3) {
886
+ if (retry <= 0) {
887
+ debug.error(`${this.resolvedPagesJSONPath} \u83B7\u53D6\u6587\u4EF6\u9501\u5931\u8D25\uFF0C\u5199\u5165\u5931\u8D25`);
888
+ return;
889
+ }
890
+ let relase;
891
+ try {
892
+ try {
893
+ relase = await lockfile.lock(this.resolvedPagesJSONPath, { realpath: false });
894
+ } catch {
895
+ return this.writePagesJSONFile(pagesJson, retry - 1);
896
+ }
897
+ await fs.promises.writeFile(this.resolvedPagesJSONPath, pagesJson, { encoding: "utf-8" });
898
+ } finally {
899
+ if (relase) {
900
+ await relase();
901
+ }
902
+ }
903
+ }
904
+ async genratePagesJSON() {
905
+ const content = await fs.promises.readFile(this.resolvedPagesJSONPath, { encoding: "utf-8" }).catch(() => "");
906
+ let pageJson = parse(content || "{}");
907
+ const { pages: _, subPackages: __, tabBar: ___, ...others } = this.pagesGlobConfig || {};
908
+ pageJson = Object.assign(pageJson, {
909
+ ...others
910
+ });
911
+ const currentPlatform = platform.toUpperCase();
912
+ pageJson.pages = mergePlatformItems(pageJson?.pages, currentPlatform, this.pageMetaData, "path");
913
+ pageJson.subPackages = pageJson?.subPackages || new CommentArray();
914
+ const newSubPackages = /* @__PURE__ */ new Map();
915
+ for (const item of this.subPageMetaData) {
916
+ newSubPackages.set(item.root, item);
917
+ }
918
+ for (const existing of pageJson.subPackages) {
919
+ const sub = newSubPackages.get(existing.root);
920
+ if (sub) {
921
+ existing.pages = mergePlatformItems(existing.pages, currentPlatform, sub.pages, "path");
922
+ newSubPackages.delete(existing.root);
923
+ }
924
+ }
925
+ for (const [_2, newSub] of newSubPackages) {
926
+ pageJson.subPackages.push({
927
+ root: newSub.root,
928
+ pages: mergePlatformItems(void 0, currentPlatform, newSub.pages, "path")
929
+ });
930
+ }
931
+ const tabBar = await this.getTabBarMerged();
932
+ if (tabBar) {
933
+ const list = mergePlatformItems(pageJson?.tabBar?.list, currentPlatform, tabBar.list, "pagePath");
934
+ if (pageJson?.tabBar?.list) {
935
+ pageJson.tabBar.list = list;
936
+ } else {
937
+ pageJson.tabBar = pageJson.tabBar || {};
938
+ pageJson.tabBar.list = list;
939
+ }
940
+ }
941
+ return pageJson;
942
+ }
852
943
  async readInfoFromPagesJSON() {
853
944
  const resolvedPagesJSONContent = await fs.promises.readFile(this.resolvedPagesJSONPath, { encoding: "utf-8" }).catch(() => "");
854
945
  this.resolvedPagesJSONIndent = detectIndent(resolvedPagesJSONContent).indent || " ";
@@ -885,19 +976,125 @@ function getPagePaths(dir, options) {
885
976
  }));
886
977
  return pagePaths;
887
978
  }
979
+ function mergePlatformItems(source, currentPlatform, items, uniqueKeyName) {
980
+ const src = source || new CommentArray();
981
+ currentPlatform = currentPlatform.toUpperCase();
982
+ let lastPlatforms = [];
983
+ for (const comment of src[Symbol.for("before:0")] || []) {
984
+ const trimed = comment.value.trim();
985
+ if (trimed.startsWith("GENERATED BY UNI-PAGES, PLATFORM:")) {
986
+ lastPlatforms = trimed.split(":")[1].split("||").map((s) => s.trim()).filter((s) => s !== currentPlatform).sort();
987
+ }
988
+ }
989
+ const tmpMap = /* @__PURE__ */ new Map();
990
+ for (let i = 0; i < src.length; i++) {
991
+ const item = src[i];
992
+ const uniqueKey = item[uniqueKeyName];
993
+ if (!uniqueKey) {
994
+ continue;
995
+ }
996
+ const beforeComments = src[Symbol.for(`before:${i}`)];
997
+ const ifdefComment = beforeComments?.find((c) => c.value.trim().startsWith("#ifdef"));
998
+ let platforms = [...lastPlatforms];
999
+ if (ifdefComment) {
1000
+ const match = ifdefComment.value.match(/#ifdef\s+(.+)/);
1001
+ if (match) {
1002
+ platforms = match[1].split("||").map((p) => p.trim()).filter((s) => s !== currentPlatform).sort();
1003
+ }
1004
+ }
1005
+ if (platforms.length === 0) {
1006
+ continue;
1007
+ }
1008
+ const existing = tmpMap.get(uniqueKey) || [];
1009
+ existing.push({ item, platforms, platformStr: platforms.join(" || ") });
1010
+ tmpMap.set(uniqueKey, existing);
1011
+ }
1012
+ for (const item of items) {
1013
+ const newItem = item;
1014
+ const uniqueKey = item[uniqueKeyName];
1015
+ if (!uniqueKey) {
1016
+ continue;
1017
+ }
1018
+ if (!tmpMap.has(uniqueKey)) {
1019
+ tmpMap.set(uniqueKey, [{
1020
+ item: newItem,
1021
+ platforms: [currentPlatform],
1022
+ platformStr: currentPlatform
1023
+ }]);
1024
+ continue;
1025
+ }
1026
+ const existing = tmpMap.get(uniqueKey);
1027
+ const newItemStr = JSON.stringify(newItem);
1028
+ const equalObj = existing.find((val) => JSON.stringify(val.item) === newItemStr);
1029
+ if (equalObj) {
1030
+ equalObj.platforms.push(currentPlatform);
1031
+ equalObj.platformStr = equalObj.platforms.join(" || ");
1032
+ } else {
1033
+ existing.push({
1034
+ item: newItem,
1035
+ platforms: [currentPlatform],
1036
+ platformStr: currentPlatform
1037
+ });
1038
+ }
1039
+ }
1040
+ const result = new CommentArray();
1041
+ const platformUsage = {};
1042
+ tmpMap.forEach((val) => {
1043
+ Object.values(val).forEach((v) => {
1044
+ platformUsage[v.platformStr] = (platformUsage[v.platformStr] || 0) + 1;
1045
+ });
1046
+ });
1047
+ const usageKeys = Object.keys(platformUsage);
1048
+ const defaultPlatformStr = usageKeys.length ? usageKeys.reduce((a, b) => platformUsage[a] > platformUsage[b] ? a : b) : currentPlatform;
1049
+ result[Symbol.for("before:0")] = [{
1050
+ type: "LineComment",
1051
+ value: ` GENERATED BY UNI-PAGES, PLATFORM: ${defaultPlatformStr}`,
1052
+ inline: false,
1053
+ loc: {
1054
+ start: { line: 0, column: 0 },
1055
+ end: { line: 0, column: 0 }
1056
+ }
1057
+ }];
1058
+ for (const [_, list] of tmpMap) {
1059
+ for (const { item, platformStr } of list) {
1060
+ result.push(item);
1061
+ if (platformStr !== defaultPlatformStr) {
1062
+ result[Symbol.for(`before:${result.length - 1}`)] = [{
1063
+ type: "LineComment",
1064
+ value: ` #ifdef ${platformStr}`,
1065
+ inline: false,
1066
+ loc: {
1067
+ start: { line: 0, column: 0 },
1068
+ end: { line: 0, column: 0 }
1069
+ }
1070
+ }];
1071
+ result[Symbol.for(`after:${result.length - 1}`)] = [{
1072
+ type: "LineComment",
1073
+ value: " #endif",
1074
+ inline: false,
1075
+ loc: {
1076
+ start: { line: 0, column: 0 },
1077
+ end: { line: 0, column: 0 }
1078
+ }
1079
+ }];
1080
+ }
1081
+ }
1082
+ }
1083
+ return result;
1084
+ }
888
1085
 
889
1086
  function defineUniPages(config) {
890
1087
  return config;
891
1088
  }
892
1089
 
893
- async function VitePluginUniPages(userOptions = {}) {
1090
+ function VitePluginUniPages(userOptions = {}) {
894
1091
  let ctx;
895
1092
  const resolvedPagesJSONPath = path.join(
896
1093
  process.env.VITE_ROOT_DIR || process.cwd(),
897
1094
  userOptions.outDir ?? "src",
898
1095
  OUTPUT_NAME
899
1096
  );
900
- await checkPagesJsonFile(resolvedPagesJSONPath);
1097
+ checkPagesJsonFileSync(resolvedPagesJSONPath);
901
1098
  return {
902
1099
  name: "vite-plugin-uni-pages",
903
1100
  enforce: "pre",
@@ -976,4 +1173,4 @@ async function VitePluginUniPages(userOptions = {}) {
976
1173
  };
977
1174
  }
978
1175
 
979
- 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, resolveOptions, resolvePageDirs, tryPageMetaFromCustomBlock, tryPageMetaFromMacro };
1176
+ export { FILE_EXTENSIONS, MODULE_ID_VIRTUAL, OUTPUT_NAME, Page, PageContext, RESOLVED_MODULE_ID_VIRTUAL, VitePluginUniPages, babelGenerate, checkPagesJsonFileSync, debug, VitePluginUniPages as default, defineUniPages, execScript, extsToGlob, findImports, findMacro, getPageFiles, getRouteBlock, getRouteSfcBlock, invalidatePagesModule, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, resolveOptions, resolvePageDirs, sleep, tryPageMetaFromCustomBlock, tryPageMetaFromMacro, writeFileWithLock };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@uni-helper/vite-plugin-uni-pages",
3
3
  "type": "module",
4
- "version": "0.3.16",
4
+ "version": "0.3.17",
5
5
  "description": "File system based routing for uni-app applications using Vite",
6
6
  "author": "KeJun",
7
7
  "maintainers": [