@vizejs/vite-plugin 0.77.0 → 0.81.0

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.d.mts CHANGED
@@ -87,9 +87,15 @@ interface VitePluginConfig {
87
87
  * @default ['**\/*.vue']
88
88
  */
89
89
  scanPatterns?: string[];
90
+ /**
91
+ * Maximum number of Vue files to compile in a single native batch during
92
+ * pre-compilation. Lower values reduce peak V8 heap usage in large apps.
93
+ * @default 128
94
+ */
95
+ precompileBatchSize?: number;
90
96
  /**
91
97
  * Glob patterns to ignore during pre-compilation
92
- * @default ['node_modules/**', 'dist/**', '.git/**']
98
+ * @default ['node_modules/**', 'dist/**', '.git/**', '.nuxt/**', '.output/**', '.nitro/**', 'coverage/**']
93
99
  */
94
100
  ignorePatterns?: string[];
95
101
  }
@@ -560,9 +566,15 @@ interface VizeOptions {
560
566
  * @default ['**\/*.vue']
561
567
  */
562
568
  scanPatterns?: string[];
569
+ /**
570
+ * Maximum number of Vue files to compile in a single native batch during
571
+ * pre-compilation. Lower values reduce peak V8 heap usage in large apps.
572
+ * @default 128
573
+ */
574
+ precompileBatchSize?: number;
563
575
  /**
564
576
  * Glob patterns to ignore during pre-compilation
565
- * @default ['node_modules/**', 'dist/**', '.git/**']
577
+ * @default ['node_modules/**', 'dist/**', '.git/**', '.nuxt/**', '.output/**', '.nitro/**', 'coverage/**']
566
578
  */
567
579
  ignorePatterns?: string[];
568
580
  /**
package/dist/index.mjs CHANGED
@@ -742,8 +742,15 @@ function compileBatch(files, cache, options) {
742
742
  }
743
743
  return result;
744
744
  }
745
- //#endregion
746
- //#region src/plugin/state.ts
745
+ const DEFAULT_PRECOMPILE_IGNORE_PATTERNS = [
746
+ "node_modules/**",
747
+ "dist/**",
748
+ ".git/**",
749
+ ".nuxt/**",
750
+ ".output/**",
751
+ ".nitro/**",
752
+ "coverage/**"
753
+ ];
747
754
  function hasFileMetadataChanged(previous, next) {
748
755
  return previous === void 0 || previous.mtimeMs !== next.mtimeMs || previous.size !== next.size;
749
756
  }
@@ -761,6 +768,16 @@ function diffPrecompileFiles(files, currentMetadata, previousMetadata) {
761
768
  deletedFiles
762
769
  };
763
770
  }
771
+ function normalizePrecompileBatchSize(value) {
772
+ if (value === void 0 || !Number.isFinite(value) || value <= 0) return 128;
773
+ return Math.max(1, Math.floor(value));
774
+ }
775
+ function chunkPrecompileFiles(files, batchSize) {
776
+ const normalizedBatchSize = normalizePrecompileBatchSize(batchSize);
777
+ const chunks = [];
778
+ for (let start = 0; start < files.length; start += normalizedBatchSize) chunks.push(files.slice(start, start + normalizedBatchSize));
779
+ return chunks;
780
+ }
764
781
  function getEnvironmentCache(state, ssr) {
765
782
  return ssr ? state.ssrCache : state.cache;
766
783
  }
@@ -812,38 +829,53 @@ async function compileAll(state) {
812
829
  state.logger.info(`Pre-compilation complete: cache reused (${elapsed}ms)`);
813
830
  return;
814
831
  }
815
- const fileContents = [];
816
- for (const file of changedFiles) try {
817
- const source = fs.readFileSync(file, "utf-8");
818
- fileContents.push({
819
- path: file,
820
- source
821
- });
822
- } catch (e) {
823
- state.logger.error(`Failed to read ${file}:`, e);
824
- }
825
- const result = compileBatch(fileContents, state.cache, {
826
- ssr: false,
827
- vapor: state.mergedOptions.vapor ?? false,
828
- customRenderer: state.mergedOptions.customRenderer ?? false
829
- });
830
832
  for (const file of changedFiles) {
831
833
  state.collectedCss.delete(file);
832
834
  state.pendingHmrUpdateTypes.delete(file);
833
835
  }
834
- for (const fileResult of result.results) {
835
- const metadata = currentMetadata.get(fileResult.path);
836
- if (fileResult.errors.length > 0) {
837
- state.cache.delete(fileResult.path);
838
- state.collectedCss.delete(fileResult.path);
839
- state.precompileMetadata.delete(fileResult.path);
840
- continue;
836
+ let successCount = 0;
837
+ let failedCount = 0;
838
+ let nativeTimeMs = 0;
839
+ const chunks = chunkPrecompileFiles(changedFiles, state.precompileBatchSize);
840
+ for (const chunk of chunks) {
841
+ const fileContents = [];
842
+ for (const file of chunk) try {
843
+ const source = fs.readFileSync(file, "utf-8");
844
+ fileContents.push({
845
+ path: file,
846
+ source
847
+ });
848
+ } catch (e) {
849
+ failedCount++;
850
+ state.cache.delete(file);
851
+ state.collectedCss.delete(file);
852
+ state.precompileMetadata.delete(file);
853
+ state.logger.error(`Failed to read ${file}:`, e);
854
+ }
855
+ if (fileContents.length === 0) continue;
856
+ const result = compileBatch(fileContents, state.cache, {
857
+ ssr: false,
858
+ vapor: state.mergedOptions.vapor ?? false,
859
+ customRenderer: state.mergedOptions.customRenderer ?? false
860
+ });
861
+ successCount += result.successCount;
862
+ failedCount += result.failedCount;
863
+ nativeTimeMs += result.timeMs;
864
+ for (const fileResult of result.results) {
865
+ const metadata = currentMetadata.get(fileResult.path);
866
+ if (fileResult.errors.length > 0) {
867
+ state.cache.delete(fileResult.path);
868
+ state.collectedCss.delete(fileResult.path);
869
+ state.precompileMetadata.delete(fileResult.path);
870
+ continue;
871
+ }
872
+ if (metadata) state.precompileMetadata.set(fileResult.path, metadata);
873
+ syncCollectedCssForFile(state, fileResult.path, state.cache.get(fileResult.path));
841
874
  }
842
- if (metadata) state.precompileMetadata.set(fileResult.path, metadata);
843
- syncCollectedCssForFile(state, fileResult.path, state.cache.get(fileResult.path));
844
875
  }
845
876
  const elapsed = (performance.now() - startTime).toFixed(2);
846
- state.logger.info(`Pre-compilation complete: ${result.successCount} recompiled, ${cachedFileCount} reused, ${result.failedCount} failed (${elapsed}ms, native batch: ${result.timeMs.toFixed(2)}ms)`);
877
+ const batchLabel = chunks.length === 1 ? "batch" : "batches";
878
+ state.logger.info(`Pre-compilation complete: ${successCount} recompiled, ${cachedFileCount} reused, ${failedCount} failed (${elapsed}ms, native ${batchLabel}: ${nativeTimeMs.toFixed(2)}ms)`);
847
879
  }
848
880
  //#endregion
849
881
  //#region src/plugin/resolve.ts
@@ -870,6 +902,9 @@ function hasMacroQuery$1(id) {
870
902
  function isMacroVirtualId(id) {
871
903
  return id.startsWith("\0") && (hasMacroQuery$1(id) || hasQueryParam$1(id, "definePage"));
872
904
  }
905
+ function isVueSfcPath$1(id) {
906
+ return (id.split("?")[0] ?? id).endsWith(".vue");
907
+ }
873
908
  function normalizeRequireBase(importer) {
874
909
  if (!importer) return null;
875
910
  let normalized = importer;
@@ -930,7 +965,7 @@ async function resolveIdHook(ctx, state, id, importer, options) {
930
965
  }
931
966
  if (id === "virtual:vize-styles") return RESOLVED_CSS_MODULE;
932
967
  if (isBuild && id.startsWith("/@fs/")) return normalizeFsIdForBuild(id);
933
- if (hasMacroQuery$1(id) || hasQueryParam$1(id, "definePage")) {
968
+ if ((hasMacroQuery$1(id) || hasQueryParam$1(id, "definePage")) && isVueSfcPath$1(id)) {
934
969
  const filePath = id.split("?")[0];
935
970
  const querySuffix = id.slice(id.indexOf("?"));
936
971
  const resolved = resolveVuePath(state, filePath, importer);
@@ -1094,6 +1129,9 @@ function hasMacroQuery(id) {
1094
1129
  function normalizeMacroRealPath(realPath) {
1095
1130
  return realPath.endsWith(".vue.ts") ? realPath.slice(0, -3) : realPath;
1096
1131
  }
1132
+ function isVueSfcPath(realPath) {
1133
+ return normalizeMacroRealPath(realPath).endsWith(".vue");
1134
+ }
1097
1135
  function stripVirtualQuery(id) {
1098
1136
  return normalizeMacroRealPath(id.slice(1).split("?")[0] ?? "");
1099
1137
  }
@@ -1160,22 +1198,27 @@ function loadHook(state, id, loadOptions) {
1160
1198
  if (fallbackCompiled?.css) return resolveCssImports(fallbackCompiled.css, realPath, state.cssAliasRules, state.server !== null, currentBase);
1161
1199
  return "";
1162
1200
  }
1163
- if (id.startsWith("\0") && hasQueryParam(id, "definePage")) return loadDefinePageArtifact(state, stripVirtualQuery(id), !!loadOptions?.ssr);
1201
+ if (id.startsWith("\0") && hasQueryParam(id, "definePage")) {
1202
+ const realPath = stripVirtualQuery(id);
1203
+ if (isVueSfcPath(realPath)) return loadDefinePageArtifact(state, realPath, !!loadOptions?.ssr);
1204
+ }
1164
1205
  if (id.startsWith("\0") && hasMacroQuery(id)) {
1165
1206
  const realPath = stripVirtualQuery(id);
1166
- const artifactLoad = loadDefinePageMetaArtifact(state, realPath, !!loadOptions?.ssr);
1167
- if (artifactLoad) return artifactLoad;
1168
- if (fs.existsSync(realPath)) {
1169
- const setupMatch = fs.readFileSync(realPath, "utf-8").match(/<script\s+setup[^>]*>([\s\S]*?)<\/script>/);
1170
- if (setupMatch) return {
1171
- code: `${setupMatch[1]}\nexport default {}`,
1207
+ if (isVueSfcPath(realPath)) {
1208
+ const artifactLoad = loadDefinePageMetaArtifact(state, realPath, !!loadOptions?.ssr);
1209
+ if (artifactLoad) return artifactLoad;
1210
+ if (fs.existsSync(realPath)) {
1211
+ const setupMatch = fs.readFileSync(realPath, "utf-8").match(/<script\s+setup[^>]*>([\s\S]*?)<\/script>/);
1212
+ if (setupMatch) return {
1213
+ code: `${setupMatch[1]}\nexport default {}`,
1214
+ map: null
1215
+ };
1216
+ }
1217
+ return {
1218
+ code: "export default {}",
1172
1219
  map: null
1173
1220
  };
1174
1221
  }
1175
- return {
1176
- code: "export default {}",
1177
- map: null
1178
- };
1179
1222
  }
1180
1223
  if (isVizeVirtual(id)) {
1181
1224
  const realPath = fromVirtualId(id);
@@ -1451,6 +1494,7 @@ function vize(options = {}) {
1451
1494
  server: null,
1452
1495
  filter: () => true,
1453
1496
  scanPatterns: null,
1497
+ precompileBatchSize: 128,
1454
1498
  ignorePatterns: [],
1455
1499
  mergedOptions: options,
1456
1500
  initialized: false,
@@ -1480,6 +1524,7 @@ function vize(options = {}) {
1480
1524
  };
1481
1525
  }
1482
1526
  return {
1527
+ // @vitejs/plugin-vue normally provides them; vize must do so as its replacement.
1483
1528
  define: {
1484
1529
  __VUE_OPTIONS_API__: true,
1485
1530
  __VUE_PROD_DEVTOOLS__: env.command === "serve",
@@ -1535,6 +1580,7 @@ function vize(options = {}) {
1535
1580
  include: options.include ?? viteConfig.include,
1536
1581
  exclude: options.exclude ?? viteConfig.exclude,
1537
1582
  scanPatterns: options.scanPatterns ?? viteConfig.scanPatterns,
1583
+ precompileBatchSize: options.precompileBatchSize ?? viteConfig.precompileBatchSize,
1538
1584
  ignorePatterns: options.ignorePatterns ?? viteConfig.ignorePatterns
1539
1585
  };
1540
1586
  state.dynamicImportAliasRules = [];
@@ -1560,11 +1606,8 @@ function vize(options = {}) {
1560
1606
  state.cssAliasRules.sort((a, b) => b.find.length - a.find.length);
1561
1607
  state.filter = createFilter(state.mergedOptions.include, state.mergedOptions.exclude);
1562
1608
  state.scanPatterns = state.mergedOptions.scanPatterns ?? ["**/*.vue"];
1563
- state.ignorePatterns = state.mergedOptions.ignorePatterns ?? [
1564
- "node_modules/**",
1565
- "dist/**",
1566
- ".git/**"
1567
- ];
1609
+ state.precompileBatchSize = normalizePrecompileBatchSize(state.mergedOptions.precompileBatchSize);
1610
+ state.ignorePatterns = state.mergedOptions.ignorePatterns ?? [...DEFAULT_PRECOMPILE_IGNORE_PATTERNS];
1568
1611
  patchUnoCssBridge(resolvedConfig.plugins);
1569
1612
  state.initialized = true;
1570
1613
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vizejs/vite-plugin",
3
- "version": "0.77.0",
3
+ "version": "0.81.0",
4
4
  "description": "High-performance native Vite plugin for Vue SFC compilation powered by Vize",
5
5
  "keywords": [
6
6
  "compiler",
@@ -33,15 +33,15 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@vizejs/native": "0.77.0",
36
+ "@vizejs/native": "0.81.0",
37
37
  "tinyglobby": "0.2.16",
38
- "vize": "0.77.0"
38
+ "vize": "0.81.0"
39
39
  },
40
40
  "devDependencies": {
41
- "@types/node": "25.6.0",
41
+ "@types/node": "25.7.0",
42
42
  "typescript": "6.0.3",
43
- "vite": "npm:@voidzero-dev/vite-plus-core@0.1.19",
44
- "vite-plus": "0.1.19"
43
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.1.21",
44
+ "vite-plus": "0.1.21"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "vite": "^8.0.0"