@vizejs/rspack-plugin 0.33.0 → 0.35.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/README.md +229 -149
- package/dist/index-Bvwqw7T6.d.mts +138 -0
- package/dist/index.d.mts +74 -0
- package/dist/index.mjs +1 -0
- package/dist/{index-C1nbpj8i.d.ts → loader/index.d.mts} +4 -4
- package/dist/loader/index.mjs +1 -0
- package/dist/loader/scope-loader.d.mts +7 -0
- package/dist/loader/scope-loader.mjs +1 -0
- package/dist/loader/style-loader.d.mts +7 -0
- package/dist/loader/style-loader.mjs +1 -0
- package/dist/loader-CTDGCafa.mjs +24 -0
- package/dist/utils-B5WyWrfH.mjs +4 -0
- package/package.json +48 -44
- package/dist/index-Crp9t5G9.d.ts +0 -249
- package/dist/index.d.ts +0 -159
- package/dist/index.js +0 -1
- package/dist/loader/index.d.ts +0 -3
- package/dist/loader/index.js +0 -1
- package/dist/loader/style-loader.d.ts +0 -3
- package/dist/loader/style-loader.js +0 -1
- package/dist/loader-DyzGJOBD.js +0 -22
- package/dist/style-loader-DPvk-BhE.js +0 -1
- package/dist/style-loader-zO0F0c6t.d.ts +0 -7
- package/dist/utils-Cw44tFia.js +0 -3
package/README.md
CHANGED
|
@@ -29,15 +29,49 @@ pnpm add -D @vizejs/rspack-plugin @rspack/core
|
|
|
29
29
|
|
|
30
30
|
## Usage
|
|
31
31
|
|
|
32
|
-
###
|
|
32
|
+
### Simple Mode (Recommended)
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
If you don't call it, write rules manually.
|
|
34
|
+
Write a single `.vue` rule and your normal CSS rules. `VizePlugin` automatically clones your CSS rules for Vue style sub-requests.
|
|
36
35
|
|
|
37
36
|
```javascript
|
|
38
37
|
// rspack.config.mjs
|
|
39
|
-
import {
|
|
40
|
-
|
|
38
|
+
import { VizePlugin } from "@vizejs/rspack-plugin";
|
|
39
|
+
|
|
40
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
41
|
+
|
|
42
|
+
export default {
|
|
43
|
+
mode: isProduction ? "production" : "development",
|
|
44
|
+
|
|
45
|
+
experiments: {
|
|
46
|
+
css: true, // Enable Rspack native CSS
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
module: {
|
|
50
|
+
rules: [
|
|
51
|
+
{
|
|
52
|
+
test: /\.vue$/,
|
|
53
|
+
use: [{ loader: "@vizejs/rspack-plugin/loader" }],
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
plugins: [
|
|
59
|
+
new VizePlugin({
|
|
60
|
+
isProduction,
|
|
61
|
+
css: { native: true },
|
|
62
|
+
}),
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Native CSS with SCSS (Simple Mode)
|
|
68
|
+
|
|
69
|
+
Uses Rspack's built-in `experiments.css` for optimal performance. Just add your SCSS rule — VizePlugin handles the rest.
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
// rspack.config.mjs
|
|
73
|
+
import { VizePlugin } from "@vizejs/rspack-plugin";
|
|
74
|
+
import path from "node:path";
|
|
41
75
|
|
|
42
76
|
const isProduction = process.env.NODE_ENV === "production";
|
|
43
77
|
|
|
@@ -50,34 +84,36 @@ export default {
|
|
|
50
84
|
|
|
51
85
|
module: {
|
|
52
86
|
rules: [
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
},
|
|
63
|
-
}),
|
|
87
|
+
{
|
|
88
|
+
test: /\.scss$/,
|
|
89
|
+
type: "css/auto",
|
|
90
|
+
use: ["sass-loader"],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
test: /\.vue$/,
|
|
94
|
+
loader: "@vizejs/rspack-plugin/loader",
|
|
95
|
+
},
|
|
64
96
|
],
|
|
65
97
|
},
|
|
66
98
|
|
|
67
99
|
plugins: [
|
|
68
100
|
new VizePlugin({
|
|
69
101
|
isProduction,
|
|
70
|
-
include: [/src\/.*\.vue$/],
|
|
71
|
-
exclude: [/node_modules/],
|
|
72
102
|
css: { native: true },
|
|
73
103
|
}),
|
|
74
104
|
],
|
|
105
|
+
|
|
106
|
+
resolve: {
|
|
107
|
+
alias: {
|
|
108
|
+
"@": path.resolve(import.meta.dirname, "src"),
|
|
109
|
+
},
|
|
110
|
+
},
|
|
75
111
|
};
|
|
76
112
|
```
|
|
77
113
|
|
|
78
|
-
###
|
|
114
|
+
### CssExtractRspackPlugin (Simple Mode)
|
|
79
115
|
|
|
80
|
-
|
|
116
|
+
Compatible with webpack ecosystem, suitable for projects requiring PostCSS plugin chains.
|
|
81
117
|
|
|
82
118
|
```javascript
|
|
83
119
|
// rspack.config.mjs
|
|
@@ -90,7 +126,103 @@ const isProduction = process.env.NODE_ENV === "production";
|
|
|
90
126
|
export default {
|
|
91
127
|
mode: isProduction ? "production" : "development",
|
|
92
128
|
|
|
93
|
-
|
|
129
|
+
module: {
|
|
130
|
+
rules: [
|
|
131
|
+
{
|
|
132
|
+
test: /\.css$/,
|
|
133
|
+
type: "javascript/auto",
|
|
134
|
+
use: [isProduction ? rspack.CssExtractRspackPlugin.loader : "style-loader", "css-loader"],
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
test: /\.scss$/,
|
|
138
|
+
type: "javascript/auto",
|
|
139
|
+
use: [
|
|
140
|
+
isProduction ? rspack.CssExtractRspackPlugin.loader : "style-loader",
|
|
141
|
+
"css-loader",
|
|
142
|
+
"sass-loader",
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
{
|
|
147
|
+
test: /\.vue$/,
|
|
148
|
+
loader: "@vizejs/rspack-plugin/loader",
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
plugins: [
|
|
154
|
+
new VizePlugin({
|
|
155
|
+
isProduction,
|
|
156
|
+
}),
|
|
157
|
+
|
|
158
|
+
...(isProduction
|
|
159
|
+
? [
|
|
160
|
+
new rspack.CssExtractRspackPlugin({
|
|
161
|
+
filename: "styles/[name].[contenthash:8].css",
|
|
162
|
+
chunkFilename: "styles/[name].[contenthash:8].chunk.css",
|
|
163
|
+
}),
|
|
164
|
+
]
|
|
165
|
+
: []),
|
|
166
|
+
],
|
|
167
|
+
|
|
168
|
+
resolve: {
|
|
169
|
+
alias: {
|
|
170
|
+
"@": path.resolve(import.meta.dirname, "src"),
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Advanced: Manual `oneOf` Rules
|
|
177
|
+
|
|
178
|
+
`VizePlugin` will automatically:
|
|
179
|
+
|
|
180
|
+
1. Find the `.vue` rule containing the vize loader
|
|
181
|
+
2. Clone your CSS/SCSS/Less/Stylus rules for `?vue&type=style` sub-requests
|
|
182
|
+
3. Inject the vize scope-loader + style-loader at the end of each cloned chain
|
|
183
|
+
(execution order: style-loader extracts block → preprocessor compiles → scope-loader applies native scoped CSS)
|
|
184
|
+
4. Build `oneOf` branches inside the `.vue` rule
|
|
185
|
+
5. Add `resourceQuery: { not: [/vue/] }` to original CSS rules so they don't conflict
|
|
186
|
+
|
|
187
|
+
To opt out and write manual rules, set `autoRules: false`:
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
new VizePlugin({ autoRules: false });
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
If you need full control over the loader chain, set `autoRules: false` and write `oneOf` branches manually.
|
|
194
|
+
|
|
195
|
+
#### Request Routing: Main vs Style Sub-Requests
|
|
196
|
+
|
|
197
|
+
When writing manual rules, you must ensure the main `.vue` loader and the style loader see different requests.
|
|
198
|
+
|
|
199
|
+
The main loader produces `import './App.vue?vue&type=style&index=0&...'` statements. These style sub-requests must be routed through `@vizejs/rspack-plugin/scope-loader` and `@vizejs/rspack-plugin/style-loader` — **not** back into the main loader. If the main loader receives a `?type=style` query it will emit an explicit error.
|
|
200
|
+
|
|
201
|
+
Use `oneOf` to guarantee mutual exclusion:
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
{
|
|
205
|
+
test: /\.vue$/,
|
|
206
|
+
oneOf: [
|
|
207
|
+
{ resourceQuery: /type=style/, use: [/* style pipeline */] },
|
|
208
|
+
{ use: [/* main vize loader */] },
|
|
209
|
+
],
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
<details>
|
|
214
|
+
<summary>Native CSS with manual oneOf</summary>
|
|
215
|
+
|
|
216
|
+
```javascript
|
|
217
|
+
// rspack.config.mjs
|
|
218
|
+
import { VizePlugin } from "@vizejs/rspack-plugin";
|
|
219
|
+
import path from "node:path";
|
|
220
|
+
|
|
221
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
222
|
+
|
|
223
|
+
export default {
|
|
224
|
+
mode: isProduction ? "production" : "development",
|
|
225
|
+
|
|
94
226
|
experiments: {
|
|
95
227
|
css: true,
|
|
96
228
|
},
|
|
@@ -105,9 +237,8 @@ export default {
|
|
|
105
237
|
resourceQuery: /vue&type=style.*module/,
|
|
106
238
|
type: "css/module",
|
|
107
239
|
use: [
|
|
108
|
-
{
|
|
109
|
-
|
|
110
|
-
},
|
|
240
|
+
{ loader: "@vizejs/rspack-plugin/scope-loader" },
|
|
241
|
+
{ loader: "@vizejs/rspack-plugin/style-loader" },
|
|
111
242
|
],
|
|
112
243
|
},
|
|
113
244
|
|
|
@@ -116,10 +247,9 @@ export default {
|
|
|
116
247
|
resourceQuery: /vue&type=style.*lang=scss/,
|
|
117
248
|
type: "css/auto",
|
|
118
249
|
use: [
|
|
250
|
+
{ loader: "@vizejs/rspack-plugin/scope-loader" },
|
|
119
251
|
"sass-loader",
|
|
120
|
-
{
|
|
121
|
-
loader: "@vizejs/rspack-plugin/style-loader",
|
|
122
|
-
},
|
|
252
|
+
{ loader: "@vizejs/rspack-plugin/style-loader" },
|
|
123
253
|
],
|
|
124
254
|
},
|
|
125
255
|
|
|
@@ -128,9 +258,8 @@ export default {
|
|
|
128
258
|
resourceQuery: /vue&type=style/,
|
|
129
259
|
type: "css/auto",
|
|
130
260
|
use: [
|
|
131
|
-
{
|
|
132
|
-
|
|
133
|
-
},
|
|
261
|
+
{ loader: "@vizejs/rspack-plugin/scope-loader" },
|
|
262
|
+
{ loader: "@vizejs/rspack-plugin/style-loader" },
|
|
134
263
|
],
|
|
135
264
|
},
|
|
136
265
|
|
|
@@ -139,11 +268,6 @@ export default {
|
|
|
139
268
|
use: [
|
|
140
269
|
{
|
|
141
270
|
loader: "@vizejs/rspack-plugin/loader",
|
|
142
|
-
options: {
|
|
143
|
-
include: [/src\/.*\.vue$/],
|
|
144
|
-
exclude: [/node_modules/],
|
|
145
|
-
sourceMap: !isProduction,
|
|
146
|
-
},
|
|
147
271
|
},
|
|
148
272
|
],
|
|
149
273
|
},
|
|
@@ -155,11 +279,8 @@ export default {
|
|
|
155
279
|
plugins: [
|
|
156
280
|
new VizePlugin({
|
|
157
281
|
isProduction,
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
css: {
|
|
161
|
-
native: true,
|
|
162
|
-
},
|
|
282
|
+
autoRules: false,
|
|
283
|
+
css: { native: true },
|
|
163
284
|
}),
|
|
164
285
|
],
|
|
165
286
|
|
|
@@ -171,9 +292,10 @@ export default {
|
|
|
171
292
|
};
|
|
172
293
|
```
|
|
173
294
|
|
|
174
|
-
|
|
295
|
+
</details>
|
|
175
296
|
|
|
176
|
-
|
|
297
|
+
<details>
|
|
298
|
+
<summary>CssExtractRspackPlugin with manual oneOf</summary>
|
|
177
299
|
|
|
178
300
|
```javascript
|
|
179
301
|
// rspack.config.mjs
|
|
@@ -196,14 +318,11 @@ export default {
|
|
|
196
318
|
resourceQuery: /vue&type=style.*lang=scss/,
|
|
197
319
|
type: "javascript/auto",
|
|
198
320
|
use: [
|
|
199
|
-
isProduction
|
|
200
|
-
? rspack.CssExtractRspackPlugin.loader
|
|
201
|
-
: "style-loader",
|
|
321
|
+
isProduction ? rspack.CssExtractRspackPlugin.loader : "style-loader",
|
|
202
322
|
"css-loader",
|
|
323
|
+
{ loader: "@vizejs/rspack-plugin/scope-loader" },
|
|
203
324
|
"sass-loader",
|
|
204
|
-
{
|
|
205
|
-
loader: "@vizejs/rspack-plugin/style-loader",
|
|
206
|
-
},
|
|
325
|
+
{ loader: "@vizejs/rspack-plugin/style-loader" },
|
|
207
326
|
],
|
|
208
327
|
},
|
|
209
328
|
|
|
@@ -212,22 +331,18 @@ export default {
|
|
|
212
331
|
resourceQuery: /vue&type=style/,
|
|
213
332
|
type: "javascript/auto",
|
|
214
333
|
use: [
|
|
215
|
-
isProduction
|
|
216
|
-
? rspack.CssExtractRspackPlugin.loader
|
|
217
|
-
: "style-loader",
|
|
334
|
+
isProduction ? rspack.CssExtractRspackPlugin.loader : "style-loader",
|
|
218
335
|
{
|
|
219
336
|
loader: "css-loader",
|
|
220
337
|
options: {
|
|
221
338
|
modules: {
|
|
222
339
|
auto: (_resourcePath, resourceQuery) =>
|
|
223
|
-
typeof resourceQuery === "string" &&
|
|
224
|
-
resourceQuery.includes("module="),
|
|
340
|
+
typeof resourceQuery === "string" && resourceQuery.includes("module="),
|
|
225
341
|
},
|
|
226
342
|
},
|
|
227
343
|
},
|
|
228
|
-
{
|
|
229
|
-
|
|
230
|
-
},
|
|
344
|
+
{ loader: "@vizejs/rspack-plugin/scope-loader" },
|
|
345
|
+
{ loader: "@vizejs/rspack-plugin/style-loader" },
|
|
231
346
|
],
|
|
232
347
|
},
|
|
233
348
|
|
|
@@ -236,11 +351,6 @@ export default {
|
|
|
236
351
|
use: [
|
|
237
352
|
{
|
|
238
353
|
loader: "@vizejs/rspack-plugin/loader",
|
|
239
|
-
options: {
|
|
240
|
-
include: [/src\/.*\.vue$/],
|
|
241
|
-
exclude: [/node_modules/],
|
|
242
|
-
sourceMap: !isProduction,
|
|
243
|
-
},
|
|
244
354
|
},
|
|
245
355
|
],
|
|
246
356
|
},
|
|
@@ -251,10 +361,7 @@ export default {
|
|
|
251
361
|
{
|
|
252
362
|
test: /\.css$/,
|
|
253
363
|
type: "javascript/auto",
|
|
254
|
-
use: [
|
|
255
|
-
isProduction ? rspack.CssExtractRspackPlugin.loader : "style-loader",
|
|
256
|
-
"css-loader",
|
|
257
|
-
],
|
|
364
|
+
use: [isProduction ? rspack.CssExtractRspackPlugin.loader : "style-loader", "css-loader"],
|
|
258
365
|
},
|
|
259
366
|
|
|
260
367
|
// Regular SCSS files (non-Vue)
|
|
@@ -273,11 +380,9 @@ export default {
|
|
|
273
380
|
plugins: [
|
|
274
381
|
new VizePlugin({
|
|
275
382
|
isProduction,
|
|
276
|
-
|
|
277
|
-
exclude: [/node_modules/],
|
|
383
|
+
autoRules: false,
|
|
278
384
|
}),
|
|
279
385
|
|
|
280
|
-
// CSS extraction (production only)
|
|
281
386
|
...(isProduction
|
|
282
387
|
? [
|
|
283
388
|
new rspack.CssExtractRspackPlugin({
|
|
@@ -296,6 +401,8 @@ export default {
|
|
|
296
401
|
};
|
|
297
402
|
```
|
|
298
403
|
|
|
404
|
+
</details>
|
|
405
|
+
|
|
299
406
|
## API
|
|
300
407
|
|
|
301
408
|
### VizePlugin
|
|
@@ -309,13 +416,14 @@ new VizePlugin({
|
|
|
309
416
|
exclude: string | RegExp | (string | RegExp)[]; // Exclude watched .vue files
|
|
310
417
|
ssr: boolean; // Enable SSR mode (default: false)
|
|
311
418
|
sourceMap: boolean; // Enable source maps (default: true in dev)
|
|
312
|
-
vapor: boolean; // Enable Vapor mode (default: false
|
|
419
|
+
vapor: boolean; // Enable Vapor mode (default: false)
|
|
313
420
|
root: string; // Root directory (default: Rspack's root)
|
|
314
421
|
css: {
|
|
315
422
|
native: boolean; // Use experiments.css (default: false), warns if config mismatch
|
|
316
423
|
};
|
|
317
424
|
compilerOptions: {}; // Extra @vizejs/native compileSfc options
|
|
318
425
|
debug: boolean; // Enable debug logging (default: false)
|
|
426
|
+
autoRules: boolean; // Auto-clone CSS rules for Vue style sub-requests (default: true)
|
|
319
427
|
});
|
|
320
428
|
// Debug logging uses Rspack's infrastructure logger.
|
|
321
429
|
// Control verbosity via `infrastructureLogging.level` in your rspack config.
|
|
@@ -332,13 +440,16 @@ new VizePlugin({
|
|
|
332
440
|
exclude: string | RegExp | (string | RegExp)[]; // Safe compile denylist
|
|
333
441
|
sourceMap: boolean; // Enable source maps (default: true)
|
|
334
442
|
ssr: boolean; // Enable SSR mode (default: false)
|
|
443
|
+
vapor: boolean; // Enable Vapor mode (default: false)
|
|
335
444
|
customElement: boolean | RegExp; // Custom element mode (default: /\.ce\.vue$/)
|
|
336
445
|
hotReload: boolean; // Enable HMR (default: true in dev, false in prod/SSR)
|
|
446
|
+
transformAssetUrls: boolean | Record<string, string[]>; // See below (default: true)
|
|
337
447
|
compilerOptions: { // Extra @vizejs/native compileSfc options
|
|
338
448
|
filename?: string;
|
|
339
449
|
sourceMap?: boolean;
|
|
340
450
|
ssr?: boolean;
|
|
341
451
|
isTs?: boolean; // Preserve TypeScript (auto-detected from <script lang="ts">)
|
|
452
|
+
vapor?: boolean; // Enable Vapor mode compilation
|
|
342
453
|
scopeId?: string;
|
|
343
454
|
};
|
|
344
455
|
};
|
|
@@ -350,6 +461,46 @@ This avoids hard failures while still alerting you to mismatched rule/filter con
|
|
|
350
461
|
|
|
351
462
|
Compilation errors cause the loader to fail immediately (`callback(error)`) instead of returning broken code.
|
|
352
463
|
|
|
464
|
+
#### TypeScript
|
|
465
|
+
|
|
466
|
+
`@vizejs/native compileSfc` preserves TypeScript syntax in its output (same behavior as `@vue/compiler-sfc`). A downstream transpiler is needed to strip type annotations:
|
|
467
|
+
|
|
468
|
+
- **Recommended**: Add a `builtin:swc-loader` post-processing rule for `.vue` files
|
|
469
|
+
- **Custom loader**: Use `esbuild-loader` or any other TS transpiler
|
|
470
|
+
- **Manual**: Add your own `enforce: "post"` rule for `.vue` files (exclude `type=style` requests)
|
|
471
|
+
|
|
472
|
+
The `isTs` option is auto-detected from `<script lang="ts">` and passed to the native compiler for correct parsing.
|
|
473
|
+
|
|
474
|
+
#### `transformAssetUrls`
|
|
475
|
+
|
|
476
|
+
Static asset URLs in template element attributes (e.g. `<img src="./logo.png">`) are automatically rewritten into JavaScript `import` bindings so that Rspack can process them through its asset pipeline.
|
|
477
|
+
|
|
478
|
+
| Value | Behaviour |
|
|
479
|
+
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
480
|
+
| `true` (default) | Apply built-in transforms: `img[src]`, `video[src,poster]`, `source[src]`, `image[xlink:href,href]`, `use[xlink:href,href]` |
|
|
481
|
+
| `false` | Disable the feature entirely — URL strings are left as-is |
|
|
482
|
+
| `Record<string, string[]>` | Custom element/attribute mapping that **replaces** the built-in defaults |
|
|
483
|
+
|
|
484
|
+
Only relative (`./`, `../`), alias (`@/`), and tilde (`~/`, `~pkg`) URLs are transformed. External (`https://…`), protocol-relative (`//…`), and data URIs are left unchanged.
|
|
485
|
+
|
|
486
|
+
```js
|
|
487
|
+
// Custom mapping example
|
|
488
|
+
{
|
|
489
|
+
loader: "@vizejs/rspack-plugin/loader",
|
|
490
|
+
options: {
|
|
491
|
+
transformAssetUrls: {
|
|
492
|
+
"my-image": ["data-src"],
|
|
493
|
+
img: ["src"],
|
|
494
|
+
},
|
|
495
|
+
},
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
> **Known limitations**
|
|
500
|
+
>
|
|
501
|
+
> - URL rewriting operates via string replacement on the compiled JS output, not on AST nodes. If a `<script>` block contains an identical string literal it will also be replaced (extremely unlikely in practice).
|
|
502
|
+
> - URLs with hash fragments (e.g. `./icons.svg#home`) are split: the base path becomes the `import` specifier and the fragment is concatenated at runtime.
|
|
503
|
+
|
|
353
504
|
### VizeStyleLoader
|
|
354
505
|
|
|
355
506
|
```typescript
|
|
@@ -362,90 +513,19 @@ Compilation errors cause the loader to fail immediately (`callback(error)`) inst
|
|
|
362
513
|
}
|
|
363
514
|
```
|
|
364
515
|
|
|
365
|
-
###
|
|
516
|
+
### VizeScopeLoader
|
|
517
|
+
|
|
518
|
+
Applies native scoped CSS transformation using `@vizejs/native compileCss`. Runs **after** preprocessors (SCSS/Less/Stylus → CSS) and **before** css-loader or `experiments.css`.
|
|
366
519
|
|
|
367
520
|
```typescript
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
styleLanguages: ["scss", "sass", "less", "stylus", "styl"],
|
|
374
|
-
styleInjectLoader: "style-loader",
|
|
375
|
-
styleExtractLoader: undefined, // e.g. rspack.CssExtractRspackPlugin.loader
|
|
376
|
-
cssLoader: "css-loader",
|
|
377
|
-
loaderOptions: {
|
|
378
|
-
include: [/src\/.*\.vue$/],
|
|
379
|
-
exclude: [/node_modules/],
|
|
380
|
-
sourceMap: true,
|
|
381
|
-
},
|
|
382
|
-
styleLoaderOptions: {
|
|
383
|
-
native: true, // match nativeCss setting
|
|
384
|
-
},
|
|
385
|
-
typescript: true, // or a custom LoaderEntry
|
|
386
|
-
});
|
|
521
|
+
// In rspack.config.js
|
|
522
|
+
{
|
|
523
|
+
loader: "@vizejs/rspack-plugin/scope-loader",
|
|
524
|
+
// No options — scope metadata is extracted from the query string (?scoped=xxxxx)
|
|
525
|
+
}
|
|
387
526
|
```
|
|
388
527
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
| Feature | Native CSS (`experiments.css`) | CssExtractRspackPlugin |
|
|
392
|
-
| ------------------ | ------------------------------ | ---------------------- |
|
|
393
|
-
| **CSS Engine** | Rust (LightningCSS) | JS (css-loader) |
|
|
394
|
-
| **CSS Extraction** | Rspack automatic | CssExtractRspackPlugin |
|
|
395
|
-
| **CSS Modules** | `type: 'css/module'` | css-loader config |
|
|
396
|
-
| **HMR** | Rspack native | style-loader |
|
|
397
|
-
| **Vendor Prefix** | LightningCSS built-in | Requires autoprefixer |
|
|
398
|
-
| **Performance** | **Excellent** (Rust) | Good (JS) |
|
|
399
|
-
| **Use Case** | **New projects** | webpack compatibility |
|
|
400
|
-
|
|
401
|
-
## Known Limitations
|
|
402
|
-
|
|
403
|
-
### HMR
|
|
404
|
-
|
|
405
|
-
Script and template changes trigger a component-level hot reload via `module.hot.accept()` + `__VUE_HMR_RUNTIME__.reload()`. CSS Module changes trigger a targeted rerender without full reload. Plain `<style>` HMR is handled natively by Rspack's CSS pipeline.
|
|
406
|
-
|
|
407
|
-
### Path Resolution
|
|
408
|
-
|
|
409
|
-
Style imports injected by the main loader are normalized to resolver-friendly request paths.
|
|
410
|
-
In modern Rspack setups this avoids most absolute-path query edge cases, especially across platforms.
|
|
411
|
-
|
|
412
|
-
### Diagnostics
|
|
413
|
-
|
|
414
|
-
Compiler diagnostics are emitted via loader APIs:
|
|
415
|
-
|
|
416
|
-
- Compile errors: `callback(error)` — fails the build immediately
|
|
417
|
-
- Compile warnings: `this.emitWarning(...)`
|
|
418
|
-
- Missing `<style src>` files: build error (fail fast, no silent style loss)
|
|
419
|
-
- Scoped CSS fallback: warning emitted once per file (deduplicated in watch mode)
|
|
420
|
-
|
|
421
|
-
Scoped preprocessor blocks such as `<style scoped lang="scss">` are currently rejected.
|
|
422
|
-
The fallback transformer only understands plain CSS selectors, so allowing SCSS/Less/Stylus here would silently produce incorrect scoped output.
|
|
423
|
-
|
|
424
|
-
### Scoped CSS
|
|
425
|
-
|
|
426
|
-
Scoped CSS scope IDs are derived from the file's **relative path** (relative to Rspack's `rootContext`). In production builds, the file content is also mixed into the hash to prevent collisions across packages with identically-named files. This ensures consistent scope IDs across different machines for SSR hydration.
|
|
427
|
-
|
|
428
|
-
The current scoped CSS implementation uses a fallback regex transformer with the following limitations:
|
|
429
|
-
|
|
430
|
-
- ❌ No support for `:deep()`, `:global()`, `:slotted()` pseudo-classes
|
|
431
|
-
- ❌ No support for nested `@media` / `@supports` selectors
|
|
432
|
-
- ❌ May not handle CSS comments containing `{` or `,` correctly
|
|
433
|
-
|
|
434
|
-
**Recommendation**: This is an MVP implementation. For production-grade scoped CSS, consider waiting for native-side precise API support.
|
|
435
|
-
|
|
436
|
-
### Source Maps
|
|
437
|
-
|
|
438
|
-
The current `@vizejs/native` NAPI does not yet return a source map field. The type definition reserves a `map?: string` field for forward-compatibility. Once the Rust side implements source map output, the loader will pass it to Rspack automatically.
|
|
439
|
-
|
|
440
|
-
### TypeScript Output
|
|
441
|
-
|
|
442
|
-
`@vizejs/native compileSfc` preserves TypeScript syntax in its output (same behavior as `@vue/compiler-sfc`). A downstream transpiler is needed to strip type annotations:
|
|
443
|
-
|
|
444
|
-
- **Recommended**: Use `createVizeVueRules({ typescript: true })` to auto-add a `builtin:swc-loader` post-processing rule
|
|
445
|
-
- **Custom loader**: Pass a `LoaderEntry` — e.g. `typescript: "esbuild-loader"` or `typescript: { loader: "esbuild-loader", options: { ... } }`
|
|
446
|
-
- **Manual**: Add your own `enforce: "post"` rule for `.vue` files (exclude `type=style` requests)
|
|
447
|
-
|
|
448
|
-
The `isTs` option is auto-detected from `<script lang="ts">` and passed to the native compiler for correct parsing.
|
|
528
|
+
The scope-loader is automatically injected by `VizePlugin` when `autoRules: true` (default). Only needed in manual `oneOf` configurations.
|
|
449
529
|
|
|
450
530
|
## License
|
|
451
531
|
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
//#region src/types/index.d.ts
|
|
2
|
+
/** Type definitions for @vizejs/rspack-plugin. */
|
|
3
|
+
interface SfcCompileOptionsNapi {
|
|
4
|
+
filename?: string;
|
|
5
|
+
sourceMap?: boolean;
|
|
6
|
+
ssr?: boolean;
|
|
7
|
+
/** Enable Vapor mode compilation */
|
|
8
|
+
vapor?: boolean;
|
|
9
|
+
/** Preserve TypeScript in output when true */
|
|
10
|
+
isTs?: boolean;
|
|
11
|
+
/** Scope ID for scoped CSS (e.g., "data-v-abc123") */
|
|
12
|
+
scopeId?: string;
|
|
13
|
+
}
|
|
14
|
+
interface SfcCompileResultNapi {
|
|
15
|
+
code: string;
|
|
16
|
+
css?: string;
|
|
17
|
+
/** Source map JSON (when implemented) */
|
|
18
|
+
map?: string;
|
|
19
|
+
errors: string[];
|
|
20
|
+
warnings: string[];
|
|
21
|
+
}
|
|
22
|
+
interface StyleBlockInfo {
|
|
23
|
+
/** Raw style content */
|
|
24
|
+
content: string;
|
|
25
|
+
/** External source from `<style src="...">` */
|
|
26
|
+
src?: string | null;
|
|
27
|
+
/** Language of the style block (e.g., "css", "scss", "less", "sass", "stylus") */
|
|
28
|
+
lang: string | null;
|
|
29
|
+
/** Whether scoped */
|
|
30
|
+
scoped: boolean;
|
|
31
|
+
/** CSS Modules: true for unnamed, or binding name for named */
|
|
32
|
+
module: boolean | string;
|
|
33
|
+
/** Block index in the SFC */
|
|
34
|
+
index: number;
|
|
35
|
+
}
|
|
36
|
+
interface CustomBlockInfo {
|
|
37
|
+
/** Tag name (e.g., "i18n", "docs") */
|
|
38
|
+
type: string;
|
|
39
|
+
/** Raw content */
|
|
40
|
+
content: string;
|
|
41
|
+
/** External source from `<block src="...">` */
|
|
42
|
+
src?: string | null;
|
|
43
|
+
/** All attributes on the tag */
|
|
44
|
+
attrs: Record<string, string | true>;
|
|
45
|
+
/** Block index in the SFC */
|
|
46
|
+
index: number;
|
|
47
|
+
}
|
|
48
|
+
interface SfcSrcInfo {
|
|
49
|
+
/** <script src> path, or null */
|
|
50
|
+
scriptSrc?: string | null;
|
|
51
|
+
/** <template src> path, or null */
|
|
52
|
+
templateSrc?: string | null;
|
|
53
|
+
}
|
|
54
|
+
/** Static asset URL in template to be rewritten as an import binding. */
|
|
55
|
+
interface TemplateAssetUrl {
|
|
56
|
+
/** Raw URL as in template (e.g., "./logo.png") */
|
|
57
|
+
url: string;
|
|
58
|
+
/** JS identifier for the import (e.g., "_imports_0") */
|
|
59
|
+
varName: string;
|
|
60
|
+
}
|
|
61
|
+
interface CompiledModule {
|
|
62
|
+
code: string;
|
|
63
|
+
css?: string;
|
|
64
|
+
errors: string[];
|
|
65
|
+
warnings: string[];
|
|
66
|
+
scopeId: string;
|
|
67
|
+
hasScoped: boolean;
|
|
68
|
+
/** Per-block style metadata */
|
|
69
|
+
styles: StyleBlockInfo[];
|
|
70
|
+
/** Custom blocks from the SFC */
|
|
71
|
+
customBlocks: CustomBlockInfo[];
|
|
72
|
+
/** Whether custom element (e.g., .ce.vue) */
|
|
73
|
+
isCustomElement: boolean;
|
|
74
|
+
/** Static asset URLs needing import rewrite. Empty when transformAssetUrls is false. */
|
|
75
|
+
templateAssetUrls: TemplateAssetUrl[];
|
|
76
|
+
}
|
|
77
|
+
interface VizeLoaderOptions {
|
|
78
|
+
/** Source maps @default true */
|
|
79
|
+
sourceMap?: boolean;
|
|
80
|
+
/** SSR mode @default false */
|
|
81
|
+
ssr?: boolean;
|
|
82
|
+
/** Project root */
|
|
83
|
+
root?: string;
|
|
84
|
+
/** Include filter */
|
|
85
|
+
include?: string | RegExp | (string | RegExp)[];
|
|
86
|
+
/** Exclude filter */
|
|
87
|
+
exclude?: string | RegExp | (string | RegExp)[];
|
|
88
|
+
/** Low-level compiler options for @vizejs/native compileSfc */
|
|
89
|
+
compilerOptions?: SfcCompileOptionsNapi;
|
|
90
|
+
/** Custom element mode. true=all, RegExp=matched. @default /\.ce\.vue$/ */
|
|
91
|
+
customElement?: boolean | RegExp;
|
|
92
|
+
/** Vapor mode @default false */
|
|
93
|
+
vapor?: boolean;
|
|
94
|
+
/** HMR. false to disable in dev. @default true (dev), false (prod/SSR) */
|
|
95
|
+
hotReload?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Transform static asset URLs in templates into import bindings.
|
|
98
|
+
* true=built-in tags, false=disabled, object=custom map. @default true
|
|
99
|
+
*/
|
|
100
|
+
transformAssetUrls?: boolean | Record<string, string[]>;
|
|
101
|
+
}
|
|
102
|
+
interface VizeStyleLoaderOptions {
|
|
103
|
+
/** Native CSS mode (experiments.css) @default false */
|
|
104
|
+
native?: boolean;
|
|
105
|
+
}
|
|
106
|
+
interface VizeRspackPluginOptions {
|
|
107
|
+
/** Include filter @default /\.vue$/ */
|
|
108
|
+
include?: string | RegExp | (string | RegExp)[];
|
|
109
|
+
/** Exclude filter @default /node_modules/ */
|
|
110
|
+
exclude?: string | RegExp | (string | RegExp)[];
|
|
111
|
+
/** Force production mode @default auto-detected */
|
|
112
|
+
isProduction?: boolean;
|
|
113
|
+
/** SSR mode @default false */
|
|
114
|
+
ssr?: boolean;
|
|
115
|
+
/** Source maps @default true (dev), false (prod) */
|
|
116
|
+
sourceMap?: boolean;
|
|
117
|
+
/** Vapor mode @default false */
|
|
118
|
+
vapor?: boolean;
|
|
119
|
+
/** Root directory @default Rspack's root */
|
|
120
|
+
root?: string;
|
|
121
|
+
/** CSS config */
|
|
122
|
+
css?: {
|
|
123
|
+
/** Native CSS (experiments.css), uses LightningCSS @default false */native?: boolean;
|
|
124
|
+
};
|
|
125
|
+
/** Compiler options */
|
|
126
|
+
compilerOptions?: SfcCompileOptionsNapi;
|
|
127
|
+
/** Debug logging @default false */
|
|
128
|
+
debug?: boolean;
|
|
129
|
+
/** Auto-clone CSS rules for Vue style sub-requests (like VueLoaderPlugin). @default true */
|
|
130
|
+
autoRules?: boolean;
|
|
131
|
+
}
|
|
132
|
+
/** Loader entry: either a string (loader name/path) or an object with loader + options */
|
|
133
|
+
type LoaderEntry = string | {
|
|
134
|
+
loader: string;
|
|
135
|
+
options?: Record<string, unknown>;
|
|
136
|
+
};
|
|
137
|
+
//#endregion
|
|
138
|
+
export { SfcCompileResultNapi as a, VizeLoaderOptions as c, SfcCompileOptionsNapi as i, VizeRspackPluginOptions as l, CustomBlockInfo as n, SfcSrcInfo as o, LoaderEntry as r, StyleBlockInfo as s, CompiledModule as t, VizeStyleLoaderOptions as u };
|