@vizejs/vite-plugin 0.8.0 → 0.10.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/LICENSE +21 -0
- package/dist/index.d.ts +14 -7
- package/dist/index.js +276 -31
- package/package.json +2 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ubugeeei
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
CHANGED
|
@@ -473,6 +473,18 @@ interface VizeOptions {
|
|
|
473
473
|
*/
|
|
474
474
|
debug?: boolean;
|
|
475
475
|
}
|
|
476
|
+
interface StyleBlockInfo {
|
|
477
|
+
/** Raw style content (uncompiled for preprocessor langs) */
|
|
478
|
+
content: string;
|
|
479
|
+
/** Language of the style block (e.g., "css", "scss", "less", "sass", "stylus") */
|
|
480
|
+
lang: string | null;
|
|
481
|
+
/** Whether the style block has the scoped attribute */
|
|
482
|
+
scoped: boolean;
|
|
483
|
+
/** CSS Modules: true for unnamed `module`, or the binding name for `module="name"` */
|
|
484
|
+
module: boolean | string;
|
|
485
|
+
/** Index of this style block in the SFC */
|
|
486
|
+
index: number;
|
|
487
|
+
}
|
|
476
488
|
interface CompiledModule {
|
|
477
489
|
code: string;
|
|
478
490
|
css?: string;
|
|
@@ -481,6 +493,8 @@ interface CompiledModule {
|
|
|
481
493
|
templateHash?: string;
|
|
482
494
|
styleHash?: string;
|
|
483
495
|
scriptHash?: string;
|
|
496
|
+
/** Per-block style metadata extracted from the source SFC */
|
|
497
|
+
styles?: StyleBlockInfo[];
|
|
484
498
|
}
|
|
485
499
|
|
|
486
500
|
//#endregion
|
|
@@ -504,13 +518,6 @@ interface DynamicImportAliasRule {
|
|
|
504
518
|
fromPrefix: string;
|
|
505
519
|
toPrefix: string;
|
|
506
520
|
}
|
|
507
|
-
/**
|
|
508
|
-
* Rewrite static asset URLs in compiled template output.
|
|
509
|
-
*
|
|
510
|
-
* Transforms property values like `src: "@/assets/logo.svg"` into import
|
|
511
|
-
* statements hoisted to the top of the module, so Vite's module resolution
|
|
512
|
-
* pipeline handles alias expansion and asset hashing in both dev and build.
|
|
513
|
-
*/
|
|
514
521
|
declare function rewriteStaticAssetUrls(code: string, aliasRules: DynamicImportAliasRule[]): string;
|
|
515
522
|
declare const __internal: {
|
|
516
523
|
rewriteStaticAssetUrls: typeof rewriteStaticAssetUrls;
|
package/dist/index.js
CHANGED
|
@@ -68,6 +68,30 @@ if (import.meta.hot) {
|
|
|
68
68
|
|
|
69
69
|
//#endregion
|
|
70
70
|
//#region src/utils.ts
|
|
71
|
+
/** Known CSS preprocessor languages that must be delegated to Vite */
|
|
72
|
+
const PREPROCESSOR_LANGS = new Set([
|
|
73
|
+
"scss",
|
|
74
|
+
"sass",
|
|
75
|
+
"less",
|
|
76
|
+
"stylus",
|
|
77
|
+
"styl"
|
|
78
|
+
]);
|
|
79
|
+
/** Check if a style block requires Vite's preprocessor pipeline */
|
|
80
|
+
function needsPreprocessor(block) {
|
|
81
|
+
return block.lang !== null && PREPROCESSOR_LANGS.has(block.lang);
|
|
82
|
+
}
|
|
83
|
+
/** Check if a style block uses CSS Modules */
|
|
84
|
+
function isCssModule(block) {
|
|
85
|
+
return block.module !== false;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Check if any style blocks in the compiled module require delegation to
|
|
89
|
+
* Vite's CSS pipeline (preprocessor or CSS Modules).
|
|
90
|
+
*/
|
|
91
|
+
function hasDelegatedStyles(compiled) {
|
|
92
|
+
if (!compiled.styles) return false;
|
|
93
|
+
return compiled.styles.some((s) => needsPreprocessor(s) || isCssModule(s));
|
|
94
|
+
}
|
|
71
95
|
function generateScopeId(filename) {
|
|
72
96
|
const hash = createHash("sha256").update(filename).digest("hex");
|
|
73
97
|
return hash.slice(0, 8);
|
|
@@ -82,7 +106,7 @@ function createFilter(include, exclude) {
|
|
|
82
106
|
};
|
|
83
107
|
}
|
|
84
108
|
function generateOutput(compiled, options) {
|
|
85
|
-
const { isProduction, isDev, hmrUpdateType, extractCss } = options;
|
|
109
|
+
const { isProduction, isDev, hmrUpdateType, extractCss, filePath } = options;
|
|
86
110
|
let output = compiled.code;
|
|
87
111
|
const exportDefaultRegex = /^export default /m;
|
|
88
112
|
const hasExportDefault = exportDefaultRegex.test(output);
|
|
@@ -94,7 +118,43 @@ function generateOutput(compiled, options) {
|
|
|
94
118
|
} else if (hasExportDefault && hasSfcMainDefined) {
|
|
95
119
|
if (compiled.hasScoped && compiled.scopeId) output = output.replace(/^export default _sfc_main/m, `_sfc_main.__scopeId = "data-v-${compiled.scopeId}";\nexport default _sfc_main`);
|
|
96
120
|
}
|
|
97
|
-
|
|
121
|
+
const useDelegatedStyles = hasDelegatedStyles(compiled) && filePath;
|
|
122
|
+
if (useDelegatedStyles) {
|
|
123
|
+
const styleImports = [];
|
|
124
|
+
const cssModuleImports = [];
|
|
125
|
+
for (const block of compiled.styles) {
|
|
126
|
+
const lang = block.lang ?? "css";
|
|
127
|
+
const params = new URLSearchParams();
|
|
128
|
+
params.set("vue", "");
|
|
129
|
+
params.set("type", "style");
|
|
130
|
+
params.set("index", String(block.index));
|
|
131
|
+
if (block.scoped) params.set("scoped", `data-v-${compiled.scopeId}`);
|
|
132
|
+
params.set("lang", lang);
|
|
133
|
+
if (isCssModule(block)) {
|
|
134
|
+
const bindingName = typeof block.module === "string" ? block.module : "$style";
|
|
135
|
+
params.set("module", typeof block.module === "string" ? block.module : "");
|
|
136
|
+
const importUrl = `${filePath}?${params.toString()}`;
|
|
137
|
+
cssModuleImports.push(`import ${bindingName} from ${JSON.stringify(importUrl)};`);
|
|
138
|
+
} else {
|
|
139
|
+
const importUrl = `${filePath}?${params.toString()}`;
|
|
140
|
+
styleImports.push(`import ${JSON.stringify(importUrl)};`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const allImports = [...styleImports, ...cssModuleImports].join("\n");
|
|
144
|
+
if (allImports) output = allImports + "\n" + output;
|
|
145
|
+
if (cssModuleImports.length > 0) {
|
|
146
|
+
const moduleBindings = [];
|
|
147
|
+
for (const block of compiled.styles) if (isCssModule(block)) {
|
|
148
|
+
const bindingName = typeof block.module === "string" ? block.module : "$style";
|
|
149
|
+
moduleBindings.push({
|
|
150
|
+
name: bindingName,
|
|
151
|
+
bindingName
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
const cssModuleSetup = moduleBindings.map((m) => `_sfc_main.__cssModules = _sfc_main.__cssModules || {};\n_sfc_main.__cssModules[${JSON.stringify(m.name)}] = ${m.bindingName};`).join("\n");
|
|
155
|
+
output = output.replace(/^export default _sfc_main;/m, `${cssModuleSetup}\nexport default _sfc_main;`);
|
|
156
|
+
}
|
|
157
|
+
} else if (compiled.css && !(isProduction && extractCss)) {
|
|
98
158
|
const cssCode = JSON.stringify(compiled.css);
|
|
99
159
|
const cssId = JSON.stringify(`vize-style-${compiled.scopeId}`);
|
|
100
160
|
output = `
|
|
@@ -185,6 +245,33 @@ function resolveCssPath(importPath, importer, aliasRules) {
|
|
|
185
245
|
//#endregion
|
|
186
246
|
//#region src/compiler.ts
|
|
187
247
|
const { compileSfc, compileSfcBatchWithResults } = native;
|
|
248
|
+
/**
|
|
249
|
+
* Extract style block metadata from a Vue SFC source string.
|
|
250
|
+
* Parses `<style>` tags to determine lang, scoped, and module attributes.
|
|
251
|
+
*/
|
|
252
|
+
function extractStyleBlocks(source) {
|
|
253
|
+
const blocks = [];
|
|
254
|
+
const styleRegex = /<style([^>]*)>([\s\S]*?)<\/style>/gi;
|
|
255
|
+
let match;
|
|
256
|
+
let index = 0;
|
|
257
|
+
while ((match = styleRegex.exec(source)) !== null) {
|
|
258
|
+
const attrs = match[1];
|
|
259
|
+
const content = match[2];
|
|
260
|
+
const lang = attrs.match(/\blang=["']([^"']+)["']/)?.[1] ?? null;
|
|
261
|
+
const scoped = /\bscoped\b/.test(attrs);
|
|
262
|
+
const moduleMatch = attrs.match(/\bmodule(?:=["']([^"']+)["'])?\b/);
|
|
263
|
+
const isModule = moduleMatch ? moduleMatch[1] || true : false;
|
|
264
|
+
blocks.push({
|
|
265
|
+
content,
|
|
266
|
+
lang,
|
|
267
|
+
scoped,
|
|
268
|
+
module: isModule,
|
|
269
|
+
index
|
|
270
|
+
});
|
|
271
|
+
index++;
|
|
272
|
+
}
|
|
273
|
+
return blocks;
|
|
274
|
+
}
|
|
188
275
|
function compileFile(filePath, cache, options, source) {
|
|
189
276
|
const content = source ?? fs.readFileSync(filePath, "utf-8");
|
|
190
277
|
const scopeId = generateScopeId(filePath);
|
|
@@ -202,11 +289,13 @@ function compileFile(filePath, cache, options, source) {
|
|
|
202
289
|
if (result.warnings.length > 0) result.warnings.forEach((warning) => {
|
|
203
290
|
console.warn(`[vize] Warning in ${filePath}: ${warning}`);
|
|
204
291
|
});
|
|
292
|
+
const styles = extractStyleBlocks(content);
|
|
205
293
|
const compiled = {
|
|
206
294
|
code: result.code,
|
|
207
295
|
css: result.css,
|
|
208
296
|
scopeId,
|
|
209
|
-
hasScoped
|
|
297
|
+
hasScoped,
|
|
298
|
+
styles
|
|
210
299
|
};
|
|
211
300
|
cache.set(filePath, compiled);
|
|
212
301
|
return compiled;
|
|
@@ -221,16 +310,23 @@ function compileBatch(files, cache, options) {
|
|
|
221
310
|
source: f.source
|
|
222
311
|
}));
|
|
223
312
|
const result = compileSfcBatchWithResults(inputs, { ssr: options.ssr });
|
|
313
|
+
const sourceMap = new Map();
|
|
314
|
+
for (const f of files) sourceMap.set(f.path, f.source);
|
|
224
315
|
for (const fileResult of result.results) {
|
|
225
|
-
if (fileResult.errors.length === 0)
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
316
|
+
if (fileResult.errors.length === 0) {
|
|
317
|
+
const source = sourceMap.get(fileResult.path);
|
|
318
|
+
const styles = source ? extractStyleBlocks(source) : void 0;
|
|
319
|
+
cache.set(fileResult.path, {
|
|
320
|
+
code: fileResult.code,
|
|
321
|
+
css: fileResult.css,
|
|
322
|
+
scopeId: fileResult.scopeId,
|
|
323
|
+
hasScoped: fileResult.hasScoped,
|
|
324
|
+
templateHash: fileResult.templateHash,
|
|
325
|
+
styleHash: fileResult.styleHash,
|
|
326
|
+
scriptHash: fileResult.scriptHash,
|
|
327
|
+
styles
|
|
328
|
+
});
|
|
329
|
+
}
|
|
234
330
|
if (fileResult.errors.length > 0) console.error(`[vize] Compilation error in ${fileResult.path}:\n${fileResult.errors.join("\n")}`);
|
|
235
331
|
if (fileResult.warnings.length > 0) fileResult.warnings.forEach((warning) => {
|
|
236
332
|
console.warn(`[vize] Warning in ${fileResult.path}: ${warning}`);
|
|
@@ -361,14 +457,16 @@ function rewriteDynamicTemplateImports(code, aliasRules) {
|
|
|
361
457
|
* statements hoisted to the top of the module, so Vite's module resolution
|
|
362
458
|
* pipeline handles alias expansion and asset hashing in both dev and build.
|
|
363
459
|
*/
|
|
460
|
+
const SCRIPT_EXTENSIONS = /\.(js|mjs|cjs|ts|mts|cts|jsx|tsx)$/i;
|
|
364
461
|
function rewriteStaticAssetUrls(code, aliasRules) {
|
|
365
462
|
let rewritten = code;
|
|
366
463
|
const imports = [];
|
|
367
464
|
let counter = 0;
|
|
368
465
|
for (const rule of aliasRules) {
|
|
369
466
|
const pattern = new RegExp(`("?src"?\\s*:\\s*)(?:"(${escapeRegExp(rule.fromPrefix)}[^"]+)"|'(${escapeRegExp(rule.fromPrefix)}[^']+)')`, "g");
|
|
370
|
-
rewritten = rewritten.replace(pattern, (
|
|
467
|
+
rewritten = rewritten.replace(pattern, (match, prefix, dqPath, sqPath) => {
|
|
371
468
|
const fullPath = dqPath || sqPath;
|
|
469
|
+
if (fullPath && SCRIPT_EXTENSIONS.test(fullPath)) return match;
|
|
372
470
|
const varName = `__vize_static_${counter++}`;
|
|
373
471
|
imports.push(`import ${varName} from ${JSON.stringify(fullPath)};`);
|
|
374
472
|
return `${prefix}${varName}`;
|
|
@@ -463,7 +561,17 @@ function vize(options = {}) {
|
|
|
463
561
|
}
|
|
464
562
|
const result = compileBatch(fileContents, cache, { ssr: mergedOptions.ssr ?? false });
|
|
465
563
|
if (isProduction) {
|
|
466
|
-
for (const fileResult of result.results) if (fileResult.css)
|
|
564
|
+
for (const fileResult of result.results) if (fileResult.css) {
|
|
565
|
+
const cached = cache.get(fileResult.path);
|
|
566
|
+
const hasDelegated = cached?.styles?.some((s) => s.lang !== null && [
|
|
567
|
+
"scss",
|
|
568
|
+
"sass",
|
|
569
|
+
"less",
|
|
570
|
+
"stylus",
|
|
571
|
+
"styl"
|
|
572
|
+
].includes(s.lang) || s.module !== false);
|
|
573
|
+
if (!hasDelegated) collectedCss.set(fileResult.path, resolveCssImports(fileResult.css, fileResult.path, cssAliasRules, false));
|
|
574
|
+
}
|
|
467
575
|
}
|
|
468
576
|
const elapsed = (performance.now() - startTime).toFixed(2);
|
|
469
577
|
logger.info(`Pre-compilation complete: ${result.successCount} succeeded, ${result.failedCount} failed (${elapsed}ms, native batch: ${result.timeMs.toFixed(2)}ms)`);
|
|
@@ -490,11 +598,7 @@ function vize(options = {}) {
|
|
|
490
598
|
__VUE_PROD_DEVTOOLS__: env.command === "serve",
|
|
491
599
|
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false
|
|
492
600
|
},
|
|
493
|
-
optimizeDeps: {
|
|
494
|
-
include: ["vue"],
|
|
495
|
-
exclude: ["virtual:vize-styles"],
|
|
496
|
-
rolldownOptions: { external: [/\.vue$/] }
|
|
497
|
-
}
|
|
601
|
+
optimizeDeps: { exclude: ["virtual:vize-styles"] }
|
|
498
602
|
};
|
|
499
603
|
},
|
|
500
604
|
async configResolved(resolvedConfig) {
|
|
@@ -633,9 +737,20 @@ function vize(options = {}) {
|
|
|
633
737
|
}
|
|
634
738
|
if (id === VIRTUAL_CSS_MODULE) return RESOLVED_CSS_MODULE;
|
|
635
739
|
if (isBuild && id.startsWith("/@fs/")) return normalizeFsIdForBuild(id);
|
|
636
|
-
if (id.includes("?
|
|
637
|
-
|
|
638
|
-
const
|
|
740
|
+
if (id.includes("?macro=true")) {
|
|
741
|
+
const filePath = id.split("?")[0];
|
|
742
|
+
const resolved = resolveVuePath(filePath, importer);
|
|
743
|
+
if (resolved && fs.existsSync(resolved)) return `\0${resolved}?macro=true`;
|
|
744
|
+
}
|
|
745
|
+
if (id.includes("?vue&type=style") || id.includes("?vue=&type=style")) {
|
|
746
|
+
const params = new URLSearchParams(id.split("?")[1]);
|
|
747
|
+
const lang = params.get("lang") || "css";
|
|
748
|
+
if (params.has("module")) return `\0${id}.module.${lang}`;
|
|
749
|
+
return `\0${id}.${lang}`;
|
|
750
|
+
}
|
|
751
|
+
const isMacroImporter = importer?.startsWith("\0") && importer?.endsWith("?macro=true");
|
|
752
|
+
if (importer && (isVizeVirtual(importer) || isMacroImporter)) {
|
|
753
|
+
const cleanImporter = isMacroImporter ? importer.slice(1).replace("?macro=true", "") : fromVirtualId(importer);
|
|
639
754
|
logger.log(`resolveId from virtual: id=${id}, cleanImporter=${cleanImporter}`);
|
|
640
755
|
if (id.startsWith("#")) try {
|
|
641
756
|
return await this.resolve(id, cleanImporter, { skipSelf: true });
|
|
@@ -643,7 +758,21 @@ function vize(options = {}) {
|
|
|
643
758
|
return null;
|
|
644
759
|
}
|
|
645
760
|
if (!id.endsWith(".vue")) {
|
|
646
|
-
if (id.
|
|
761
|
+
if (!id.startsWith("./") && !id.startsWith("../") && !id.startsWith("/")) {
|
|
762
|
+
const matchesAlias = cssAliasRules.some((rule) => id === rule.find || id.startsWith(rule.find + "/"));
|
|
763
|
+
if (!matchesAlias) try {
|
|
764
|
+
const resolved = await this.resolve(id, cleanImporter, { skipSelf: true });
|
|
765
|
+
if (resolved) {
|
|
766
|
+
logger.log(`resolveId: resolved bare ${id} to ${resolved.id} via Vite resolver`);
|
|
767
|
+
if (isBuild && resolved.id.startsWith("/@fs/")) return {
|
|
768
|
+
...resolved,
|
|
769
|
+
id: normalizeFsIdForBuild(resolved.id)
|
|
770
|
+
};
|
|
771
|
+
return resolved;
|
|
772
|
+
}
|
|
773
|
+
} catch {}
|
|
774
|
+
return null;
|
|
775
|
+
}
|
|
647
776
|
try {
|
|
648
777
|
const resolved = await this.resolve(id, cleanImporter, { skipSelf: true });
|
|
649
778
|
if (resolved) {
|
|
@@ -731,13 +860,60 @@ function vize(options = {}) {
|
|
|
731
860
|
const allCss = Array.from(collectedCss.values()).join("\n\n");
|
|
732
861
|
return allCss;
|
|
733
862
|
}
|
|
734
|
-
|
|
735
|
-
|
|
863
|
+
let styleId = id;
|
|
864
|
+
if (id.startsWith("\0") && id.includes("?vue")) styleId = id.slice(1).replace(/\.module\.\w+$/, "").replace(/\.\w+$/, "");
|
|
865
|
+
if (styleId.includes("?vue&type=style") || styleId.includes("?vue=&type=style")) {
|
|
866
|
+
const [filename, queryString] = styleId.split("?");
|
|
736
867
|
const realPath = isVizeVirtual(filename) ? fromVirtualId(filename) : filename;
|
|
868
|
+
const params = new URLSearchParams(queryString);
|
|
869
|
+
const indexStr = params.get("index");
|
|
870
|
+
const lang = params.get("lang");
|
|
871
|
+
const _hasModule = params.has("module");
|
|
872
|
+
const scoped = params.get("scoped");
|
|
737
873
|
const compiled = cache.get(realPath);
|
|
874
|
+
const blockIndex = indexStr !== null ? parseInt(indexStr, 10) : -1;
|
|
875
|
+
if (compiled?.styles && blockIndex >= 0 && blockIndex < compiled.styles.length) {
|
|
876
|
+
const block = compiled.styles[blockIndex];
|
|
877
|
+
let styleContent = block.content;
|
|
878
|
+
if (scoped && block.scoped && lang && lang !== "css") {
|
|
879
|
+
const lines = styleContent.split("\n");
|
|
880
|
+
const hoisted = [];
|
|
881
|
+
const body = [];
|
|
882
|
+
for (const line of lines) {
|
|
883
|
+
const trimmed = line.trimStart();
|
|
884
|
+
if (trimmed.startsWith("@use ") || trimmed.startsWith("@forward ") || trimmed.startsWith("@import ")) hoisted.push(line);
|
|
885
|
+
else body.push(line);
|
|
886
|
+
}
|
|
887
|
+
const bodyContent = body.join("\n");
|
|
888
|
+
const hoistedContent = hoisted.length > 0 ? hoisted.join("\n") + "\n\n" : "";
|
|
889
|
+
styleContent = `${hoistedContent}[${scoped}] {\n${bodyContent}\n}`;
|
|
890
|
+
}
|
|
891
|
+
return {
|
|
892
|
+
code: styleContent,
|
|
893
|
+
map: null
|
|
894
|
+
};
|
|
895
|
+
}
|
|
738
896
|
if (compiled?.css) return resolveCssImports(compiled.css, realPath, cssAliasRules, server !== null, currentBase);
|
|
739
897
|
return "";
|
|
740
898
|
}
|
|
899
|
+
if (id.startsWith("\0") && id.endsWith("?macro=true")) {
|
|
900
|
+
const realPath = id.slice(1).replace("?macro=true", "");
|
|
901
|
+
if (fs.existsSync(realPath)) {
|
|
902
|
+
const source = fs.readFileSync(realPath, "utf-8");
|
|
903
|
+
const setupMatch = source.match(/<script\s+setup[^>]*>([\s\S]*?)<\/script>/);
|
|
904
|
+
if (setupMatch) {
|
|
905
|
+
const scriptContent = setupMatch[1];
|
|
906
|
+
return {
|
|
907
|
+
code: `${scriptContent}\nexport default {}`,
|
|
908
|
+
map: null
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
return {
|
|
913
|
+
code: "export default {}",
|
|
914
|
+
map: null
|
|
915
|
+
};
|
|
916
|
+
}
|
|
741
917
|
if (isVizeVirtual(id)) {
|
|
742
918
|
const realPath = fromVirtualId(id);
|
|
743
919
|
if (!realPath.endsWith(".vue")) {
|
|
@@ -753,14 +929,22 @@ function vize(options = {}) {
|
|
|
753
929
|
});
|
|
754
930
|
}
|
|
755
931
|
if (compiled) {
|
|
756
|
-
|
|
932
|
+
const hasDelegated = compiled.styles?.some((s) => s.lang !== null && [
|
|
933
|
+
"scss",
|
|
934
|
+
"sass",
|
|
935
|
+
"less",
|
|
936
|
+
"stylus",
|
|
937
|
+
"styl"
|
|
938
|
+
].includes(s.lang) || s.module !== false);
|
|
939
|
+
if (compiled.css && !hasDelegated) compiled = {
|
|
757
940
|
...compiled,
|
|
758
941
|
css: resolveCssImports(compiled.css, realPath, cssAliasRules, server !== null, currentBase)
|
|
759
942
|
};
|
|
760
943
|
const output = rewriteStaticAssetUrls(rewriteDynamicTemplateImports(generateOutput(compiled, {
|
|
761
944
|
isProduction,
|
|
762
945
|
isDev: server !== null,
|
|
763
|
-
extractCss
|
|
946
|
+
extractCss,
|
|
947
|
+
filePath: realPath
|
|
764
948
|
}), dynamicImportAliasRules), dynamicImportAliasRules);
|
|
765
949
|
return {
|
|
766
950
|
code: output,
|
|
@@ -783,8 +967,9 @@ function vize(options = {}) {
|
|
|
783
967
|
return null;
|
|
784
968
|
},
|
|
785
969
|
async transform(code, id, options$1) {
|
|
786
|
-
|
|
787
|
-
|
|
970
|
+
const isMacro = id.startsWith("\0") && id.endsWith("?macro=true");
|
|
971
|
+
if (isVizeVirtual(id) || isMacro) {
|
|
972
|
+
const realPath = isMacro ? id.slice(1).replace("?macro=true", "") : fromVirtualId(id);
|
|
788
973
|
try {
|
|
789
974
|
const result = await transformWithOxc(code, realPath, { lang: "ts" });
|
|
790
975
|
const defines = options$1?.ssr ? serverViteDefine : clientViteDefine;
|
|
@@ -821,7 +1006,31 @@ function vize(options = {}) {
|
|
|
821
1006
|
logger.log(`Re-compiled: ${path.relative(root, file)} (${updateType})`);
|
|
822
1007
|
const virtualId = toVirtualId(file);
|
|
823
1008
|
const modules = server$1.moduleGraph.getModulesByFile(virtualId) ?? server$1.moduleGraph.getModulesByFile(file);
|
|
824
|
-
|
|
1009
|
+
const hasDelegated = newCompiled.styles?.some((s) => s.lang !== null && [
|
|
1010
|
+
"scss",
|
|
1011
|
+
"sass",
|
|
1012
|
+
"less",
|
|
1013
|
+
"stylus",
|
|
1014
|
+
"styl"
|
|
1015
|
+
].includes(s.lang) || s.module !== false);
|
|
1016
|
+
if (hasDelegated && updateType === "style-only") {
|
|
1017
|
+
const affectedModules = new Set();
|
|
1018
|
+
for (const block of newCompiled.styles ?? []) {
|
|
1019
|
+
const params = new URLSearchParams();
|
|
1020
|
+
params.set("vue", "");
|
|
1021
|
+
params.set("type", "style");
|
|
1022
|
+
params.set("index", String(block.index));
|
|
1023
|
+
if (block.scoped) params.set("scoped", `data-v-${newCompiled.scopeId}`);
|
|
1024
|
+
params.set("lang", block.lang ?? "css");
|
|
1025
|
+
if (block.module !== false) params.set("module", typeof block.module === "string" ? block.module : "");
|
|
1026
|
+
const styleId = `${file}?${params.toString()}`;
|
|
1027
|
+
const styleMods = server$1.moduleGraph.getModulesByFile(styleId);
|
|
1028
|
+
if (styleMods) for (const mod of styleMods) affectedModules.add(mod);
|
|
1029
|
+
}
|
|
1030
|
+
if (modules) for (const mod of modules) affectedModules.add(mod);
|
|
1031
|
+
if (affectedModules.size > 0) return [...affectedModules];
|
|
1032
|
+
}
|
|
1033
|
+
if (updateType === "style-only" && newCompiled.css && !hasDelegated) {
|
|
825
1034
|
server$1.ws.send({
|
|
826
1035
|
type: "custom",
|
|
827
1036
|
event: "vize:update",
|
|
@@ -875,7 +1084,43 @@ function vize(options = {}) {
|
|
|
875
1084
|
};
|
|
876
1085
|
} }
|
|
877
1086
|
};
|
|
878
|
-
|
|
1087
|
+
const postTransformPlugin = {
|
|
1088
|
+
name: "vize:post-transform",
|
|
1089
|
+
enforce: "post",
|
|
1090
|
+
async transform(code, id, transformOptions) {
|
|
1091
|
+
if (!id.endsWith(".vue") && !id.endsWith(".vue.ts") && !id.includes("node_modules") && id.endsWith(".setup.ts") && /<script\s+setup[\s>]/.test(code)) {
|
|
1092
|
+
logger.log(`post-transform: compiling virtual SFC content from ${id}`);
|
|
1093
|
+
try {
|
|
1094
|
+
const compiled = compileFile(id, cache, {
|
|
1095
|
+
sourceMap: mergedOptions?.sourceMap ?? !(isProduction ?? false),
|
|
1096
|
+
ssr: mergedOptions?.ssr ?? false
|
|
1097
|
+
}, code);
|
|
1098
|
+
const output = generateOutput(compiled, {
|
|
1099
|
+
isProduction,
|
|
1100
|
+
isDev: server !== null,
|
|
1101
|
+
extractCss,
|
|
1102
|
+
filePath: id
|
|
1103
|
+
});
|
|
1104
|
+
const result = await transformWithOxc(output, id, { lang: "ts" });
|
|
1105
|
+
const defines = transformOptions?.ssr ? serverViteDefine : clientViteDefine;
|
|
1106
|
+
let transformed = result.code;
|
|
1107
|
+
if (Object.keys(defines).length > 0) transformed = applyDefineReplacements(transformed, defines);
|
|
1108
|
+
return {
|
|
1109
|
+
code: transformed,
|
|
1110
|
+
map: result.map
|
|
1111
|
+
};
|
|
1112
|
+
} catch (e) {
|
|
1113
|
+
logger.error(`Virtual SFC compilation failed for ${id}:`, e);
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
return null;
|
|
1117
|
+
}
|
|
1118
|
+
};
|
|
1119
|
+
return [
|
|
1120
|
+
vueCompatPlugin,
|
|
1121
|
+
mainPlugin,
|
|
1122
|
+
postTransformPlugin
|
|
1123
|
+
];
|
|
879
1124
|
}
|
|
880
1125
|
var src_default = vize;
|
|
881
1126
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vizejs/vite-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "High-performance native Vite plugin for Vue SFC compilation powered by Vize",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"tinyglobby": "^0.2.0",
|
|
46
|
-
"@vizejs/native": "0.
|
|
46
|
+
"@vizejs/native": "0.10.0"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "tsdown",
|