befly-vite 1.6.3 → 1.6.12
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 +673 -12
- package/index.js +74 -24
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
# befly-vite
|
|
2
2
|
|
|
3
|
-
Befly Vite
|
|
3
|
+
`befly-vite` 是 Befly 后台项目的 Vite 预设包,负责把项目约定、常用插件和 Vite 原生配置组合在一起。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
它目前提供 4 类能力:
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
1. Vite 配置侧的 `createBeflyViteConfig()`
|
|
8
|
+
2. Vite 配置侧的 `scanViews()`
|
|
9
|
+
3. 浏览器运行时的 `Layouts()`
|
|
10
|
+
4. CLI 入口 `befly-vite`
|
|
11
|
+
|
|
12
|
+
## 适用场景
|
|
13
|
+
|
|
14
|
+
- 想在后台管理项目里直接复用 Befly 约定的 Vite 默认配置
|
|
15
|
+
- 想自动扫描 `src/views` 和 `befly-admin-ui/views`
|
|
16
|
+
- 想复用 TDesign 相关的自动导入、组件自动注册和图标规则
|
|
17
|
+
- 想保留 Vite 原生 `viteConfig` 作为统一扩展出口
|
|
11
18
|
|
|
12
19
|
## 安装
|
|
13
20
|
|
|
@@ -15,9 +22,44 @@ Befly Vite 配置预设和插件集合,专为 Vue 3 项目优化。
|
|
|
15
22
|
bun add -d befly-vite vite
|
|
16
23
|
```
|
|
17
24
|
|
|
18
|
-
|
|
25
|
+
如果项目本身还没安装运行时依赖,通常还需要自行安装 Vue 侧依赖,例如:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bun add vue vue-router pinia tdesign-vue-next tdesign-icons-vue-next
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 导出说明
|
|
32
|
+
|
|
33
|
+
### Vite 配置侧
|
|
34
|
+
|
|
35
|
+
在 `vite.config.js` 里使用:
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
import { createBeflyViteConfig, scanViews } from "befly-vite";
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
可用导出:
|
|
42
|
+
|
|
43
|
+
- `createBeflyViteConfig`
|
|
44
|
+
- `scanViews`
|
|
45
|
+
|
|
46
|
+
### 浏览器运行时
|
|
47
|
+
|
|
48
|
+
在前端运行时代码里使用:
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
import { Layouts } from "befly-vite";
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
可用导出:
|
|
55
|
+
|
|
56
|
+
- `Layouts`
|
|
19
57
|
|
|
20
|
-
|
|
58
|
+
## createBeflyViteConfig
|
|
59
|
+
|
|
60
|
+
`createBeflyViteConfig(options)` 是主入口,用来生成 Befly 项目的 Vite 配置。
|
|
61
|
+
|
|
62
|
+
### 最小用法
|
|
21
63
|
|
|
22
64
|
```javascript
|
|
23
65
|
// vite.config.js
|
|
@@ -26,9 +68,164 @@ import { createBeflyViteConfig } from "befly-vite";
|
|
|
26
68
|
export default createBeflyViteConfig();
|
|
27
69
|
```
|
|
28
70
|
|
|
29
|
-
|
|
71
|
+
### 默认内置内容
|
|
72
|
+
|
|
73
|
+
调用后默认会包含以下能力:
|
|
74
|
+
|
|
75
|
+
1. `vue-router/vite` 路由扫描插件
|
|
76
|
+
2. `@vitejs/plugin-vue`
|
|
77
|
+
3. `unplugin-auto-import`
|
|
78
|
+
4. `unplugin-vue-components`
|
|
79
|
+
5. `@` 指向项目 `src`
|
|
80
|
+
6. `server.open = false`
|
|
81
|
+
7. `server.hmr = true`
|
|
82
|
+
8. `build.outDir = "dist"`
|
|
83
|
+
9. `build.assetsDir = "assets"`
|
|
84
|
+
10. `build.cssMinify = "lightningcss"`
|
|
85
|
+
11. `css.transformer = "lightningcss"`
|
|
86
|
+
12. 默认 CSS 浏览器基线:Chrome 107 / Edge 107 / Firefox 104 / Safari 16.0
|
|
87
|
+
|
|
88
|
+
### 参数说明
|
|
89
|
+
|
|
90
|
+
| 参数 | 类型 | 默认值 | 作用 |
|
|
91
|
+
| -------------- | -------------------- | --------------- | ---------------------------------------------------- |
|
|
92
|
+
| `root` | `string` | `process.cwd()` | 项目根目录,用于解析 `src`、扫描 `views` 和生成别名 |
|
|
93
|
+
| `devtool` | `boolean` | `false` | 是否启用 `vite-plugin-vue-devtools` |
|
|
94
|
+
| `analyzer` | `boolean` | `false` | 是否启用打包分析,并输出到 `<root>/temp/analyzer` |
|
|
95
|
+
| `resolvers` | `Object \| Object[]` | `undefined` | 追加到自动导入和组件自动注册中的自定义 resolver |
|
|
96
|
+
| `manualChunks` | `Function \| Object` | `undefined` | 便捷写入 `build.rolldownOptions.output.manualChunks` |
|
|
97
|
+
| `viteConfig` | `Object` | `{}` | 最终合并到默认配置上的 Vite 原生配置 |
|
|
98
|
+
|
|
99
|
+
### 参数细节
|
|
100
|
+
|
|
101
|
+
#### root
|
|
102
|
+
|
|
103
|
+
`root` 决定这些行为的基准目录:
|
|
104
|
+
|
|
105
|
+
1. `@` 别名指向哪个 `src`
|
|
106
|
+
2. `scanViews()` 扫哪个项目目录
|
|
107
|
+
3. 打包分析文件输出到哪个 `temp`
|
|
108
|
+
|
|
109
|
+
最常见写法:
|
|
110
|
+
|
|
111
|
+
```javascript
|
|
112
|
+
import { fileURLToPath } from "node:url";
|
|
113
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
114
|
+
|
|
115
|
+
export default createBeflyViteConfig({
|
|
116
|
+
root: fileURLToPath(new URL(".", import.meta.url))
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### devtool
|
|
121
|
+
|
|
122
|
+
开启后会额外注入 `vite-plugin-vue-devtools`。
|
|
123
|
+
|
|
124
|
+
```javascript
|
|
125
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
126
|
+
|
|
127
|
+
export default createBeflyViteConfig({
|
|
128
|
+
devtool: true
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
适合:本地调试组件树、路由和状态。
|
|
133
|
+
|
|
134
|
+
#### analyzer
|
|
135
|
+
|
|
136
|
+
开启后会额外注入 `vite-bundle-analyzer`,并把报告输出到项目的 `temp/analyzer`。
|
|
137
|
+
|
|
138
|
+
```javascript
|
|
139
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
140
|
+
|
|
141
|
+
export default createBeflyViteConfig({
|
|
142
|
+
analyzer: true
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
适合:分析打包体积、依赖拆分和大包来源。
|
|
147
|
+
|
|
148
|
+
#### resolvers
|
|
149
|
+
|
|
150
|
+
`befly-vite` 默认内置:
|
|
151
|
+
|
|
152
|
+
1. TDesign Vue Next resolver
|
|
153
|
+
2. TDesign 图标 resolver
|
|
154
|
+
|
|
155
|
+
如果项目还想增加额外 resolver,可以通过 `resolvers` 追加。它会同时追加到:
|
|
156
|
+
|
|
157
|
+
1. `unplugin-auto-import`
|
|
158
|
+
2. `unplugin-vue-components`
|
|
159
|
+
|
|
160
|
+
```javascript
|
|
161
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
162
|
+
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
|
|
163
|
+
|
|
164
|
+
export default createBeflyViteConfig({
|
|
165
|
+
resolvers: [ElementPlusResolver()]
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
说明:
|
|
170
|
+
|
|
171
|
+
1. 默认的 TDesign resolver 不会被替换,只会追加新的 resolver
|
|
172
|
+
2. 如果你传单个对象,也会自动转成数组处理
|
|
173
|
+
|
|
174
|
+
#### manualChunks
|
|
175
|
+
|
|
176
|
+
`manualChunks` 是一个便捷入口,会写入 `build.rolldownOptions.output.manualChunks`。
|
|
177
|
+
|
|
178
|
+
适合:
|
|
179
|
+
|
|
180
|
+
1. 只想快速传一个 `manualChunks`
|
|
181
|
+
2. 不想为了简单分包额外展开完整的 `build` 配置
|
|
182
|
+
|
|
183
|
+
如果还要同时配置 `output.entryFileNames`、`chunkFileNames`、`assetFileNames` 等其他构建输出项,推荐直接走 `viteConfig.build.rolldownOptions`。
|
|
184
|
+
|
|
185
|
+
如果旧项目还在传 `viteConfig.build.rollupOptions`,在 Vite 8 下也还能继续工作;只是新配置更建议直接写 `build.rolldownOptions`。
|
|
186
|
+
|
|
187
|
+
函数写法:
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
191
|
+
|
|
192
|
+
export default createBeflyViteConfig({
|
|
193
|
+
manualChunks: function (id) {
|
|
194
|
+
if (id.includes("tdesign-vue-next")) {
|
|
195
|
+
return "tdesign";
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (id.includes("node_modules")) {
|
|
199
|
+
return "vendor";
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
对象写法:
|
|
206
|
+
|
|
207
|
+
```javascript
|
|
208
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
209
|
+
|
|
210
|
+
export default createBeflyViteConfig({
|
|
211
|
+
manualChunks: {
|
|
212
|
+
vue: ["vue", "vue-router", "pinia"],
|
|
213
|
+
tdesign: ["tdesign-vue-next", "tdesign-icons-vue-next"]
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
适合:
|
|
219
|
+
|
|
220
|
+
1. 把大依赖稳定拆分出去
|
|
221
|
+
2. 减少首屏主包体积
|
|
222
|
+
3. 提升缓存命中率
|
|
223
|
+
|
|
224
|
+
#### viteConfig
|
|
225
|
+
|
|
226
|
+
`viteConfig` 是扩展出口,所有不值得再额外封装一层的配置,都建议直接从这里传入。
|
|
30
227
|
|
|
31
|
-
|
|
228
|
+
简单示例:
|
|
32
229
|
|
|
33
230
|
```javascript
|
|
34
231
|
import { createBeflyViteConfig } from "befly-vite";
|
|
@@ -36,8 +233,6 @@ import { fileURLToPath } from "node:url";
|
|
|
36
233
|
|
|
37
234
|
export default createBeflyViteConfig({
|
|
38
235
|
root: fileURLToPath(new URL(".", import.meta.url)),
|
|
39
|
-
|
|
40
|
-
// 自定义配置
|
|
41
236
|
viteConfig: {
|
|
42
237
|
server: {
|
|
43
238
|
port: 5600
|
|
@@ -46,6 +241,472 @@ export default createBeflyViteConfig({
|
|
|
46
241
|
});
|
|
47
242
|
```
|
|
48
243
|
|
|
244
|
+
适合放在这里的配置包括:
|
|
245
|
+
|
|
246
|
+
1. `server.port`
|
|
247
|
+
2. `server.proxy`
|
|
248
|
+
3. `define`
|
|
249
|
+
4. `build.sourcemap`
|
|
250
|
+
5. `build.cssTarget`
|
|
251
|
+
6. `css.lightningcss`
|
|
252
|
+
7. `build.rolldownOptions`
|
|
253
|
+
8. 其他任意 Vite 原生配置
|
|
254
|
+
|
|
255
|
+
chunks 的推荐方式:
|
|
256
|
+
|
|
257
|
+
1. 简单场景用顶层 `manualChunks`
|
|
258
|
+
2. 需要完整控制输出结构时,用 `viteConfig.build.rolldownOptions`
|
|
259
|
+
|
|
260
|
+
示例:
|
|
261
|
+
|
|
262
|
+
```javascript
|
|
263
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
264
|
+
import { fileURLToPath } from "node:url";
|
|
265
|
+
|
|
266
|
+
export default createBeflyViteConfig({
|
|
267
|
+
root: fileURLToPath(new URL(".", import.meta.url)),
|
|
268
|
+
viteConfig: {
|
|
269
|
+
build: {
|
|
270
|
+
rolldownOptions: {
|
|
271
|
+
output: {
|
|
272
|
+
manualChunks: function (id) {
|
|
273
|
+
if (id.includes("tdesign-vue-next") || id.includes("tdesign-icons-vue-next")) {
|
|
274
|
+
return "tdesign";
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (id.includes("node_modules/vue") || id.includes("node_modules/vue-router") || id.includes("node_modules/pinia")) {
|
|
278
|
+
return "framework";
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
entryFileNames: "assets/[name]-[hash].js",
|
|
282
|
+
chunkFileNames: "assets/[name]-[hash].js"
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## CSS 兼容配置
|
|
291
|
+
|
|
292
|
+
`befly-vite` 不再提供单独的 `compat` 配置,CSS 兼容统一走 Vite 8 原生配置。
|
|
293
|
+
|
|
294
|
+
### 默认行为
|
|
295
|
+
|
|
296
|
+
默认内置:
|
|
297
|
+
|
|
298
|
+
```javascript
|
|
299
|
+
{
|
|
300
|
+
build: {
|
|
301
|
+
cssTarget: ["chrome107", "edge107", "firefox104", "safari16"],
|
|
302
|
+
cssMinify: "lightningcss"
|
|
303
|
+
},
|
|
304
|
+
css: {
|
|
305
|
+
transformer: "lightningcss",
|
|
306
|
+
lightningcss: {
|
|
307
|
+
targets: {
|
|
308
|
+
chrome: 107 << 16,
|
|
309
|
+
edge: 107 << 16,
|
|
310
|
+
firefox: 104 << 16,
|
|
311
|
+
ios_saf: 16 << 16,
|
|
312
|
+
safari: 16 << 16
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### 为什么同时有 `build.cssTarget` 和 `css.lightningcss.targets`
|
|
320
|
+
|
|
321
|
+
1. `build.cssTarget` 控制 CSS 压缩输出目标
|
|
322
|
+
2. `css.lightningcss.targets` 控制 Lightning CSS 的语法降级和前缀处理目标
|
|
323
|
+
|
|
324
|
+
这两者默认保持一致。
|
|
325
|
+
|
|
326
|
+
### 项目侧覆盖写法
|
|
327
|
+
|
|
328
|
+
如果项目需要更高或更低的兼容基线,可以直接通过 `viteConfig` 覆盖。
|
|
329
|
+
|
|
330
|
+
```javascript
|
|
331
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
332
|
+
|
|
333
|
+
export default createBeflyViteConfig({
|
|
334
|
+
viteConfig: {
|
|
335
|
+
build: {
|
|
336
|
+
cssTarget: ["chrome120", "edge120", "firefox120", "safari17"]
|
|
337
|
+
},
|
|
338
|
+
css: {
|
|
339
|
+
lightningcss: {
|
|
340
|
+
targets: {
|
|
341
|
+
chrome: 120 << 16,
|
|
342
|
+
edge: 120 << 16,
|
|
343
|
+
firefox: 120 << 16,
|
|
344
|
+
ios_saf: 17 << 16,
|
|
345
|
+
safari: 17 << 16
|
|
346
|
+
},
|
|
347
|
+
drafts: {
|
|
348
|
+
nesting: true
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
说明:
|
|
357
|
+
|
|
358
|
+
1. `viteConfig.build.cssTarget` 一旦传入,会直接覆盖默认值
|
|
359
|
+
2. `viteConfig.css.lightningcss.targets` 一旦传入,也会直接覆盖默认值
|
|
360
|
+
3. 其他 `css.lightningcss` 选项仍会与默认配置合并
|
|
361
|
+
|
|
362
|
+
### 常见 CSS 配置案例
|
|
363
|
+
|
|
364
|
+
#### 只改压缩目标
|
|
365
|
+
|
|
366
|
+
```javascript
|
|
367
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
368
|
+
|
|
369
|
+
export default createBeflyViteConfig({
|
|
370
|
+
viteConfig: {
|
|
371
|
+
build: {
|
|
372
|
+
cssTarget: "safari16"
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
#### 调整 Lightning CSS draft 能力
|
|
379
|
+
|
|
380
|
+
```javascript
|
|
381
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
382
|
+
|
|
383
|
+
export default createBeflyViteConfig({
|
|
384
|
+
viteConfig: {
|
|
385
|
+
css: {
|
|
386
|
+
lightningcss: {
|
|
387
|
+
drafts: {
|
|
388
|
+
nesting: true,
|
|
389
|
+
customMedia: true
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
#### 关闭 CSS 压缩
|
|
398
|
+
|
|
399
|
+
```javascript
|
|
400
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
401
|
+
|
|
402
|
+
export default createBeflyViteConfig({
|
|
403
|
+
viteConfig: {
|
|
404
|
+
build: {
|
|
405
|
+
cssMinify: false
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
## 路由扫描规则
|
|
412
|
+
|
|
413
|
+
`befly-vite` 内部通过 `scanViews(appRoot)` 扫描视图目录,并交给 `vue-router/vite`。
|
|
414
|
+
|
|
415
|
+
### 默认扫描来源
|
|
416
|
+
|
|
417
|
+
1. `<root>/src/views`
|
|
418
|
+
2. `<root>/node_modules/befly-admin-ui/views`
|
|
419
|
+
|
|
420
|
+
其中 `befly-admin-ui/views` 会被挂到 `core/` 前缀下。
|
|
421
|
+
|
|
422
|
+
### 默认排除规则
|
|
423
|
+
|
|
424
|
+
两个目录都会排除:
|
|
425
|
+
|
|
426
|
+
```text
|
|
427
|
+
**/components/**
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### 单独使用 scanViews
|
|
431
|
+
|
|
432
|
+
如果项目要直接复用这套扫描规则,也可以单独调用:
|
|
433
|
+
|
|
434
|
+
```javascript
|
|
435
|
+
import { fileURLToPath } from "node:url";
|
|
436
|
+
import { scanViews } from "befly-vite";
|
|
437
|
+
|
|
438
|
+
const appRoot = fileURLToPath(new URL(".", import.meta.url));
|
|
439
|
+
const routesFolders = scanViews(appRoot);
|
|
440
|
+
|
|
441
|
+
console.log(routesFolders);
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
返回值结构示例:
|
|
445
|
+
|
|
446
|
+
```javascript
|
|
447
|
+
[
|
|
448
|
+
{
|
|
449
|
+
src: "/absolute/path/to/src/views",
|
|
450
|
+
path: "",
|
|
451
|
+
exclude: ["**/components/**"]
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
src: "/absolute/path/to/node_modules/befly-admin-ui/views",
|
|
455
|
+
path: "core/",
|
|
456
|
+
exclude: ["**/components/**"]
|
|
457
|
+
}
|
|
458
|
+
];
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
## 自动导入与组件自动注册规则
|
|
462
|
+
|
|
463
|
+
### Auto Import
|
|
464
|
+
|
|
465
|
+
默认会对以下文件启用自动导入:
|
|
466
|
+
|
|
467
|
+
```text
|
|
468
|
+
src/**/*.vue
|
|
469
|
+
src/**/*.js
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
默认自动导入内容:
|
|
473
|
+
|
|
474
|
+
1. `vue`
|
|
475
|
+
2. `pinia`
|
|
476
|
+
3. `vue-router` 的 auto imports
|
|
477
|
+
4. 默认 TDesign resolver
|
|
478
|
+
5. 你额外传入的 `resolvers`
|
|
479
|
+
|
|
480
|
+
默认扫描目录:
|
|
481
|
+
|
|
482
|
+
1. `src/utils`
|
|
483
|
+
2. `src/plugins`
|
|
484
|
+
3. `src/config`
|
|
485
|
+
4. `src/hooks`
|
|
486
|
+
|
|
487
|
+
### Components
|
|
488
|
+
|
|
489
|
+
默认会对以下目录启用组件自动注册:
|
|
490
|
+
|
|
491
|
+
1. `src/**/*.vue`
|
|
492
|
+
2. `node_modules/befly-admin-ui/**/*.vue`
|
|
493
|
+
|
|
494
|
+
默认内置 resolver:
|
|
495
|
+
|
|
496
|
+
1. TDesign Vue Next resolver
|
|
497
|
+
2. `tdesign-icons-vue-next` 图标 resolver
|
|
498
|
+
3. 你额外传入的 `resolvers`
|
|
499
|
+
|
|
500
|
+
说明:
|
|
501
|
+
|
|
502
|
+
1. `src/components` 会被作为本地组件目录扫描
|
|
503
|
+
2. addon 视图不在当前自动导入的 include 范围内,需要按项目规范手动导入
|
|
504
|
+
|
|
505
|
+
## Layouts
|
|
506
|
+
|
|
507
|
+
`Layouts(routes, rootRedirectPath, resolveLayoutComponent)` 用于浏览器运行时把 auto-routes 结果转换成带布局的最终路由。
|
|
508
|
+
|
|
509
|
+
### 作用
|
|
510
|
+
|
|
511
|
+
它会根据页面文件名里的 `_数字` 后缀决定使用哪个布局,并把普通路径段统一转换成短横线小写。
|
|
512
|
+
|
|
513
|
+
例如:
|
|
514
|
+
|
|
515
|
+
1. `userCenter/account_1.vue` -> `/user-center/account`,布局 `1`
|
|
516
|
+
2. `newsDetail_2.vue` -> `/news-detail`,布局 `2`
|
|
517
|
+
3. `guide/index_1.vue` -> `/guide`,布局 `1`
|
|
518
|
+
|
|
519
|
+
### 基础示例
|
|
520
|
+
|
|
521
|
+
```javascript
|
|
522
|
+
import { Layouts } from "befly-vite";
|
|
523
|
+
|
|
524
|
+
const routes = [
|
|
525
|
+
{
|
|
526
|
+
path: "userCenter",
|
|
527
|
+
children: [
|
|
528
|
+
{
|
|
529
|
+
path: "account_1",
|
|
530
|
+
component: () => import("./views/userCenter/account.vue")
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
path: "my_news",
|
|
534
|
+
component: () => import("./views/userCenter/my_news.vue")
|
|
535
|
+
}
|
|
536
|
+
]
|
|
537
|
+
}
|
|
538
|
+
];
|
|
539
|
+
|
|
540
|
+
const finalRoutes = Layouts(routes, "/dashboard", function (layoutName) {
|
|
541
|
+
return layoutName ? `layout:${layoutName}` : "layout:default";
|
|
542
|
+
});
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### 参数说明
|
|
546
|
+
|
|
547
|
+
| 参数 | 类型 | 作用 |
|
|
548
|
+
| ------------------------ | ---------- | --------------------------------------------- |
|
|
549
|
+
| `routes` | `Array` | auto-routes 产出的原始路由数组 |
|
|
550
|
+
| `rootRedirectPath` | `string` | 根路径 `/` 的重定向目标;传空值则不注入重定向 |
|
|
551
|
+
| `resolveLayoutComponent` | `Function` | 根据布局名返回布局组件 |
|
|
552
|
+
|
|
553
|
+
### Layouts 规则说明
|
|
554
|
+
|
|
555
|
+
1. 动态参数段如 `:userId` 会保留原样
|
|
556
|
+
2. 普通路径段会统一转成短横线小写
|
|
557
|
+
3. 下划线 `_` 会转成 `-`
|
|
558
|
+
4. 驼峰会转成短横线小写
|
|
559
|
+
5. `_数字` 后缀只用于布局名,不会出现在最终路径里
|
|
560
|
+
6. `index` 子页会折叠成父路径下的空子路径
|
|
561
|
+
|
|
562
|
+
## CLI
|
|
563
|
+
|
|
564
|
+
包内自带 `befly-vite` 命令,本质上是一个 Bun 环境下的 Vite 启动包装器,用来帮项目找到 `vite/bin/vite.js` 并转发参数。
|
|
565
|
+
|
|
566
|
+
### 最常见脚本写法
|
|
567
|
+
|
|
568
|
+
```json
|
|
569
|
+
{
|
|
570
|
+
"scripts": {
|
|
571
|
+
"dev": "bunx --bun befly-vite",
|
|
572
|
+
"build": "bunx --bun befly-vite build",
|
|
573
|
+
"preview": "bunx --bun befly-vite preview"
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### 作用
|
|
579
|
+
|
|
580
|
+
1. 自动定位 `vite` 可执行文件
|
|
581
|
+
2. 用 Bun 转发执行 `vite`
|
|
582
|
+
3. 保持项目脚本写法统一
|
|
583
|
+
|
|
584
|
+
## 完整案例
|
|
585
|
+
|
|
586
|
+
### 案例 1:最小后台项目
|
|
587
|
+
|
|
588
|
+
```javascript
|
|
589
|
+
import { fileURLToPath } from "node:url";
|
|
590
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
591
|
+
|
|
592
|
+
export default createBeflyViteConfig({
|
|
593
|
+
root: fileURLToPath(new URL(".", import.meta.url))
|
|
594
|
+
});
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
### 案例 2:本地开发端口 + 调试工具
|
|
598
|
+
|
|
599
|
+
```javascript
|
|
600
|
+
import { fileURLToPath } from "node:url";
|
|
601
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
602
|
+
|
|
603
|
+
export default createBeflyViteConfig({
|
|
604
|
+
root: fileURLToPath(new URL(".", import.meta.url)),
|
|
605
|
+
devtool: true,
|
|
606
|
+
viteConfig: {
|
|
607
|
+
server: {
|
|
608
|
+
port: 5206
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
});
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### 案例 3:打包分析 + Vite 原生分包
|
|
615
|
+
|
|
616
|
+
```javascript
|
|
617
|
+
import { fileURLToPath } from "node:url";
|
|
618
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
619
|
+
|
|
620
|
+
export default createBeflyViteConfig({
|
|
621
|
+
root: fileURLToPath(new URL(".", import.meta.url)),
|
|
622
|
+
analyzer: true,
|
|
623
|
+
viteConfig: {
|
|
624
|
+
build: {
|
|
625
|
+
rolldownOptions: {
|
|
626
|
+
output: {
|
|
627
|
+
manualChunks: function (id) {
|
|
628
|
+
if (id.includes("tdesign-vue-next") || id.includes("tdesign-icons-vue-next")) {
|
|
629
|
+
return "tdesign";
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
if (id.includes("node_modules")) {
|
|
633
|
+
return "vendor";
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### 案例 4:自定义 CSS 浏览器兼容目标
|
|
644
|
+
|
|
645
|
+
```javascript
|
|
646
|
+
import { fileURLToPath } from "node:url";
|
|
647
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
648
|
+
|
|
649
|
+
export default createBeflyViteConfig({
|
|
650
|
+
root: fileURLToPath(new URL(".", import.meta.url)),
|
|
651
|
+
viteConfig: {
|
|
652
|
+
build: {
|
|
653
|
+
cssTarget: ["chrome120", "edge120", "firefox120", "safari17"]
|
|
654
|
+
},
|
|
655
|
+
css: {
|
|
656
|
+
lightningcss: {
|
|
657
|
+
targets: {
|
|
658
|
+
chrome: 120 << 16,
|
|
659
|
+
edge: 120 << 16,
|
|
660
|
+
firefox: 120 << 16,
|
|
661
|
+
ios_saf: 17 << 16,
|
|
662
|
+
safari: 17 << 16
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
});
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
### 案例 5:Vite 原生能力扩展
|
|
671
|
+
|
|
672
|
+
```javascript
|
|
673
|
+
import { fileURLToPath } from "node:url";
|
|
674
|
+
import { createBeflyViteConfig } from "befly-vite";
|
|
675
|
+
|
|
676
|
+
export default createBeflyViteConfig({
|
|
677
|
+
root: fileURLToPath(new URL(".", import.meta.url)),
|
|
678
|
+
viteConfig: {
|
|
679
|
+
define: {
|
|
680
|
+
__APP_NAME__: JSON.stringify("befly-admin")
|
|
681
|
+
},
|
|
682
|
+
build: {
|
|
683
|
+
sourcemap: true
|
|
684
|
+
},
|
|
685
|
+
server: {
|
|
686
|
+
proxy: {
|
|
687
|
+
"/api": {
|
|
688
|
+
target: "http://127.0.0.1:3000",
|
|
689
|
+
changeOrigin: true
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
## 什么时候应该直接用 viteConfig
|
|
698
|
+
|
|
699
|
+
如果某个能力本身已经是稳定的 Vite 原生配置,而且 `befly-vite` 没必要再包装一层,优先直接用 `viteConfig`。例如:
|
|
700
|
+
|
|
701
|
+
1. `server.port`
|
|
702
|
+
2. `server.proxy`
|
|
703
|
+
3. `define`
|
|
704
|
+
4. `build.sourcemap`
|
|
705
|
+
5. `build.cssTarget`
|
|
706
|
+
6. `build.cssMinify`
|
|
707
|
+
7. `css.lightningcss`
|
|
708
|
+
8. `resolve.alias`
|
|
709
|
+
|
|
49
710
|
## License
|
|
50
711
|
|
|
51
712
|
Apache-2.0
|
package/index.js
CHANGED
|
@@ -39,20 +39,36 @@ function createVuePlugin() {
|
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
function createTDesignResolver() {
|
|
43
|
+
return TDesignResolver({
|
|
44
|
+
library: "vue-next",
|
|
45
|
+
importStyle: "css"
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function normalizeResolvers(resolvers) {
|
|
50
|
+
if (resolvers === null || resolvers === undefined) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (Array.isArray(resolvers)) {
|
|
55
|
+
return resolvers;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return [resolvers];
|
|
59
|
+
}
|
|
60
|
+
|
|
42
61
|
/**
|
|
43
62
|
* 创建自动导入插件配置
|
|
44
63
|
*/
|
|
45
|
-
function createAutoImportPlugin() {
|
|
64
|
+
function createAutoImportPlugin(options = {}) {
|
|
65
|
+
const { resolvers } = options;
|
|
66
|
+
|
|
46
67
|
return AutoImport({
|
|
47
68
|
// 只给 admin 自身源码做自动导入;addon 视图强制手动导入
|
|
48
69
|
include: [/[\\/]src[\\/].*\.(vue|js)$/],
|
|
49
70
|
imports: ["vue", "pinia", VueRouterAutoImports],
|
|
50
|
-
resolvers: [
|
|
51
|
-
TDesignResolver({
|
|
52
|
-
library: "vue-next",
|
|
53
|
-
importStyle: "css"
|
|
54
|
-
})
|
|
55
|
-
],
|
|
71
|
+
resolvers: [createTDesignResolver(), ...normalizeResolvers(resolvers)],
|
|
56
72
|
dts: false,
|
|
57
73
|
dirs: ["src/utils", "src/plugins", "src/config", "src/hooks"],
|
|
58
74
|
vueTemplate: true
|
|
@@ -71,17 +87,13 @@ function resolveTDesignIcon(componentName) {
|
|
|
71
87
|
/**
|
|
72
88
|
* 创建组件自动导入插件配置
|
|
73
89
|
*/
|
|
74
|
-
function createComponentsPlugin() {
|
|
90
|
+
function createComponentsPlugin(options = {}) {
|
|
91
|
+
const { resolvers } = options;
|
|
92
|
+
|
|
75
93
|
return Components({
|
|
76
94
|
// 给 admin 自身源码和 befly-admin-ui 视图做组件自动注册;addon 视图强制手动导入
|
|
77
95
|
include: [/[\\/]src[\\/].*\.vue$/, /[\\/]node_modules[\\/]befly-admin-ui[\\/].*\.vue$/],
|
|
78
|
-
resolvers: [
|
|
79
|
-
TDesignResolver({
|
|
80
|
-
library: "vue-next",
|
|
81
|
-
importStyle: "css"
|
|
82
|
-
}),
|
|
83
|
-
resolveTDesignIcon
|
|
84
|
-
],
|
|
96
|
+
resolvers: [createTDesignResolver(), resolveTDesignIcon, ...normalizeResolvers(resolvers)],
|
|
85
97
|
dirs: ["src/components"],
|
|
86
98
|
deep: true,
|
|
87
99
|
dts: false
|
|
@@ -99,8 +111,22 @@ function createAnalyzerPlugin(appRoot) {
|
|
|
99
111
|
});
|
|
100
112
|
}
|
|
101
113
|
|
|
102
|
-
function
|
|
103
|
-
|
|
114
|
+
function createCssCompatConfig(viteConfig) {
|
|
115
|
+
const defaultCssTarget = ["chrome107", "edge107", "firefox104", "safari16"];
|
|
116
|
+
const defaultLightningCssTargets = {
|
|
117
|
+
chrome: 107 << 16,
|
|
118
|
+
edge: 107 << 16,
|
|
119
|
+
firefox: 104 << 16,
|
|
120
|
+
ios_saf: 16 << 16,
|
|
121
|
+
safari: 16 << 16
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
cssTarget: viteConfig.build && Object.hasOwn(viteConfig.build, "cssTarget") ? viteConfig.build.cssTarget : defaultCssTarget,
|
|
126
|
+
lightningcss: {
|
|
127
|
+
targets: viteConfig.css && viteConfig.css.lightningcss && Object.hasOwn(viteConfig.css.lightningcss, "targets") ? viteConfig.css.lightningcss.targets : defaultLightningCssTargets
|
|
128
|
+
}
|
|
129
|
+
};
|
|
104
130
|
}
|
|
105
131
|
|
|
106
132
|
/**
|
|
@@ -109,8 +135,8 @@ function createDevToolsPlugin() {
|
|
|
109
135
|
* @param {string} options.root - 项目根目录(可选)
|
|
110
136
|
* @param {boolean} options.devtool - 是否启用 vite-plugin-vue-devtools(可选,默认 false)
|
|
111
137
|
* @param {boolean} options.analyzer - 是否启用 vite-bundle-analyzer(可选,默认 false)
|
|
112
|
-
* @param {Object} options.resolvers - 自定义 resolvers(可选)
|
|
113
|
-
* @param {Function} options.manualChunks -
|
|
138
|
+
* @param {Object|Object[]} options.resolvers - 自定义 resolvers(可选)
|
|
139
|
+
* @param {Function|Object} options.manualChunks - 便捷分包配置,会写入 build.rolldownOptions.output.manualChunks(可选)
|
|
114
140
|
* @param {Object} options.viteConfig - 用户自定义配置(可选)
|
|
115
141
|
* @returns {Object} Vite 配置对象
|
|
116
142
|
*/
|
|
@@ -120,7 +146,8 @@ export function createBeflyViteConfig(options = {}) {
|
|
|
120
146
|
root,
|
|
121
147
|
devtool = false,
|
|
122
148
|
analyzer = false,
|
|
123
|
-
resolvers
|
|
149
|
+
resolvers,
|
|
150
|
+
manualChunks,
|
|
124
151
|
viteConfig = {}
|
|
125
152
|
} = options;
|
|
126
153
|
|
|
@@ -134,7 +161,7 @@ export function createBeflyViteConfig(options = {}) {
|
|
|
134
161
|
plugins.push(createRouterPlugin({ routesFolders: routesFolders }));
|
|
135
162
|
plugins.push(createVuePlugin());
|
|
136
163
|
if (devtool) {
|
|
137
|
-
plugins.push(
|
|
164
|
+
plugins.push(VueDevTools());
|
|
138
165
|
}
|
|
139
166
|
plugins.push(createAutoImportPlugin({ resolvers: resolvers }));
|
|
140
167
|
plugins.push(createComponentsPlugin({ resolvers: resolvers }));
|
|
@@ -142,6 +169,8 @@ export function createBeflyViteConfig(options = {}) {
|
|
|
142
169
|
plugins.push(createAnalyzerPlugin(appRoot));
|
|
143
170
|
}
|
|
144
171
|
|
|
172
|
+
const cssCompatConfig = createCssCompatConfig(viteConfig);
|
|
173
|
+
|
|
145
174
|
const baseConfig = defineConfig({
|
|
146
175
|
base: "./",
|
|
147
176
|
|
|
@@ -160,7 +189,22 @@ export function createBeflyViteConfig(options = {}) {
|
|
|
160
189
|
|
|
161
190
|
build: {
|
|
162
191
|
outDir: "dist",
|
|
163
|
-
assetsDir: "assets"
|
|
192
|
+
assetsDir: "assets",
|
|
193
|
+
cssTarget: cssCompatConfig.cssTarget,
|
|
194
|
+
rolldownOptions:
|
|
195
|
+
manualChunks === undefined
|
|
196
|
+
? undefined
|
|
197
|
+
: {
|
|
198
|
+
output: {
|
|
199
|
+
manualChunks: manualChunks
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
cssMinify: "lightningcss"
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
css: {
|
|
206
|
+
transformer: "lightningcss",
|
|
207
|
+
lightningcss: cssCompatConfig.lightningcss
|
|
164
208
|
},
|
|
165
209
|
|
|
166
210
|
optimizeDeps: {
|
|
@@ -168,7 +212,13 @@ export function createBeflyViteConfig(options = {}) {
|
|
|
168
212
|
}
|
|
169
213
|
});
|
|
170
214
|
|
|
171
|
-
|
|
215
|
+
const finalConfig = mergeConfig(baseConfig, viteConfig);
|
|
216
|
+
|
|
217
|
+
if (viteConfig.build && Object.hasOwn(viteConfig.build, "cssTarget")) {
|
|
218
|
+
finalConfig.build.cssTarget = viteConfig.build.cssTarget;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return finalConfig;
|
|
172
222
|
}
|
|
173
223
|
|
|
174
224
|
/**
|
|
@@ -192,7 +242,7 @@ export function scanViews(appRoot = process.cwd()) {
|
|
|
192
242
|
});
|
|
193
243
|
}
|
|
194
244
|
|
|
195
|
-
// 2. 扫描 befly-admin-ui/views(框架内置视图)
|
|
245
|
+
// 2. 扫描 befly-admin-ui/views(框架内置视图)2
|
|
196
246
|
if (existsSync(adminUiPath)) {
|
|
197
247
|
const adminUiViewsPath = join(adminUiPath, "views");
|
|
198
248
|
if (existsSync(adminUiViewsPath)) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "befly-vite",
|
|
3
|
-
"version": "1.6.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "1.6.12",
|
|
4
|
+
"gitHead": "b02b83ced3735d167d79254ba907eda8b02c5dc3",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Befly Vite 配置预设和插件集合",
|
|
7
7
|
"keywords": [
|
|
@@ -41,9 +41,10 @@
|
|
|
41
41
|
"sass": "^1.99.0",
|
|
42
42
|
"unplugin-auto-import": "^21.0.0",
|
|
43
43
|
"unplugin-vue-components": "^32.0.0",
|
|
44
|
-
"vite": "^8.0.
|
|
44
|
+
"vite": "^8.0.13",
|
|
45
45
|
"vite-bundle-analyzer": "^1.3.8",
|
|
46
|
-
"vite-plugin-vue-devtools": "^8.1.2"
|
|
46
|
+
"vite-plugin-vue-devtools": "^8.1.2",
|
|
47
|
+
"vue-router": "^5.0.7"
|
|
47
48
|
},
|
|
48
49
|
"engines": {
|
|
49
50
|
"bun": ">=1.3.0"
|