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

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
@@ -2,7 +2,6 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const node_child_process = require('node:child_process');
6
5
  const path = require('node:path');
7
6
  const process = require('node:process');
8
7
  const astKit = require('ast-kit');
@@ -10,13 +9,14 @@ const chokidar = require('chokidar');
10
9
  const kolorist = require('kolorist');
11
10
  const MagicString = require('magic-string');
12
11
  const vite = require('vite');
12
+ const fs = require('node:fs');
13
13
  const uniEnv = require('@uni-helper/uni-env');
14
14
  const commentJson = require('comment-json');
15
15
  const Debug = require('debug');
16
16
  const detectIndent = require('detect-indent');
17
17
  const detectNewline = require('detect-newline');
18
+ const lockfile = require('proper-lockfile');
18
19
  const unconfig = require('unconfig');
19
- const fs = require('node:fs');
20
20
  const promises = require('node:fs/promises');
21
21
  const fg = require('fast-glob');
22
22
  const node_module = require('node:module');
@@ -47,10 +47,11 @@ const path__default = /*#__PURE__*/_interopDefaultCompat(path);
47
47
  const process__default = /*#__PURE__*/_interopDefaultCompat(process);
48
48
  const chokidar__default = /*#__PURE__*/_interopDefaultCompat(chokidar);
49
49
  const MagicString__default = /*#__PURE__*/_interopDefaultCompat(MagicString);
50
+ const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
50
51
  const Debug__default = /*#__PURE__*/_interopDefaultCompat(Debug);
51
52
  const detectIndent__default = /*#__PURE__*/_interopDefaultCompat(detectIndent);
52
53
  const detectNewline__default = /*#__PURE__*/_interopDefaultCompat(detectNewline);
53
- const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
54
+ const lockfile__default = /*#__PURE__*/_interopDefaultCompat(lockfile);
54
55
  const fg__default = /*#__PURE__*/_interopDefaultCompat(fg);
55
56
  const vm__default = /*#__PURE__*/_interopDefaultCompat(vm);
56
57
  const babelGenerator__default = /*#__PURE__*/_interopDefaultCompat(babelGenerator);
@@ -249,23 +250,33 @@ function getPageFiles(path, options) {
249
250
  });
250
251
  return files;
251
252
  }
252
- function checkPagesJsonFile(path) {
253
- if (!fs__default.existsSync(path)) {
254
- writeFileSync(path, commentJson.stringify({ pages: [{ path: "" }] }, null, 2));
255
- return false;
256
- }
257
- return true;
258
- }
259
- function readFileSync(path) {
253
+ async function checkPagesJsonFile(path) {
254
+ const createEmptyFile = (path2) => {
255
+ return fs__default.promises.writeFile(path2, JSON.stringify({ pages: [{ path: "" }] }, null, 2), { encoding: "utf-8" }).then(() => true).catch(() => false);
256
+ };
257
+ const unlink = (path2) => {
258
+ return fs__default.promises.unlink(path2).then(() => true).catch(() => false);
259
+ };
260
260
  try {
261
- return fs__default.readFileSync(path, { encoding: "utf-8" });
261
+ const stat = await fs__default.promises.stat(path);
262
+ if (!stat.isFile()) {
263
+ if (!await unlink(path)) {
264
+ return false;
265
+ }
266
+ return createEmptyFile(path);
267
+ }
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)) {
271
+ return false;
272
+ }
273
+ return createEmptyFile(path);
274
+ }
275
+ return true;
262
276
  } catch {
263
- return "";
277
+ return createEmptyFile(path);
264
278
  }
265
279
  }
266
- function writeFileSync(path, content) {
267
- fs__default.writeFileSync(path, content, { encoding: "utf-8" });
268
- }
269
280
 
270
281
  function resolveOptions(userOptions, viteRoot = process__default.cwd()) {
271
282
  const {
@@ -461,7 +472,7 @@ class Page {
461
472
  }
462
473
  async readPageMetaFromFile() {
463
474
  try {
464
- const content = fs.readFileSync(this.path.absolutePath, "utf-8");
475
+ const content = await fs__default.promises.readFile(this.path.absolutePath, { encoding: "utf-8" });
465
476
  const sfc = parseSFC(content, { filename: this.path.absolutePath });
466
477
  const meta = await tryPageMetaFromMacro(sfc);
467
478
  if (meta) {
@@ -571,9 +582,12 @@ class PageContext {
571
582
  __publicField(this, "pageMetaData", []);
572
583
  __publicField(this, "subPageMetaData", []);
573
584
  __publicField(this, "resolvedPagesJSONPath", "");
574
- __publicField(this, "resolvedPagesJSONIndent", " ");
575
- __publicField(this, "resolvedPagesJSONNewline", "\n");
576
- __publicField(this, "resolvedPagesJSONEofNewline", true);
585
+ __publicField(this, "resolvedPagesJSONIndent");
586
+ // ' '
587
+ __publicField(this, "resolvedPagesJSONNewline");
588
+ // '\n'
589
+ __publicField(this, "resolvedPagesJSONEofNewline");
590
+ // true
577
591
  __publicField(this, "rawOptions");
578
592
  __publicField(this, "root");
579
593
  __publicField(this, "options");
@@ -590,10 +604,6 @@ class PageContext {
590
604
  Debug__default.enable(`${prefix}${suffix}`);
591
605
  }
592
606
  this.resolvedPagesJSONPath = path__default.join(this.root, this.options.outDir, OUTPUT_NAME);
593
- const resolvedPagesJSONContent = readFileSync(this.resolvedPagesJSONPath);
594
- this.resolvedPagesJSONIndent = detectIndent__default(resolvedPagesJSONContent).indent || " ";
595
- this.resolvedPagesJSONNewline = detectNewline__default(resolvedPagesJSONContent) || "\n";
596
- this.resolvedPagesJSONEofNewline = (resolvedPagesJSONContent.at(-1) ?? "\n") === this.resolvedPagesJSONNewline;
597
607
  debug.options(this.options);
598
608
  }
599
609
  setLogger(logger) {
@@ -761,6 +771,16 @@ class PageContext {
761
771
  debug.subPages(this.subPageMetaData);
762
772
  }
763
773
  async getTabBarMerged() {
774
+ const tabBarItems = [];
775
+ for (const [_, page] of this.pages) {
776
+ const tabbar = await page.getTabBar();
777
+ if (tabbar) {
778
+ tabBarItems.push(tabbar);
779
+ }
780
+ }
781
+ if (tabBarItems.length === 0) {
782
+ return this.pagesGlobConfig?.tabBar;
783
+ }
764
784
  const tabBar = {
765
785
  ...this.pagesGlobConfig?.tabBar,
766
786
  list: this.pagesGlobConfig?.tabBar?.list || []
@@ -769,13 +789,6 @@ class PageContext {
769
789
  for (const item of tabBar.list) {
770
790
  pagePaths.set(item.pagePath, true);
771
791
  }
772
- const tabBarItems = [];
773
- for (const [_, page] of this.pages) {
774
- const tabbar = await page.getTabBar();
775
- if (tabbar) {
776
- tabBarItems.push(tabbar);
777
- }
778
- }
779
792
  tabBarItems.sort((a, b) => a.index - b.index);
780
793
  for (const item of tabBarItems) {
781
794
  if (!pagePaths.has(item.pagePath)) {
@@ -806,7 +819,7 @@ class PageContext {
806
819
  }
807
820
  }
808
821
  }
809
- checkPagesJsonFile(this.resolvedPagesJSONPath);
822
+ await checkPagesJsonFile(this.resolvedPagesJSONPath);
810
823
  this.options.onBeforeLoadUserConfig(this);
811
824
  await this.loadUserPagesConfig();
812
825
  this.options.onAfterLoadUserConfig(this);
@@ -837,14 +850,19 @@ class PageContext {
837
850
  const pagesJson = commentJson.stringify(
838
851
  data,
839
852
  null,
840
- this.options.minify ? void 0 : this.resolvedPagesJSONIndent
841
- ) + (this.resolvedPagesJSONEofNewline ? this.resolvedPagesJSONNewline : "");
853
+ this.options.minify ? void 0 : await this.getIndent()
854
+ ) + (await this.getEndOfLine() ? await this.getNewline() : "");
842
855
  this.generateDeclaration();
843
856
  if (lsatPagesJson === pagesJson) {
844
857
  debug.pages("PagesJson Not have change");
845
858
  return false;
846
859
  }
847
- writeFileSync(this.resolvedPagesJSONPath, pagesJson);
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
+ }
848
866
  lsatPagesJson = pagesJson;
849
867
  this.options.onAfterWriteFile(this);
850
868
  return true;
@@ -866,6 +884,30 @@ class PageContext {
866
884
  debug.declaration("generating");
867
885
  return writeDeclaration(this, this.options.dts);
868
886
  }
887
+ async readInfoFromPagesJSON() {
888
+ const resolvedPagesJSONContent = await fs__default.promises.readFile(this.resolvedPagesJSONPath, { encoding: "utf-8" }).catch(() => "");
889
+ this.resolvedPagesJSONIndent = detectIndent__default(resolvedPagesJSONContent).indent || " ";
890
+ this.resolvedPagesJSONNewline = detectNewline__default(resolvedPagesJSONContent) || "\n";
891
+ this.resolvedPagesJSONEofNewline = (resolvedPagesJSONContent.at(-1) ?? "\n") === this.resolvedPagesJSONNewline;
892
+ }
893
+ async getIndent() {
894
+ if (!this.resolvedPagesJSONIndent) {
895
+ await this.readInfoFromPagesJSON();
896
+ }
897
+ return this.resolvedPagesJSONIndent;
898
+ }
899
+ async getNewline() {
900
+ if (!this.resolvedPagesJSONNewline) {
901
+ await this.readInfoFromPagesJSON();
902
+ }
903
+ return this.resolvedPagesJSONNewline;
904
+ }
905
+ async getEndOfLine() {
906
+ if (!this.resolvedPagesJSONEofNewline) {
907
+ await this.readInfoFromPagesJSON();
908
+ }
909
+ return this.resolvedPagesJSONEofNewline;
910
+ }
869
911
  }
870
912
  function getPagePaths(dir, options) {
871
913
  const pagesDirPath = slash(path__default.resolve(options.root, dir));
@@ -883,28 +925,14 @@ function defineUniPages(config) {
883
925
  return config;
884
926
  }
885
927
 
886
- async function restart() {
887
- return new Promise((resolve) => {
888
- const build = node_child_process.spawn(process__default.argv.shift(), process__default.argv, {
889
- cwd: process__default.env.VITE_ROOT_DIR || process__default.cwd(),
890
- detached: true,
891
- env: process__default.env
892
- });
893
- build.stdout?.pipe(process__default.stdout);
894
- build.stderr?.pipe(process__default.stderr);
895
- build.on("close", (code) => {
896
- resolve(process__default.exit(code));
897
- });
898
- });
899
- }
900
- function VitePluginUniPages(userOptions = {}) {
928
+ async function VitePluginUniPages(userOptions = {}) {
901
929
  let ctx;
902
930
  const resolvedPagesJSONPath = path__default.join(
903
931
  process__default.env.VITE_ROOT_DIR || process__default.cwd(),
904
932
  userOptions.outDir ?? "src",
905
933
  OUTPUT_NAME
906
934
  );
907
- const isValidated = checkPagesJsonFile(resolvedPagesJSONPath);
935
+ await checkPagesJsonFile(resolvedPagesJSONPath);
908
936
  return {
909
937
  name: "vite-plugin-uni-pages",
910
938
  enforce: "pre",
@@ -918,12 +946,6 @@ function VitePluginUniPages(userOptions = {}) {
918
946
  ctx.setLogger(logger);
919
947
  await ctx.updatePagesJSON();
920
948
  if (config.command === "build") {
921
- if (!isValidated) {
922
- ctx.logger?.warn("In build mode, if `pages.json` does not exist, the plugin cannot create the complete `pages.json` before the uni-app, so it restarts the build.", {
923
- timestamp: true
924
- });
925
- await restart();
926
- }
927
949
  if (config.build.watch)
928
950
  ctx.setupWatcher(chokidar__default.watch([...ctx.options.dirs, ...ctx.options.subPackages]));
929
951
  }
@@ -1013,9 +1035,7 @@ exports.isTargetFile = isTargetFile;
1013
1035
  exports.mergePageMetaDataArray = mergePageMetaDataArray;
1014
1036
  exports.parseCustomBlock = parseCustomBlock;
1015
1037
  exports.parseSFC = parseSFC;
1016
- exports.readFileSync = readFileSync;
1017
1038
  exports.resolveOptions = resolveOptions;
1018
1039
  exports.resolvePageDirs = resolvePageDirs;
1019
1040
  exports.tryPageMetaFromCustomBlock = tryPageMetaFromCustomBlock;
1020
1041
  exports.tryPageMetaFromMacro = tryPageMetaFromMacro;
1021
- exports.writeFileSync = writeFileSync;
package/dist/index.d.cts CHANGED
@@ -6,6 +6,7 @@ import { SFCParseOptions, SFCDescriptor, SFCBlock } from '@vue/compiler-sfc';
6
6
  import * as t from '@babel/types';
7
7
  import babelGenerator from '@babel/generator';
8
8
  import Debug from 'debug';
9
+ import fs from 'node:fs';
9
10
 
10
11
  interface ConditionItem {
11
12
  /**
@@ -2955,9 +2956,9 @@ declare class PageContext {
2955
2956
  pageMetaData: PageMetaDatum[];
2956
2957
  subPageMetaData: SubPageMetaDatum[];
2957
2958
  resolvedPagesJSONPath: string;
2958
- resolvedPagesJSONIndent: string;
2959
- resolvedPagesJSONNewline: string;
2960
- resolvedPagesJSONEofNewline: boolean;
2959
+ private resolvedPagesJSONIndent?;
2960
+ private resolvedPagesJSONNewline?;
2961
+ private resolvedPagesJSONEofNewline?;
2961
2962
  rawOptions: UserOptions;
2962
2963
  root: string;
2963
2964
  options: ResolvedOptions;
@@ -2993,6 +2994,10 @@ declare class PageContext {
2993
2994
  resolveRoutes(): string;
2994
2995
  resolveSubRoutes(): string;
2995
2996
  generateDeclaration(): Promise<void> | undefined;
2997
+ private readInfoFromPagesJSON;
2998
+ private getIndent;
2999
+ private getNewline;
3000
+ private getEndOfLine;
2996
3001
  }
2997
3002
 
2998
3003
  declare function invalidatePagesModule(server: ViteDevServer): void;
@@ -3189,9 +3194,12 @@ declare function getRouteBlock(path: string, blockStr: SFCBlock | undefined, rou
3189
3194
  * Resolves the files that are valid pages for the given context.
3190
3195
  */
3191
3196
  declare function getPageFiles(path: string, options: ResolvedOptions): string[];
3192
- declare function checkPagesJsonFile(path: string): boolean;
3193
- declare function readFileSync(path: string): string;
3194
- declare function writeFileSync(path: string, content: string): void;
3197
+ /**
3198
+ * 检查指定路径的pages.json文件,如果文件不存在或不是有效文件则创建一个空的pages.json文件
3199
+ * @param path - 要检查的文件路径
3200
+ * @returns Promise<void> - 无返回值的异步函数
3201
+ */
3202
+ declare function checkPagesJsonFile(path: fs.PathLike): Promise<boolean>;
3195
3203
 
3196
3204
  declare function resolveOptions(userOptions: UserOptions, viteRoot?: string): ResolvedOptions;
3197
3205
  /**
@@ -3199,7 +3207,7 @@ declare function resolveOptions(userOptions: UserOptions, viteRoot?: string): Re
3199
3207
  */
3200
3208
  declare function resolvePageDirs(dir: string, root: string, exclude: string[]): string[];
3201
3209
 
3202
- declare function VitePluginUniPages(userOptions?: UserOptions): Plugin;
3210
+ declare function VitePluginUniPages(userOptions?: UserOptions): Promise<Plugin>;
3203
3211
 
3204
- 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, readFileSync, resolveOptions, resolvePageDirs, tryPageMetaFromCustomBlock, tryPageMetaFromMacro, writeFileSync };
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 };
3205
3213
  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
@@ -6,6 +6,7 @@ import { SFCParseOptions, SFCDescriptor, SFCBlock } from '@vue/compiler-sfc';
6
6
  import * as t from '@babel/types';
7
7
  import babelGenerator from '@babel/generator';
8
8
  import Debug from 'debug';
9
+ import fs from 'node:fs';
9
10
 
10
11
  interface ConditionItem {
11
12
  /**
@@ -2955,9 +2956,9 @@ declare class PageContext {
2955
2956
  pageMetaData: PageMetaDatum[];
2956
2957
  subPageMetaData: SubPageMetaDatum[];
2957
2958
  resolvedPagesJSONPath: string;
2958
- resolvedPagesJSONIndent: string;
2959
- resolvedPagesJSONNewline: string;
2960
- resolvedPagesJSONEofNewline: boolean;
2959
+ private resolvedPagesJSONIndent?;
2960
+ private resolvedPagesJSONNewline?;
2961
+ private resolvedPagesJSONEofNewline?;
2961
2962
  rawOptions: UserOptions;
2962
2963
  root: string;
2963
2964
  options: ResolvedOptions;
@@ -2993,6 +2994,10 @@ declare class PageContext {
2993
2994
  resolveRoutes(): string;
2994
2995
  resolveSubRoutes(): string;
2995
2996
  generateDeclaration(): Promise<void> | undefined;
2997
+ private readInfoFromPagesJSON;
2998
+ private getIndent;
2999
+ private getNewline;
3000
+ private getEndOfLine;
2996
3001
  }
2997
3002
 
2998
3003
  declare function invalidatePagesModule(server: ViteDevServer): void;
@@ -3189,9 +3194,12 @@ declare function getRouteBlock(path: string, blockStr: SFCBlock | undefined, rou
3189
3194
  * Resolves the files that are valid pages for the given context.
3190
3195
  */
3191
3196
  declare function getPageFiles(path: string, options: ResolvedOptions): string[];
3192
- declare function checkPagesJsonFile(path: string): boolean;
3193
- declare function readFileSync(path: string): string;
3194
- declare function writeFileSync(path: string, content: string): void;
3197
+ /**
3198
+ * 检查指定路径的pages.json文件,如果文件不存在或不是有效文件则创建一个空的pages.json文件
3199
+ * @param path - 要检查的文件路径
3200
+ * @returns Promise<void> - 无返回值的异步函数
3201
+ */
3202
+ declare function checkPagesJsonFile(path: fs.PathLike): Promise<boolean>;
3195
3203
 
3196
3204
  declare function resolveOptions(userOptions: UserOptions, viteRoot?: string): ResolvedOptions;
3197
3205
  /**
@@ -3199,7 +3207,7 @@ declare function resolveOptions(userOptions: UserOptions, viteRoot?: string): Re
3199
3207
  */
3200
3208
  declare function resolvePageDirs(dir: string, root: string, exclude: string[]): string[];
3201
3209
 
3202
- declare function VitePluginUniPages(userOptions?: UserOptions): Plugin;
3210
+ declare function VitePluginUniPages(userOptions?: UserOptions): Promise<Plugin>;
3203
3211
 
3204
- 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, readFileSync, resolveOptions, resolvePageDirs, tryPageMetaFromCustomBlock, tryPageMetaFromMacro, writeFileSync };
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 };
3205
3213
  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
@@ -6,6 +6,7 @@ import { SFCParseOptions, SFCDescriptor, SFCBlock } from '@vue/compiler-sfc';
6
6
  import * as t from '@babel/types';
7
7
  import babelGenerator from '@babel/generator';
8
8
  import Debug from 'debug';
9
+ import fs from 'node:fs';
9
10
 
10
11
  interface ConditionItem {
11
12
  /**
@@ -2955,9 +2956,9 @@ declare class PageContext {
2955
2956
  pageMetaData: PageMetaDatum[];
2956
2957
  subPageMetaData: SubPageMetaDatum[];
2957
2958
  resolvedPagesJSONPath: string;
2958
- resolvedPagesJSONIndent: string;
2959
- resolvedPagesJSONNewline: string;
2960
- resolvedPagesJSONEofNewline: boolean;
2959
+ private resolvedPagesJSONIndent?;
2960
+ private resolvedPagesJSONNewline?;
2961
+ private resolvedPagesJSONEofNewline?;
2961
2962
  rawOptions: UserOptions;
2962
2963
  root: string;
2963
2964
  options: ResolvedOptions;
@@ -2993,6 +2994,10 @@ declare class PageContext {
2993
2994
  resolveRoutes(): string;
2994
2995
  resolveSubRoutes(): string;
2995
2996
  generateDeclaration(): Promise<void> | undefined;
2997
+ private readInfoFromPagesJSON;
2998
+ private getIndent;
2999
+ private getNewline;
3000
+ private getEndOfLine;
2996
3001
  }
2997
3002
 
2998
3003
  declare function invalidatePagesModule(server: ViteDevServer): void;
@@ -3189,9 +3194,12 @@ declare function getRouteBlock(path: string, blockStr: SFCBlock | undefined, rou
3189
3194
  * Resolves the files that are valid pages for the given context.
3190
3195
  */
3191
3196
  declare function getPageFiles(path: string, options: ResolvedOptions): string[];
3192
- declare function checkPagesJsonFile(path: string): boolean;
3193
- declare function readFileSync(path: string): string;
3194
- declare function writeFileSync(path: string, content: string): void;
3197
+ /**
3198
+ * 检查指定路径的pages.json文件,如果文件不存在或不是有效文件则创建一个空的pages.json文件
3199
+ * @param path - 要检查的文件路径
3200
+ * @returns Promise<void> - 无返回值的异步函数
3201
+ */
3202
+ declare function checkPagesJsonFile(path: fs.PathLike): Promise<boolean>;
3195
3203
 
3196
3204
  declare function resolveOptions(userOptions: UserOptions, viteRoot?: string): ResolvedOptions;
3197
3205
  /**
@@ -3199,7 +3207,7 @@ declare function resolveOptions(userOptions: UserOptions, viteRoot?: string): Re
3199
3207
  */
3200
3208
  declare function resolvePageDirs(dir: string, root: string, exclude: string[]): string[];
3201
3209
 
3202
- declare function VitePluginUniPages(userOptions?: UserOptions): Plugin;
3210
+ declare function VitePluginUniPages(userOptions?: UserOptions): Promise<Plugin>;
3203
3211
 
3204
- 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, readFileSync, resolveOptions, resolvePageDirs, tryPageMetaFromCustomBlock, tryPageMetaFromMacro, writeFileSync };
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 };
3205
3213
  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
@@ -1,4 +1,3 @@
1
- import { spawn } from 'node:child_process';
2
1
  import path, { join, dirname, resolve, extname } from 'node:path';
3
2
  import process from 'node:process';
4
3
  import { babelParse, isCallOf } from 'ast-kit';
@@ -6,13 +5,14 @@ import chokidar from 'chokidar';
6
5
  import { lightYellow, bold, link, dim } from 'kolorist';
7
6
  import MagicString from 'magic-string';
8
7
  import { normalizePath, createLogger } from 'vite';
8
+ import fs, { existsSync } from 'node:fs';
9
9
  import { platform } from '@uni-helper/uni-env';
10
- import { stringify, parse, assign } from 'comment-json';
10
+ import { parse, assign, stringify } from 'comment-json';
11
11
  import Debug from 'debug';
12
12
  import detectIndent from 'detect-indent';
13
13
  import detectNewline from 'detect-newline';
14
+ import lockfile from 'proper-lockfile';
14
15
  import { loadConfig } from 'unconfig';
15
- import fs, { existsSync, readFileSync as readFileSync$1 } from 'node:fs';
16
16
  import { readFile, mkdir, writeFile as writeFile$1 } from 'node:fs/promises';
17
17
  import fg from 'fast-glob';
18
18
  import { createRequire } from 'node:module';
@@ -215,23 +215,33 @@ function getPageFiles(path, options) {
215
215
  });
216
216
  return files;
217
217
  }
218
- function checkPagesJsonFile(path) {
219
- if (!fs.existsSync(path)) {
220
- writeFileSync(path, stringify({ pages: [{ path: "" }] }, null, 2));
221
- return false;
222
- }
223
- return true;
224
- }
225
- function readFileSync(path) {
218
+ async function checkPagesJsonFile(path) {
219
+ const createEmptyFile = (path2) => {
220
+ return fs.promises.writeFile(path2, JSON.stringify({ pages: [{ path: "" }] }, null, 2), { encoding: "utf-8" }).then(() => true).catch(() => false);
221
+ };
222
+ const unlink = (path2) => {
223
+ return fs.promises.unlink(path2).then(() => true).catch(() => false);
224
+ };
226
225
  try {
227
- return fs.readFileSync(path, { encoding: "utf-8" });
226
+ const stat = await fs.promises.stat(path);
227
+ if (!stat.isFile()) {
228
+ if (!await unlink(path)) {
229
+ return false;
230
+ }
231
+ return createEmptyFile(path);
232
+ }
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)) {
236
+ return false;
237
+ }
238
+ return createEmptyFile(path);
239
+ }
240
+ return true;
228
241
  } catch {
229
- return "";
242
+ return createEmptyFile(path);
230
243
  }
231
244
  }
232
- function writeFileSync(path, content) {
233
- fs.writeFileSync(path, content, { encoding: "utf-8" });
234
- }
235
245
 
236
246
  function resolveOptions(userOptions, viteRoot = process.cwd()) {
237
247
  const {
@@ -427,7 +437,7 @@ class Page {
427
437
  }
428
438
  async readPageMetaFromFile() {
429
439
  try {
430
- const content = readFileSync$1(this.path.absolutePath, "utf-8");
440
+ const content = await fs.promises.readFile(this.path.absolutePath, { encoding: "utf-8" });
431
441
  const sfc = parseSFC(content, { filename: this.path.absolutePath });
432
442
  const meta = await tryPageMetaFromMacro(sfc);
433
443
  if (meta) {
@@ -537,9 +547,12 @@ class PageContext {
537
547
  __publicField(this, "pageMetaData", []);
538
548
  __publicField(this, "subPageMetaData", []);
539
549
  __publicField(this, "resolvedPagesJSONPath", "");
540
- __publicField(this, "resolvedPagesJSONIndent", " ");
541
- __publicField(this, "resolvedPagesJSONNewline", "\n");
542
- __publicField(this, "resolvedPagesJSONEofNewline", true);
550
+ __publicField(this, "resolvedPagesJSONIndent");
551
+ // ' '
552
+ __publicField(this, "resolvedPagesJSONNewline");
553
+ // '\n'
554
+ __publicField(this, "resolvedPagesJSONEofNewline");
555
+ // true
543
556
  __publicField(this, "rawOptions");
544
557
  __publicField(this, "root");
545
558
  __publicField(this, "options");
@@ -556,10 +569,6 @@ class PageContext {
556
569
  Debug.enable(`${prefix}${suffix}`);
557
570
  }
558
571
  this.resolvedPagesJSONPath = path.join(this.root, this.options.outDir, OUTPUT_NAME);
559
- const resolvedPagesJSONContent = readFileSync(this.resolvedPagesJSONPath);
560
- this.resolvedPagesJSONIndent = detectIndent(resolvedPagesJSONContent).indent || " ";
561
- this.resolvedPagesJSONNewline = detectNewline(resolvedPagesJSONContent) || "\n";
562
- this.resolvedPagesJSONEofNewline = (resolvedPagesJSONContent.at(-1) ?? "\n") === this.resolvedPagesJSONNewline;
563
572
  debug.options(this.options);
564
573
  }
565
574
  setLogger(logger) {
@@ -727,6 +736,16 @@ class PageContext {
727
736
  debug.subPages(this.subPageMetaData);
728
737
  }
729
738
  async getTabBarMerged() {
739
+ const tabBarItems = [];
740
+ for (const [_, page] of this.pages) {
741
+ const tabbar = await page.getTabBar();
742
+ if (tabbar) {
743
+ tabBarItems.push(tabbar);
744
+ }
745
+ }
746
+ if (tabBarItems.length === 0) {
747
+ return this.pagesGlobConfig?.tabBar;
748
+ }
730
749
  const tabBar = {
731
750
  ...this.pagesGlobConfig?.tabBar,
732
751
  list: this.pagesGlobConfig?.tabBar?.list || []
@@ -735,13 +754,6 @@ class PageContext {
735
754
  for (const item of tabBar.list) {
736
755
  pagePaths.set(item.pagePath, true);
737
756
  }
738
- const tabBarItems = [];
739
- for (const [_, page] of this.pages) {
740
- const tabbar = await page.getTabBar();
741
- if (tabbar) {
742
- tabBarItems.push(tabbar);
743
- }
744
- }
745
757
  tabBarItems.sort((a, b) => a.index - b.index);
746
758
  for (const item of tabBarItems) {
747
759
  if (!pagePaths.has(item.pagePath)) {
@@ -772,7 +784,7 @@ class PageContext {
772
784
  }
773
785
  }
774
786
  }
775
- checkPagesJsonFile(this.resolvedPagesJSONPath);
787
+ await checkPagesJsonFile(this.resolvedPagesJSONPath);
776
788
  this.options.onBeforeLoadUserConfig(this);
777
789
  await this.loadUserPagesConfig();
778
790
  this.options.onAfterLoadUserConfig(this);
@@ -803,14 +815,19 @@ class PageContext {
803
815
  const pagesJson = stringify(
804
816
  data,
805
817
  null,
806
- this.options.minify ? void 0 : this.resolvedPagesJSONIndent
807
- ) + (this.resolvedPagesJSONEofNewline ? this.resolvedPagesJSONNewline : "");
818
+ this.options.minify ? void 0 : await this.getIndent()
819
+ ) + (await this.getEndOfLine() ? await this.getNewline() : "");
808
820
  this.generateDeclaration();
809
821
  if (lsatPagesJson === pagesJson) {
810
822
  debug.pages("PagesJson Not have change");
811
823
  return false;
812
824
  }
813
- writeFileSync(this.resolvedPagesJSONPath, pagesJson);
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
+ }
814
831
  lsatPagesJson = pagesJson;
815
832
  this.options.onAfterWriteFile(this);
816
833
  return true;
@@ -832,6 +849,30 @@ class PageContext {
832
849
  debug.declaration("generating");
833
850
  return writeDeclaration(this, this.options.dts);
834
851
  }
852
+ async readInfoFromPagesJSON() {
853
+ const resolvedPagesJSONContent = await fs.promises.readFile(this.resolvedPagesJSONPath, { encoding: "utf-8" }).catch(() => "");
854
+ this.resolvedPagesJSONIndent = detectIndent(resolvedPagesJSONContent).indent || " ";
855
+ this.resolvedPagesJSONNewline = detectNewline(resolvedPagesJSONContent) || "\n";
856
+ this.resolvedPagesJSONEofNewline = (resolvedPagesJSONContent.at(-1) ?? "\n") === this.resolvedPagesJSONNewline;
857
+ }
858
+ async getIndent() {
859
+ if (!this.resolvedPagesJSONIndent) {
860
+ await this.readInfoFromPagesJSON();
861
+ }
862
+ return this.resolvedPagesJSONIndent;
863
+ }
864
+ async getNewline() {
865
+ if (!this.resolvedPagesJSONNewline) {
866
+ await this.readInfoFromPagesJSON();
867
+ }
868
+ return this.resolvedPagesJSONNewline;
869
+ }
870
+ async getEndOfLine() {
871
+ if (!this.resolvedPagesJSONEofNewline) {
872
+ await this.readInfoFromPagesJSON();
873
+ }
874
+ return this.resolvedPagesJSONEofNewline;
875
+ }
835
876
  }
836
877
  function getPagePaths(dir, options) {
837
878
  const pagesDirPath = slash(path.resolve(options.root, dir));
@@ -849,28 +890,14 @@ function defineUniPages(config) {
849
890
  return config;
850
891
  }
851
892
 
852
- async function restart() {
853
- return new Promise((resolve) => {
854
- const build = spawn(process.argv.shift(), process.argv, {
855
- cwd: process.env.VITE_ROOT_DIR || process.cwd(),
856
- detached: true,
857
- env: process.env
858
- });
859
- build.stdout?.pipe(process.stdout);
860
- build.stderr?.pipe(process.stderr);
861
- build.on("close", (code) => {
862
- resolve(process.exit(code));
863
- });
864
- });
865
- }
866
- function VitePluginUniPages(userOptions = {}) {
893
+ async function VitePluginUniPages(userOptions = {}) {
867
894
  let ctx;
868
895
  const resolvedPagesJSONPath = path.join(
869
896
  process.env.VITE_ROOT_DIR || process.cwd(),
870
897
  userOptions.outDir ?? "src",
871
898
  OUTPUT_NAME
872
899
  );
873
- const isValidated = checkPagesJsonFile(resolvedPagesJSONPath);
900
+ await checkPagesJsonFile(resolvedPagesJSONPath);
874
901
  return {
875
902
  name: "vite-plugin-uni-pages",
876
903
  enforce: "pre",
@@ -884,12 +911,6 @@ function VitePluginUniPages(userOptions = {}) {
884
911
  ctx.setLogger(logger);
885
912
  await ctx.updatePagesJSON();
886
913
  if (config.command === "build") {
887
- if (!isValidated) {
888
- ctx.logger?.warn("In build mode, if `pages.json` does not exist, the plugin cannot create the complete `pages.json` before the uni-app, so it restarts the build.", {
889
- timestamp: true
890
- });
891
- await restart();
892
- }
893
914
  if (config.build.watch)
894
915
  ctx.setupWatcher(chokidar.watch([...ctx.options.dirs, ...ctx.options.subPackages]));
895
916
  }
@@ -955,4 +976,4 @@ function VitePluginUniPages(userOptions = {}) {
955
976
  };
956
977
  }
957
978
 
958
- export { FILE_EXTENSIONS, MODULE_ID_VIRTUAL, OUTPUT_NAME, Page, PageContext, RESOLVED_MODULE_ID_VIRTUAL, VitePluginUniPages, babelGenerate, checkPagesJsonFile, debug, VitePluginUniPages as default, defineUniPages, execScript, extsToGlob, findImports, findMacro, getPageFiles, getRouteBlock, getRouteSfcBlock, invalidatePagesModule, isTargetFile, mergePageMetaDataArray, parseCustomBlock, parseSFC, readFileSync, resolveOptions, resolvePageDirs, tryPageMetaFromCustomBlock, tryPageMetaFromMacro, writeFileSync };
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 };
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.14",
4
+ "version": "0.3.16",
5
5
  "description": "File system based routing for uni-app applications using Vite",
6
6
  "author": "KeJun",
7
7
  "maintainers": [
@@ -53,6 +53,7 @@
53
53
  "dependencies": {
54
54
  "@babel/generator": "^7.28.3",
55
55
  "@babel/types": "^7.28.2",
56
+ "@types/proper-lockfile": "^4.1.4",
56
57
  "@uni-helper/uni-env": "^0.1.4",
57
58
  "@vue/compiler-sfc": "3.4.21",
58
59
  "ast-kit": "1.4.3",
@@ -66,6 +67,7 @@
66
67
  "kolorist": "^1.8.0",
67
68
  "lodash.groupby": "^4.6.0",
68
69
  "magic-string": "^0.30.11",
70
+ "proper-lockfile": "^4.1.2",
69
71
  "typescript": "5.9.2",
70
72
  "unconfig": "^7.3.2",
71
73
  "yaml": "^2.5.0"