@vizejs/vite-plugin 0.185.0 → 0.186.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
@@ -219,6 +219,10 @@ interface TypeCheckerConfig {
219
219
  * Check fallthrough attrs on multi-root templates
220
220
  */
221
221
  checkFallthroughAttrs?: boolean;
222
+ /**
223
+ * 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).
224
+ */
225
+ optionsApi?: boolean;
222
226
  /**
223
227
  * Enable Vue 2.7 / Nuxt 2 Options API template binding support
224
228
  */
@@ -788,6 +792,8 @@ interface VizeOptions {
788
792
  interface StyleBlockInfo {
789
793
  /** Raw style content (uncompiled for preprocessor langs) */
790
794
  content: string;
795
+ /** External source path from `<style src>`, when present */
796
+ src?: string | null;
791
797
  /** Language of the style block (e.g., "css", "scss", "less", "sass", "stylus") */
792
798
  lang: string | null;
793
799
  /** Whether the style block has the scoped attribute */
@@ -809,6 +815,8 @@ interface CompiledModule {
809
815
  macroArtifacts?: MacroArtifact[];
810
816
  /** Per-block style metadata extracted from the source SFC */
811
817
  styles?: StyleBlockInfo[];
818
+ /** Files loaded through SFC `src` imports */
819
+ dependencies?: string[];
812
820
  }
813
821
  //#endregion
814
822
  //#region src/virtual.d.ts
package/dist/index.mjs CHANGED
@@ -326,16 +326,62 @@ function normalizeStyleBlocks(styles) {
326
326
  if (!styles) return [];
327
327
  return styles.map((block) => ({
328
328
  content: block.content,
329
+ src: block.src ?? null,
329
330
  lang: block.lang ?? null,
330
331
  scoped: block.scoped,
331
332
  module: block.module ? block.moduleName ?? true : false,
332
333
  index: block.index
333
334
  }));
334
335
  }
336
+ function resolveRelativeSrc(filePath, src) {
337
+ return path.isAbsolute(src) ? src : path.resolve(path.dirname(filePath), src);
338
+ }
339
+ function readSrcImport(filePath, tag, src) {
340
+ const resolvedPath = resolveRelativeSrc(filePath, src);
341
+ try {
342
+ return {
343
+ path: resolvedPath,
344
+ content: fs.readFileSync(resolvedPath, "utf-8")
345
+ };
346
+ } catch {
347
+ throw new Error(`[vize] <${tag} src="${src}"> not found (resolved: ${resolvedPath}) in ${filePath}`);
348
+ }
349
+ }
350
+ function stripSrcAttribute(attrs) {
351
+ return attrs.replace(/\s*\bsrc\s*=\s*(?:"[^"]*"|'[^']*')/i, "");
352
+ }
353
+ function inlineSingleSrcBlock(source, filePath, tag, src, dependencies) {
354
+ if (!src) return source;
355
+ const imported = readSrcImport(filePath, tag, src);
356
+ dependencies.push(imported.path);
357
+ const pattern = new RegExp(`<${tag}\\b([^>]*)\\bsrc\\s*=\\s*(['"])[^'"]+\\2([^>]*)>[\\s\\S]*?<\\/${tag}>`, "i");
358
+ return source.replace(pattern, (_match, beforeSrc, _quote, afterSrc) => {
359
+ return `<${tag}${stripSrcAttribute(`${beforeSrc}${afterSrc}`)}>\n${imported.content}\n</${tag}>`;
360
+ });
361
+ }
362
+ function inlineStyleSrcBlocks(source, filePath, dependencies) {
363
+ return source.replace(/<style\b([^>]*)\bsrc\s*=\s*(['"])([^'"]+)\2([^>]*)>[\s\S]*?<\/style>/gi, (_match, beforeSrc, _quote, src, afterSrc) => {
364
+ const imported = readSrcImport(filePath, "style", src);
365
+ dependencies.push(imported.path);
366
+ return `<style${stripSrcAttribute(`${beforeSrc}${afterSrc}`)}>\n${imported.content}\n</style>`;
367
+ });
368
+ }
369
+ function resolveSfcSrcImports(filePath, source) {
370
+ const dependencies = [];
371
+ const srcInfo = native.extractSfcSrcInfo(source, filePath);
372
+ let resolvedSource = source;
373
+ resolvedSource = inlineSingleSrcBlock(resolvedSource, filePath, "script", srcInfo.scriptSrc, dependencies);
374
+ resolvedSource = inlineSingleSrcBlock(resolvedSource, filePath, "template", srcInfo.templateSrc, dependencies);
375
+ resolvedSource = inlineStyleSrcBlocks(resolvedSource, filePath, dependencies);
376
+ return {
377
+ source: resolvedSource,
378
+ dependencies
379
+ };
380
+ }
335
381
  function compileFile(filePath, cache, options, source) {
336
- const content = source ?? fs.readFileSync(filePath, "utf-8");
382
+ const resolved = resolveSfcSrcImports(filePath, source ?? fs.readFileSync(filePath, "utf-8"));
337
383
  const scopeId = generateScopeId(filePath);
338
- const result = compileSfc(content, buildCompileFileOptions(filePath, options));
384
+ const result = compileSfc(resolved.source, buildCompileFileOptions(filePath, options));
339
385
  if (result.errors.length > 0) throw new VizeSfcCompileError(filePath, result.errors);
340
386
  if (result.warnings.length > 0) result.warnings.forEach((warning) => {
341
387
  console.warn(`[vize] Warning in ${filePath}: ${warning}`);
@@ -349,7 +395,8 @@ function compileFile(filePath, cache, options, source) {
349
395
  styleHash: result.styleHash,
350
396
  scriptHash: result.scriptHash,
351
397
  macroArtifacts: result.macroArtifacts ?? [],
352
- styles: normalizeStyleBlocks(result.styles)
398
+ styles: normalizeStyleBlocks(result.styles),
399
+ dependencies: resolved.dependencies
353
400
  };
354
401
  cache.set(filePath, compiled);
355
402
  return compiled;
@@ -359,7 +406,15 @@ function compileFile(filePath, cache, options, source) {
359
406
  * Returns per-file results with content hashes for HMR.
360
407
  */
361
408
  function compileBatch(files, cache, options) {
362
- const result = compileSfcBatchWithResults(files, buildCompileBatchOptions(options));
409
+ const dependenciesByPath = /* @__PURE__ */ new Map();
410
+ const result = compileSfcBatchWithResults(files.map((file) => {
411
+ const resolved = resolveSfcSrcImports(file.path, file.source);
412
+ dependenciesByPath.set(file.path, resolved.dependencies);
413
+ return {
414
+ path: file.path,
415
+ source: resolved.source
416
+ };
417
+ }), buildCompileBatchOptions(options));
363
418
  for (const fileResult of result.results) {
364
419
  if (fileResult.errors.length === 0) cache.set(fileResult.path, {
365
420
  code: fileResult.code,
@@ -370,7 +425,8 @@ function compileBatch(files, cache, options) {
370
425
  styleHash: fileResult.styleHash,
371
426
  scriptHash: fileResult.scriptHash,
372
427
  macroArtifacts: fileResult.macroArtifacts ?? [],
373
- styles: normalizeStyleBlocks(fileResult.styles)
428
+ styles: normalizeStyleBlocks(fileResult.styles),
429
+ dependencies: dependenciesByPath.get(fileResult.path) ?? []
374
430
  });
375
431
  if (fileResult.errors.length > 0) console.error(formatCompileErrorMessage(fileResult.path, fileResult.errors));
376
432
  if (fileResult.warnings.length > 0) fileResult.warnings.forEach((warning) => {
@@ -1300,6 +1356,7 @@ function loadCompiledSfcModule(state, realPath, isSsr, currentBase, loadOptions)
1300
1356
  extractCss
1301
1357
  }, realPath, compiled);
1302
1358
  if (!compiled) return null;
1359
+ for (const dependency of compiled.dependencies ?? []) loadOptions?.addWatchFile?.(dependency);
1303
1360
  const hasDelegated = hasDelegatedStyles(compiled);
1304
1361
  const pendingHmrUpdateType = loadOptions?.ssr ? void 0 : state.pendingHmrUpdateTypes.get(realPath);
1305
1362
  if (compiled.css && !hasDelegated) compiled = {
@@ -1446,8 +1503,33 @@ function formatUnknownError(error) {
1446
1503
  //#region src/plugin/hmr.ts
1447
1504
  const VIZE_COMPONENTS_CSS_BASENAME = "vize-components.css";
1448
1505
  const VIZE_COMPONENTS_CSS_FILE = `assets/${VIZE_COMPONENTS_CSS_BASENAME}`;
1506
+ function getVueFilesDependingOn(state, dependencyFile) {
1507
+ const normalizedDependency = path.resolve(dependencyFile);
1508
+ const owners = /* @__PURE__ */ new Set();
1509
+ 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);
1510
+ return [...owners];
1511
+ }
1449
1512
  async function handleHotUpdateHook(state, ctx) {
1450
1513
  const { file, server, read } = ctx;
1514
+ const dependencyOwners = getVueFilesDependingOn(state, file);
1515
+ if (dependencyOwners.length > 0) {
1516
+ const affectedModules = /* @__PURE__ */ new Set();
1517
+ for (const vueFile of dependencyOwners) {
1518
+ state.cache.delete(vueFile);
1519
+ state.ssrCache.delete(vueFile);
1520
+ state.collectedCss.delete(vueFile);
1521
+ state.precompileMetadata.delete(vueFile);
1522
+ state.pendingHmrUpdateTypes.set(vueFile, "full-reload");
1523
+ const virtualId = toVirtualId(vueFile);
1524
+ const modules = server.moduleGraph.getModulesByFile(virtualId) ?? server.moduleGraph.getModulesByFile(vueFile);
1525
+ if (modules) for (const module of modules) {
1526
+ server.moduleGraph.invalidateModule(module);
1527
+ affectedModules.add(module);
1528
+ }
1529
+ state.logger.log(`Invalidated ${path.relative(state.root, vueFile)} because ${path.relative(state.root, file)} changed`);
1530
+ }
1531
+ return [...affectedModules];
1532
+ }
1451
1533
  if (file.endsWith(".vue") && state.filter(file)) try {
1452
1534
  const source = await read();
1453
1535
  const prevCompiled = state.cache.get(file);
@@ -1991,7 +2073,10 @@ function vize(options = {}) {
1991
2073
  return resolveIdHook(this, state, id, importer, options);
1992
2074
  },
1993
2075
  load(id, loadOptions) {
1994
- return loadHook(state, id, loadOptions);
2076
+ return loadHook(state, id, {
2077
+ ...loadOptions,
2078
+ addWatchFile: this.addWatchFile.bind(this)
2079
+ });
1995
2080
  },
1996
2081
  async transform(code, id, transformOptions) {
1997
2082
  return transformHook(state, code, id, transformOptions);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vizejs/vite-plugin",
3
- "version": "0.185.0",
3
+ "version": "0.186.0",
4
4
  "description": "High-performance native Vite plugin for Vue SFC compilation powered by Vize",
5
5
  "keywords": [
6
6
  "compiler",
@@ -39,9 +39,9 @@
39
39
  "access": "public"
40
40
  },
41
41
  "dependencies": {
42
- "@vizejs/native": "0.185.0",
42
+ "@vizejs/native": "0.186.0",
43
43
  "tinyglobby": "0.2.16",
44
- "vize": "0.185.0"
44
+ "vize": "0.186.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/node": "25.7.0",