@vizejs/vite-plugin 0.243.0 → 0.250.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
@@ -5,7 +5,7 @@ import { Plugin } from "vite";
5
5
  /**
6
6
  * Host Vue runtime version for opt-in compatibility modes
7
7
  */
8
- type VueVersion = 0.11 | 1 | 2 | 3 | "legacy";
8
+ type VueVersion = "3" | "2.7" | "2" | "1" | "0.11" | "0.10";
9
9
  /**
10
10
  * Configuration file for vize - High-performance Vue.js toolchain
11
11
  */
@@ -223,21 +223,21 @@ interface TypeCheckerConfig {
223
223
  * Check fallthrough attrs on multi-root templates
224
224
  */
225
225
  checkFallthroughAttrs?: boolean;
226
- /**
227
- * Resolve Vue 3 Options API template bindings (data/computed/methods/inject/setup/props) during type checking. Opt-in; available in the standard build (not a legacy feature).
228
- */
226
+ /** Resolve Vue 3 Options API template bindings during type checking. */
229
227
  optionsApi?: boolean;
230
228
  /**
231
229
  * Enable Vue 2.7 / Nuxt 2 Options API template binding support
232
230
  */
233
231
  legacyVue2?: boolean;
234
232
  /**
235
- * Path to tsconfig.json
233
+ * Opt-in type-checking of .jsx/.tsx Vue components (#1497). Default-off so mixed Vue/React repositories do not accidentally route React .tsx through the Vue JSX checker. Set to true to route .jsx/.tsx through the Vize JSX virtual-TS path.
236
234
  */
237
- tsconfig?: string;
235
+ jsxTypecheck?: boolean;
238
236
  /**
239
- * Path to the Corsa executable. This is the canonical runtime key; tsgoPath is kept as a compatibility alias.
237
+ * Path to tsconfig.json
240
238
  */
239
+ tsconfig?: string;
240
+ /** Path to the Corsa executable. tsgoPath is kept as a compatibility alias. */
241
241
  corsaPath?: string;
242
242
  /**
243
243
  * Deprecated alias for typeChecker.corsaPath
package/dist/index.mjs CHANGED
@@ -10,7 +10,8 @@ import { pathToFileURL } from "node:url";
10
10
  import * as vite from "vite";
11
11
  //#region src/hmr.ts
12
12
  function hasHmrChanges(prev, next) {
13
- return hasViteHmrChanges(toHmrHashes(prev), toHmrHashes(next));
13
+ if (!prev) return true;
14
+ return hasViteHmrChanges(toHmrHashes(prev), toHmrHashes(next)) || runtimeFingerprint(prev) !== runtimeFingerprint(next) || styleFingerprint(prev) !== styleFingerprint(next);
14
15
  }
15
16
  /**
16
17
  * Detect the type of HMR update needed based on content hash changes.
@@ -20,7 +21,13 @@ function hasHmrChanges(prev, next) {
20
21
  * @returns The type of HMR update needed
21
22
  */
22
23
  function detectHmrUpdateType(prev, next) {
23
- return detectViteHmrUpdateType(toHmrHashes(prev), toHmrHashes(next));
24
+ if (!prev) return detectViteHmrUpdateType(void 0, toHmrHashes(next));
25
+ if (prev.scriptHash !== next.scriptHash) return "full-reload";
26
+ if (prev.templateHash !== next.templateHash) return "template-only";
27
+ if (prev.styleHash !== next.styleHash) return "style-only";
28
+ if (runtimeFingerprint(prev) !== runtimeFingerprint(next)) return "full-reload";
29
+ if (styleFingerprint(prev) !== styleFingerprint(next)) return "style-only";
30
+ return "full-reload";
24
31
  }
25
32
  /**
26
33
  * Generate HMR-aware code output based on update type.
@@ -35,6 +42,38 @@ function toHmrHashes(module) {
35
42
  styleHash: module.styleHash
36
43
  } : void 0;
37
44
  }
45
+ function runtimeFingerprint(module) {
46
+ return JSON.stringify({
47
+ code: module.code,
48
+ scopeId: module.scopeId,
49
+ hasScoped: module.hasScoped,
50
+ macroArtifacts: module.macroArtifacts?.map((artifact) => ({
51
+ kind: artifact.kind,
52
+ name: artifact.name,
53
+ source: artifact.source,
54
+ content: artifact.content,
55
+ moduleCode: artifact.moduleCode,
56
+ start: artifact.start,
57
+ end: artifact.end
58
+ })),
59
+ styles: module.styles?.map((style) => ({
60
+ lang: style.lang,
61
+ scoped: style.scoped,
62
+ module: style.module,
63
+ index: style.index
64
+ })),
65
+ dependencies: [...module.dependencies ?? []].sort()
66
+ });
67
+ }
68
+ function styleFingerprint(module) {
69
+ return JSON.stringify({
70
+ css: module.css,
71
+ styles: module.styles?.map((style) => ({
72
+ index: style.index,
73
+ content: style.content
74
+ }))
75
+ });
76
+ }
38
77
  //#endregion
39
78
  //#region src/utils/css.ts
40
79
  function scopeCssForPipeline(css, scopeId) {
@@ -495,6 +534,9 @@ const DEFAULT_PRECOMPILE_IGNORE_PATTERNS = [
495
534
  ".nitro/**",
496
535
  "coverage/**"
497
536
  ];
537
+ function isPrecompileSfcPath(path) {
538
+ return path.endsWith(".vue");
539
+ }
498
540
  function diffPrecompileFiles(files, currentMetadata, previousMetadata) {
499
541
  return diffVitePrecompileFiles([...files], toNativePrecompileMetadataEntries(currentMetadata), toNativePrecompileMetadataEntries(previousMetadata));
500
542
  }
@@ -560,13 +602,13 @@ function clearBuildCaches(state) {
560
602
  */
561
603
  async function compileAll(state) {
562
604
  const startTime = performance.now();
563
- const files = await glob(state.scanPatterns, {
605
+ const sfcFiles = (await glob(state.scanPatterns, {
564
606
  cwd: state.root,
565
607
  ignore: state.ignorePatterns,
566
608
  absolute: true
567
- });
609
+ })).filter(isPrecompileSfcPath);
568
610
  const currentMetadata = /* @__PURE__ */ new Map();
569
- for (const file of files) try {
611
+ for (const file of sfcFiles) try {
570
612
  const stat = fs.statSync(file);
571
613
  currentMetadata.set(file, {
572
614
  mtimeMs: stat.mtimeMs,
@@ -575,8 +617,8 @@ async function compileAll(state) {
575
617
  } catch (e) {
576
618
  state.logger.error(`Failed to stat ${file}:`, e);
577
619
  }
578
- const { changedFiles, deletedFiles } = diffPrecompileFiles(files, currentMetadata, state.precompileMetadata);
579
- const cachedFileCount = files.length - changedFiles.length;
620
+ const { changedFiles, deletedFiles } = diffPrecompileFiles(sfcFiles, currentMetadata, state.precompileMetadata);
621
+ const cachedFileCount = sfcFiles.length - changedFiles.length;
580
622
  for (const file of deletedFiles) {
581
623
  state.cache.delete(file);
582
624
  state.ssrCache.delete(file);
@@ -584,7 +626,7 @@ async function compileAll(state) {
584
626
  state.precompileMetadata.delete(file);
585
627
  state.pendingHmrUpdateTypes.delete(file);
586
628
  }
587
- state.logger.info(`Pre-compiling ${files.length} Vue files... (${changedFiles.length} changed, ${cachedFileCount} cached, ${deletedFiles.length} removed)`);
629
+ state.logger.info(`Pre-compiling ${sfcFiles.length} Vue files... (${changedFiles.length} changed, ${cachedFileCount} cached, ${deletedFiles.length} removed)`);
588
630
  if (changedFiles.length === 0) {
589
631
  const elapsed = (performance.now() - startTime).toFixed(2);
590
632
  state.logger.info(`Pre-compilation complete: cache reused (${elapsed}ms)`);
@@ -1631,6 +1673,34 @@ function getVueFilesDependingOn(state, dependencyFile) {
1631
1673
  for (const cache of [state.cache, state.ssrCache]) for (const [vueFile, compiled] of cache) if (compiled.dependencies?.some((dependency) => path.resolve(dependency) === normalizedDependency)) owners.add(vueFile);
1632
1674
  return [...owners];
1633
1675
  }
1676
+ function unique(values) {
1677
+ return [...new Set(values)];
1678
+ }
1679
+ function getVueModuleFileCandidates(vueFile) {
1680
+ return unique([
1681
+ toVirtualId(vueFile),
1682
+ toPluginVisibleVirtualId(vueFile),
1683
+ toVirtualId(vueFile, true),
1684
+ toPluginVisibleVirtualId(vueFile, true),
1685
+ toPluginVisibleVirtualId(vueFile).split("?")[0],
1686
+ vueFile
1687
+ ]);
1688
+ }
1689
+ function getStyleModuleFileCandidates(styleId) {
1690
+ return unique([styleId, `${styleId}.css`]);
1691
+ }
1692
+ function collectModulesByFile(server, fileIds) {
1693
+ const modules = /* @__PURE__ */ new Set();
1694
+ for (const fileId of fileIds) {
1695
+ const matched = server.moduleGraph.getModulesByFile(fileId);
1696
+ if (!matched) continue;
1697
+ for (const mod of matched) modules.add(mod);
1698
+ }
1699
+ return modules;
1700
+ }
1701
+ function invalidateModules(server, modules) {
1702
+ for (const module of modules) server.moduleGraph.invalidateModule(module);
1703
+ }
1634
1704
  async function handleHotUpdateHook(state, ctx) {
1635
1705
  const { file, server, read } = ctx;
1636
1706
  const dependencyOwners = getVueFilesDependingOn(state, file);
@@ -1642,9 +1712,8 @@ async function handleHotUpdateHook(state, ctx) {
1642
1712
  state.collectedCss.delete(vueFile);
1643
1713
  state.precompileMetadata.delete(vueFile);
1644
1714
  state.pendingHmrUpdateTypes.set(vueFile, "full-reload");
1645
- const virtualId = toVirtualId(vueFile);
1646
- const modules = server.moduleGraph.getModulesByFile(virtualId) ?? server.moduleGraph.getModulesByFile(vueFile);
1647
- if (modules) for (const module of modules) {
1715
+ const modules = collectModulesByFile(server, getVueModuleFileCandidates(vueFile));
1716
+ for (const module of modules) {
1648
1717
  server.moduleGraph.invalidateModule(module);
1649
1718
  affectedModules.add(module);
1650
1719
  }
@@ -1674,8 +1743,7 @@ async function handleHotUpdateHook(state, ctx) {
1674
1743
  }
1675
1744
  const updateType = detectHmrUpdateType(prevCompiled, newCompiled);
1676
1745
  state.logger.log(`Re-compiled: ${path.relative(state.root, file)} (${updateType})`);
1677
- const virtualId = toVirtualId(file);
1678
- const modules = server.moduleGraph.getModulesByFile(virtualId) ?? server.moduleGraph.getModulesByFile(file);
1746
+ const modules = collectModulesByFile(server, getVueModuleFileCandidates(file));
1679
1747
  const hasDelegated = hasDelegatedStyles(newCompiled);
1680
1748
  if (hasDelegated && updateType === "style-only") {
1681
1749
  const affectedModules = /* @__PURE__ */ new Set();
@@ -1687,12 +1755,11 @@ async function handleHotUpdateHook(state, ctx) {
1687
1755
  if (block.scoped) params.set("scoped", `data-v-${newCompiled.scopeId}`);
1688
1756
  params.set("lang", block.lang ?? "css");
1689
1757
  if (block.module !== false) params.set("module", typeof block.module === "string" ? block.module : "");
1690
- const styleId = `${file}?${params.toString()}`;
1691
- const styleMods = server.moduleGraph.getModulesByFile(styleId);
1692
- if (styleMods) for (const mod of styleMods) affectedModules.add(mod);
1758
+ const styleMods = collectModulesByFile(server, getStyleModuleFileCandidates(`${file}?${params.toString()}`));
1759
+ for (const mod of styleMods) affectedModules.add(mod);
1693
1760
  }
1694
1761
  if (affectedModules.size > 0) return [...affectedModules];
1695
- if (modules) return [...modules];
1762
+ if (modules.size > 0) return [...modules];
1696
1763
  return [];
1697
1764
  }
1698
1765
  if (updateType === "style-only" && newCompiled.css && !hasDelegated) {
@@ -1708,8 +1775,9 @@ async function handleHotUpdateHook(state, ctx) {
1708
1775
  });
1709
1776
  return [];
1710
1777
  }
1711
- if (modules) {
1778
+ if (modules.size > 0) {
1712
1779
  state.pendingHmrUpdateTypes.set(file, updateType);
1780
+ invalidateModules(server, modules);
1713
1781
  return [...modules];
1714
1782
  }
1715
1783
  state.pendingHmrUpdateTypes.delete(file);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vizejs/vite-plugin",
3
- "version": "0.243.0",
3
+ "version": "0.250.0",
4
4
  "description": "High-performance native Vite plugin for Vue SFC compilation powered by Vize",
5
5
  "keywords": [
6
6
  "compiler",
@@ -40,9 +40,9 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
- "@vizejs/native": "0.243.0",
43
+ "@vizejs/native": "0.251.0",
44
44
  "tinyglobby": "0.2.16",
45
- "vize": "0.243.0"
45
+ "vize": "0.251.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/node": "25.9.2",
@@ -51,7 +51,7 @@
51
51
  "vite-plus": "0.1.21"
52
52
  },
53
53
  "peerDependencies": {
54
- "vite": "^8.0.0"
54
+ "vite": "^7.3.0 || ^8.0.0"
55
55
  },
56
56
  "engines": {
57
57
  "node": ">=22"