@vizejs/unplugin 0.58.0 → 0.59.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.
@@ -0,0 +1,7 @@
1
+ import { t as VizeUnpluginOptions } from "./types-B9p6RbVJ.mjs";
2
+ import * as _$unplugin from "unplugin";
3
+
4
+ //#region src/esbuild.d.ts
5
+ declare const _default: (options?: VizeUnpluginOptions | undefined) => _$unplugin.EsbuildPlugin;
6
+ //#endregion
7
+ export { _default as default };
@@ -0,0 +1,5 @@
1
+ import { t as vizeUnplugin } from "./unplugin-DdRfNL4n.mjs";
2
+ //#region src/esbuild.ts
3
+ var esbuild_default = vizeUnplugin.esbuild;
4
+ //#endregion
5
+ export { esbuild_default as default };
@@ -0,0 +1,7 @@
1
+ import { t as VizeUnpluginOptions } from "./types-B9p6RbVJ.mjs";
2
+ import * as _$unplugin from "unplugin";
3
+
4
+ //#region src/unplugin.d.ts
5
+ declare const vizeUnplugin: _$unplugin.UnpluginInstance<VizeUnpluginOptions | undefined, boolean>;
6
+ //#endregion
7
+ export { type VizeUnpluginOptions, vizeUnplugin as default, vizeUnplugin };
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { t as vizeUnplugin } from "./unplugin-DdRfNL4n.mjs";
2
+ export { vizeUnplugin as default, vizeUnplugin };
@@ -0,0 +1,7 @@
1
+ import { t as VizeUnpluginOptions } from "./types-B9p6RbVJ.mjs";
2
+ import * as _$unplugin from "unplugin";
3
+
4
+ //#region src/rollup.d.ts
5
+ declare const _default: (options?: VizeUnpluginOptions | undefined) => _$unplugin.RollupPlugin<any> | _$unplugin.RollupPlugin<any>[];
6
+ //#endregion
7
+ export { _default as default };
@@ -0,0 +1,5 @@
1
+ import { t as vizeUnplugin } from "./unplugin-DdRfNL4n.mjs";
2
+ //#region src/rollup.ts
3
+ var rollup_default = vizeUnplugin.rollup;
4
+ //#endregion
5
+ export { rollup_default as default };
@@ -0,0 +1,13 @@
1
+ //#region src/types.d.ts
2
+ interface VizeUnpluginOptions {
3
+ include?: string | RegExp | Array<string | RegExp>;
4
+ exclude?: string | RegExp | Array<string | RegExp>;
5
+ isProduction?: boolean;
6
+ ssr?: boolean;
7
+ sourceMap?: boolean;
8
+ vapor?: boolean;
9
+ root?: string;
10
+ debug?: boolean;
11
+ }
12
+ //#endregion
13
+ export { VizeUnpluginOptions as t };
@@ -0,0 +1,380 @@
1
+ import fs from "node:fs";
2
+ import { createUnplugin } from "unplugin";
3
+ import { createHash } from "node:crypto";
4
+ import * as native from "@vizejs/native";
5
+ import path from "node:path";
6
+ import { transform } from "oxc-transform";
7
+ //#region src/filter.ts
8
+ function createFilter(include, exclude) {
9
+ const includePatterns = include ? Array.isArray(include) ? include : [include] : [/\.vue$/];
10
+ const excludePatterns = exclude ? Array.isArray(exclude) ? exclude : [exclude] : [/node_modules/];
11
+ return (id) => {
12
+ const matchInclude = includePatterns.some((pattern) => typeof pattern === "string" ? id.includes(pattern) : pattern.test(id));
13
+ const matchExclude = excludePatterns.some((pattern) => typeof pattern === "string" ? id.includes(pattern) : pattern.test(id));
14
+ return matchInclude && !matchExclude;
15
+ };
16
+ }
17
+ //#endregion
18
+ //#region src/style.ts
19
+ const PREPROCESSOR_LANGS = new Set([
20
+ "scss",
21
+ "sass",
22
+ "less",
23
+ "stylus",
24
+ "styl"
25
+ ]);
26
+ function needsPreprocessor(block) {
27
+ return block.lang !== null && PREPROCESSOR_LANGS.has(block.lang);
28
+ }
29
+ function isCssModule(block) {
30
+ return block.module !== false;
31
+ }
32
+ function hasDelegatedStyles(compiled) {
33
+ return compiled.styles.some((style) => needsPreprocessor(style) || isCssModule(style));
34
+ }
35
+ function generateScopeId(filename, root, isProduction, source) {
36
+ const relative = path.relative(root, filename).replace(/^(\.\.[/\\])+/, "").replace(/\\/g, "/");
37
+ const input = isProduction ? `${relative}\n${source.replace(/\r\n/g, "\n")}` : relative;
38
+ return createHash("sha256").update(input).digest("hex").slice(0, 8);
39
+ }
40
+ function extractStyleBlocks(source) {
41
+ const blocks = [];
42
+ const styleRegex = /<style([^>]*)>([\s\S]*?)<\/style>/gi;
43
+ let match = null;
44
+ let index = 0;
45
+ while ((match = styleRegex.exec(source)) !== null) {
46
+ const attrs = match[1];
47
+ const content = match[2];
48
+ const src = attrs.match(/\bsrc=["']([^"']+)["']/)?.[1] ?? null;
49
+ const lang = attrs.match(/\blang=["']([^"']+)["']/)?.[1] ?? null;
50
+ const scoped = /\bscoped\b/.test(attrs);
51
+ const moduleMatch = attrs.match(/\bmodule(?:=["']([^"']+)["'])?/);
52
+ const moduleValue = moduleMatch ? moduleMatch[1] || true : false;
53
+ blocks.push({
54
+ content,
55
+ src,
56
+ lang,
57
+ scoped,
58
+ module: moduleValue,
59
+ index
60
+ });
61
+ index++;
62
+ }
63
+ return blocks;
64
+ }
65
+ function supportsTemplateOnlyHmr(output) {
66
+ return /(?:^|\n)(?:_sfc_main|__sfc__)\.render\s*=\s*render\b/m.test(output);
67
+ }
68
+ function generateOutput(compiled, options) {
69
+ const { isProduction, isDev, extractCss, filePath } = options;
70
+ let output = compiled.code;
71
+ const exportDefaultRegex = /^export default /m;
72
+ const hasExportDefault = exportDefaultRegex.test(output);
73
+ const hasNamedRenderExport = /^export function render\b/m.test(output);
74
+ const hasSfcMainDefined = /\bconst\s+_sfc_main\s*=/.test(output);
75
+ if (hasExportDefault && !hasSfcMainDefined) {
76
+ output = output.replace(exportDefaultRegex, "const _sfc_main = ");
77
+ if (compiled.hasScoped) output += `\n_sfc_main.__scopeId = "data-v-${compiled.scopeId}";`;
78
+ output += "\nexport default _sfc_main;";
79
+ } else if (hasExportDefault && hasSfcMainDefined && compiled.hasScoped) output = output.replace(/^export default _sfc_main/m, `_sfc_main.__scopeId = "data-v-${compiled.scopeId}";\nexport default _sfc_main`);
80
+ else if (!hasExportDefault && !hasSfcMainDefined && hasNamedRenderExport) {
81
+ output += "\nconst _sfc_main = {};";
82
+ if (compiled.hasScoped) output += `\n_sfc_main.__scopeId = "data-v-${compiled.scopeId}";`;
83
+ output += "\n_sfc_main.render = render;";
84
+ output += "\nexport default _sfc_main;";
85
+ }
86
+ if (hasDelegatedStyles(compiled) && filePath) {
87
+ const styleImports = [];
88
+ const cssModuleImports = [];
89
+ for (const block of compiled.styles) {
90
+ const lang = block.lang ?? "css";
91
+ const params = new URLSearchParams();
92
+ params.set("vue", "");
93
+ params.set("type", "style");
94
+ params.set("index", String(block.index));
95
+ params.set("lang", lang);
96
+ if (block.scoped) params.set("scoped", `data-v-${compiled.scopeId}`);
97
+ const importUrl = `${filePath}?${params.toString()}`;
98
+ if (isCssModule(block)) {
99
+ const bindingName = typeof block.module === "string" ? block.module : "$style";
100
+ const moduleParams = new URLSearchParams(params);
101
+ moduleParams.set("module", typeof block.module === "string" ? block.module : "");
102
+ cssModuleImports.push(`import ${bindingName} from ${JSON.stringify(`${filePath}?${moduleParams.toString()}`)};`);
103
+ } else styleImports.push(`import ${JSON.stringify(importUrl)};`);
104
+ }
105
+ const allImports = [...styleImports, ...cssModuleImports].join("\n");
106
+ if (allImports) output = `${allImports}\n${output}`;
107
+ if (cssModuleImports.length > 0) {
108
+ const cssModuleSetup = compiled.styles.filter((block) => isCssModule(block)).map((block) => {
109
+ const bindingName = typeof block.module === "string" ? block.module : "$style";
110
+ return `_sfc_main.__cssModules = _sfc_main.__cssModules || {};\n_sfc_main.__cssModules[${JSON.stringify(bindingName)}] = ${bindingName};`;
111
+ }).join("\n");
112
+ output = output.replace(/^export default _sfc_main;/m, `${cssModuleSetup}\nexport default _sfc_main;`);
113
+ }
114
+ } else if (compiled.css && !(isProduction && extractCss)) output = `
115
+ export const __vize_css__ = ${JSON.stringify(compiled.css)};
116
+ const __vize_css_id__ = ${JSON.stringify(`vize-style-${compiled.scopeId}`)};
117
+ (function() {
118
+ if (typeof document !== "undefined") {
119
+ let style = document.getElementById(__vize_css_id__);
120
+ if (!style) {
121
+ style = document.createElement("style");
122
+ style.id = __vize_css_id__;
123
+ style.textContent = __vize_css__;
124
+ document.head.appendChild(style);
125
+ } else {
126
+ style.textContent = __vize_css__;
127
+ }
128
+ }
129
+ })();
130
+ ${output}`;
131
+ if (!isProduction && isDev && hasExportDefault && supportsTemplateOnlyHmr(output)) output += "";
132
+ return output;
133
+ }
134
+ function wrapScopedPreprocessorStyle(content, scoped, lang) {
135
+ if (!scoped || !lang || lang === "css") return content;
136
+ const lines = content.split("\n");
137
+ const hoisted = [];
138
+ const body = [];
139
+ for (const line of lines) {
140
+ const trimmed = line.trimStart();
141
+ if (trimmed.startsWith("@use ") || trimmed.startsWith("@forward ") || trimmed.startsWith("@import ")) {
142
+ hoisted.push(line);
143
+ continue;
144
+ }
145
+ body.push(line);
146
+ }
147
+ return `${hoisted.length > 0 ? `${hoisted.join("\n")}\n\n` : ""}[${scoped}] {\n${body.join("\n")}\n}`;
148
+ }
149
+ //#endregion
150
+ //#region src/compiler.ts
151
+ const { compileSfc } = native;
152
+ function buildSignature(options) {
153
+ return [
154
+ options.isProduction ? "1" : "0",
155
+ options.ssr ? "1" : "0",
156
+ options.vapor ? "1" : "0",
157
+ options.sourceMap ? "1" : "0",
158
+ options.root
159
+ ].join(":");
160
+ }
161
+ function buildSourceHash(source) {
162
+ return createHash("sha256").update(source).digest("hex");
163
+ }
164
+ function compileVueModule(filePath, source, options, cache) {
165
+ const sourceHash = buildSourceHash(source);
166
+ const signature = buildSignature(options);
167
+ const cached = cache.get(filePath);
168
+ if (cached && cached.sourceHash === sourceHash && cached.signature === signature) return {
169
+ compiled: cached.compiled,
170
+ warnings: []
171
+ };
172
+ const scopeId = generateScopeId(filePath, options.root, options.isProduction, source);
173
+ const hasScoped = /<style[^>]*\bscoped\b/.test(source);
174
+ const result = compileSfc(source, {
175
+ filename: filePath,
176
+ sourceMap: options.sourceMap,
177
+ ssr: options.ssr,
178
+ vapor: options.vapor,
179
+ scopeId: hasScoped ? `data-v-${scopeId}` : void 0
180
+ });
181
+ if (result.errors.length > 0) throw new Error(result.errors.join("\n"));
182
+ const compiled = {
183
+ code: result.code,
184
+ css: result.css,
185
+ scopeId,
186
+ hasScoped,
187
+ templateHash: result.templateHash,
188
+ styleHash: result.styleHash,
189
+ scriptHash: result.scriptHash,
190
+ styles: extractStyleBlocks(source)
191
+ };
192
+ cache.set(filePath, {
193
+ compiled,
194
+ sourceHash,
195
+ signature
196
+ });
197
+ return {
198
+ compiled,
199
+ warnings: result.warnings
200
+ };
201
+ }
202
+ //#endregion
203
+ //#region src/request.ts
204
+ const STYLE_MARKER = ".__vize_style_";
205
+ function isVueFile(id) {
206
+ return id.endsWith(".vue");
207
+ }
208
+ function isVueStyleRequest(id) {
209
+ const { query } = parseVueRequest(id);
210
+ return query.vue && query.type === "style";
211
+ }
212
+ function isVirtualStyleId(id) {
213
+ return id.includes(STYLE_MARKER);
214
+ }
215
+ function parseVueRequest(id) {
216
+ const [path, rawQuery = ""] = id.split("?", 2);
217
+ const params = new URLSearchParams(rawQuery);
218
+ const filename = params.get("vize-file") ?? path;
219
+ const moduleValue = params.has("module") ? params.get("module") || true : false;
220
+ const indexValue = params.get("index");
221
+ return {
222
+ filename,
223
+ path,
224
+ query: {
225
+ vue: params.has("vue"),
226
+ type: params.get("type"),
227
+ index: indexValue === null ? null : Number.parseInt(indexValue, 10),
228
+ lang: params.get("lang"),
229
+ module: moduleValue,
230
+ scoped: params.get("scoped"),
231
+ vizeFile: params.get("vize-file")
232
+ }
233
+ };
234
+ }
235
+ function createVirtualStyleId(id) {
236
+ const { filename, query } = parseVueRequest(id);
237
+ const index = query.index ?? 0;
238
+ const lang = query.lang ?? "css";
239
+ const suffix = query.module !== false ? `.module.${lang}` : `.${lang}`;
240
+ const params = new URLSearchParams();
241
+ params.set("vue", "");
242
+ params.set("type", "style");
243
+ params.set("index", String(index));
244
+ params.set("lang", lang);
245
+ params.set("vize-file", filename);
246
+ if (query.scoped) params.set("scoped", query.scoped);
247
+ if (query.module !== false) params.set("module", typeof query.module === "string" ? query.module : "");
248
+ return `${filename}${STYLE_MARKER}${index}${suffix}?${params.toString()}`;
249
+ }
250
+ //#endregion
251
+ //#region src/strip-types.ts
252
+ function formatErrorMessage(error) {
253
+ const parts = [error.message];
254
+ if (error.helpMessage) parts.push(error.helpMessage);
255
+ if (error.codeframe) parts.push(error.codeframe);
256
+ return parts.join("\n");
257
+ }
258
+ async function stripTypeScript(filePath, code, sourceMap) {
259
+ const result = transform(filePath, code, {
260
+ lang: "ts",
261
+ sourcemap: sourceMap,
262
+ sourceType: "module"
263
+ });
264
+ if (result.errors.length > 0) throw new Error(result.errors.map(formatErrorMessage).join("\n\n"));
265
+ return {
266
+ code: result.code,
267
+ map: result.map ?? null
268
+ };
269
+ }
270
+ //#endregion
271
+ //#region src/unplugin.ts
272
+ function normalizeOptions(rawOptions = {}) {
273
+ const isProduction = rawOptions.isProduction ?? process.env.NODE_ENV === "production";
274
+ return {
275
+ include: rawOptions.include,
276
+ exclude: rawOptions.exclude,
277
+ isProduction,
278
+ ssr: rawOptions.ssr ?? false,
279
+ sourceMap: rawOptions.sourceMap ?? !isProduction,
280
+ vapor: rawOptions.vapor ?? false,
281
+ root: rawOptions.root ?? process.cwd(),
282
+ debug: rawOptions.debug ?? false
283
+ };
284
+ }
285
+ function createVueDefineMap(isProduction) {
286
+ return {
287
+ __VUE_OPTIONS_API__: JSON.stringify(true),
288
+ __VUE_PROD_DEVTOOLS__: JSON.stringify(!isProduction),
289
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: JSON.stringify(!isProduction)
290
+ };
291
+ }
292
+ function injectWebpackVueDefines(compiler, isProduction) {
293
+ const { DefinePlugin } = compiler.webpack;
294
+ const existingDefines = /* @__PURE__ */ new Set();
295
+ for (const plugin of compiler.options.plugins ?? []) {
296
+ const definitions = plugin.definitions;
297
+ if (!definitions) continue;
298
+ for (const key of Object.keys(definitions)) existingDefines.add(key);
299
+ }
300
+ const definitions = createVueDefineMap(isProduction);
301
+ const missingDefinitions = {};
302
+ for (const [key, value] of Object.entries(definitions)) if (!existingDefines.has(key)) missingDefinitions[key] = value;
303
+ if (Object.keys(missingDefinitions).length > 0) new DefinePlugin(missingDefinitions).apply(compiler);
304
+ }
305
+ async function loadStyleBlock(id, options, cache) {
306
+ const request = parseVueRequest(id);
307
+ const index = request.query.index ?? -1;
308
+ if (index < 0) return "";
309
+ let compiled = cache.get(request.filename)?.compiled;
310
+ if (!compiled && fs.existsSync(request.filename)) {
311
+ const source = fs.readFileSync(request.filename, "utf8");
312
+ compiled = compileVueModule(request.filename, source, options, cache).compiled;
313
+ }
314
+ const block = compiled?.styles[index];
315
+ if (!block) return "";
316
+ return wrapScopedPreprocessorStyle(block.content, request.query.scoped, block.lang);
317
+ }
318
+ const vizeUnplugin = createUnplugin((rawOptions = {}) => {
319
+ const options = normalizeOptions(rawOptions);
320
+ const filter = createFilter(options.include, options.exclude);
321
+ const cache = /* @__PURE__ */ new Map();
322
+ return {
323
+ name: "unplugin-vize",
324
+ resolveId(id) {
325
+ if (isVueStyleRequest(id)) return createVirtualStyleId(id);
326
+ return null;
327
+ },
328
+ loadInclude(id) {
329
+ return isVirtualStyleId(id);
330
+ },
331
+ async load(id) {
332
+ if (!isVirtualStyleId(id)) return null;
333
+ return {
334
+ code: await loadStyleBlock(id, options, cache),
335
+ map: null
336
+ };
337
+ },
338
+ transformInclude(id) {
339
+ const request = parseVueRequest(id);
340
+ return !request.query.vue && isVueFile(request.filename) && filter(request.filename);
341
+ },
342
+ async transform(code, id) {
343
+ if (!isVueFile(id) || !filter(id)) return null;
344
+ const { compiled, warnings } = compileVueModule(id, code, options, cache);
345
+ for (const warning of warnings) this.warn(`[vize] ${warning}`);
346
+ const transformed = await stripTypeScript(id, generateOutput(compiled, {
347
+ isProduction: options.isProduction,
348
+ isDev: false,
349
+ filePath: id
350
+ }), options.sourceMap);
351
+ return {
352
+ code: transformed.code,
353
+ map: transformed.map
354
+ };
355
+ },
356
+ watchChange(id) {
357
+ if (isVueFile(id)) cache.delete(id);
358
+ },
359
+ webpack(compiler) {
360
+ injectWebpackVueDefines(compiler, options.isProduction);
361
+ },
362
+ esbuild: {
363
+ onResolveFilter: /\.vue(?:$|\?)/,
364
+ onLoadFilter: /\.vue(?:$|\?)/,
365
+ loader(_code, id) {
366
+ const request = parseVueRequest(id);
367
+ if (request.query.type === "style") return request.query.module !== false ? "local-css" : "css";
368
+ return "js";
369
+ },
370
+ config(buildOptions) {
371
+ buildOptions.define = {
372
+ ...createVueDefineMap(options.isProduction),
373
+ ...buildOptions.define
374
+ };
375
+ }
376
+ }
377
+ };
378
+ });
379
+ //#endregion
380
+ export { vizeUnplugin as t };
@@ -0,0 +1,6 @@
1
+ import { t as VizeUnpluginOptions } from "./types-B9p6RbVJ.mjs";
2
+
3
+ //#region src/webpack.d.ts
4
+ declare const _default: (options?: VizeUnpluginOptions | undefined) => undefined;
5
+ //#endregion
6
+ export { _default as default };
@@ -0,0 +1,5 @@
1
+ import { t as vizeUnplugin } from "./unplugin-DdRfNL4n.mjs";
2
+ //#region src/webpack.ts
3
+ var webpack_default = vizeUnplugin.webpack;
4
+ //#endregion
5
+ export { webpack_default as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vizejs/unplugin",
3
- "version": "0.58.0",
3
+ "version": "0.59.0",
4
4
  "description": "Experimental unplugin-based Vue SFC integration for rollup, webpack, and esbuild powered by Vize",
5
5
  "keywords": [
6
6
  "compiler",
@@ -51,7 +51,7 @@
51
51
  "access": "public"
52
52
  },
53
53
  "dependencies": {
54
- "@vizejs/native": "0.58.0",
54
+ "@vizejs/native": "0.59.0",
55
55
  "oxc-transform": "0.56.5",
56
56
  "unplugin": "3.0.0"
57
57
  },