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