vite-plugin-ops 0.1.1 → 0.1.2
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 -21
- package/README.md +409 -409
- package/dist/index.cjs +49 -8
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +49 -8
- package/package.json +56 -56
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) suileyan
|
|
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.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) suileyan
|
|
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
CHANGED
|
@@ -1,409 +1,409 @@
|
|
|
1
|
-
# vite-plugin-ops
|
|
2
|
-
|
|
3
|
-
**O**ptimized **P**ackaging **S**trategy - 一个智能的 Vite 分包优化插件
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/vite-plugin-ops)
|
|
6
|
-
[](https://github.com/suileyan/vite-plugin-ops/blob/main/LICENSE)
|
|
7
|
-
|
|
8
|
-
## 特性
|
|
9
|
-
|
|
10
|
-
- **智能分包策略** - 三种预设策略适配不同场景
|
|
11
|
-
- **自动识别依赖** - 无需手动配置,自动读取 package.json
|
|
12
|
-
- **框架预设** - 内置主流框架和库的最佳分包方案
|
|
13
|
-
- **高度可配置** - 支持自定义分包规则
|
|
14
|
-
- **优先级系统** - 灵活的匹配优先级机制
|
|
15
|
-
- **资源分类** - 自动将 CSS、图片、字体分类存放
|
|
16
|
-
- **零配置可用** - 开箱即用,合理的默认配置
|
|
17
|
-
|
|
18
|
-
## 安装
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
npm install vite-plugin-ops -D
|
|
22
|
-
# 或
|
|
23
|
-
pnpm add vite-plugin-ops -D
|
|
24
|
-
# 或
|
|
25
|
-
yarn add vite-plugin-ops -D
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## 快速开始
|
|
29
|
-
|
|
30
|
-
### 基础使用
|
|
31
|
-
|
|
32
|
-
```typescript
|
|
33
|
-
// vite.config.ts
|
|
34
|
-
import { defineConfig } from 'vite'
|
|
35
|
-
import vue from '@vitejs/plugin-vue'
|
|
36
|
-
import OPS from 'vite-plugin-ops'
|
|
37
|
-
|
|
38
|
-
export default defineConfig({
|
|
39
|
-
plugins: [
|
|
40
|
-
vue(),
|
|
41
|
-
OPS() // 使用默认配置
|
|
42
|
-
]
|
|
43
|
-
})
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
插件会自动:
|
|
47
|
-
- 将 node_modules 中的依赖智能分包
|
|
48
|
-
- 将 CSS 文件放入 `css/` 目录
|
|
49
|
-
- 将图片放入 `img/` 目录
|
|
50
|
-
- 将字体放入 `fonts/` 目录
|
|
51
|
-
- 将其他资源放入 `assets/` 目录
|
|
52
|
-
|
|
53
|
-
## 分包策略
|
|
54
|
-
|
|
55
|
-
插件提供三种分包策略,适用于不同场景:
|
|
56
|
-
|
|
57
|
-
### 1. Balanced(平衡 - 默认推荐)
|
|
58
|
-
|
|
59
|
-
适合大多数生产环境,平衡构建速度和加载性能。
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
OPS({
|
|
63
|
-
strategy: 'balanced' // 默认值,可省略
|
|
64
|
-
})
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
**特点:**
|
|
68
|
-
- 大型库独立分包(React、Vue、Antd、Echarts 等)
|
|
69
|
-
- 中型库按类型分组(工具库、图标库、表单库等)
|
|
70
|
-
- 小型库合并到 vendor
|
|
71
|
-
- 典型输出:5-15 个 chunk
|
|
72
|
-
|
|
73
|
-
**适用场景:** 生产环境、中大型项目
|
|
74
|
-
|
|
75
|
-
### 2. Aggressive(激进)
|
|
76
|
-
|
|
77
|
-
每个依赖都独立分包,适合开发调试。
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
OPS({
|
|
81
|
-
strategy: 'aggressive'
|
|
82
|
-
})
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**特点:**
|
|
86
|
-
- 每个依赖独立成一个 chunk
|
|
87
|
-
- 便于查看单个依赖的体积
|
|
88
|
-
- 可能产生大量小文件
|
|
89
|
-
- 典型输出:20-50+ 个 chunk
|
|
90
|
-
|
|
91
|
-
**适用场景:** 开发环境、依赖分析
|
|
92
|
-
|
|
93
|
-
### 3. Conservative(保守)
|
|
94
|
-
|
|
95
|
-
最小化分包,减少 HTTP 请求。
|
|
96
|
-
|
|
97
|
-
```typescript
|
|
98
|
-
OPS({
|
|
99
|
-
strategy: 'conservative'
|
|
100
|
-
})
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
**特点:**
|
|
104
|
-
- 只分离超大型库(React、Vue、Antd、Echarts 等)
|
|
105
|
-
- 其他库合并到 vendor
|
|
106
|
-
- 减少 HTTP 请求数量
|
|
107
|
-
- 典型输出:3-8 个 chunk
|
|
108
|
-
|
|
109
|
-
**适用场景:** 小型项目、HTTP/1.x 环境
|
|
110
|
-
|
|
111
|
-
## 配置选项
|
|
112
|
-
|
|
113
|
-
### 完整配置示例
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
OPS({
|
|
117
|
-
// 分包策略
|
|
118
|
-
strategy: 'balanced', // 'aggressive' | 'balanced' | 'conservative'
|
|
119
|
-
|
|
120
|
-
// 是否覆盖用户已有的 rollupOptions.output 配置
|
|
121
|
-
override: false,
|
|
122
|
-
|
|
123
|
-
// 最小分包大小(KB),仅在 balanced 和 conservative 策略下生效
|
|
124
|
-
minSize: 50,
|
|
125
|
-
|
|
126
|
-
// 自定义分组规则
|
|
127
|
-
groups: {
|
|
128
|
-
// 将 lodash 相关库独立分包
|
|
129
|
-
'lodash': ['lodash', 'lodash-es'],
|
|
130
|
-
|
|
131
|
-
// 使用正则匹配
|
|
132
|
-
'my-ui': [/my-ui-library/],
|
|
133
|
-
|
|
134
|
-
// 将多个相关库分到一组
|
|
135
|
-
'charts': ['echarts', 'chart.js', 'd3']
|
|
136
|
-
}
|
|
137
|
-
})
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### 配置项说明
|
|
141
|
-
|
|
142
|
-
| 参数 | 类型 | 默认值 | 说明 |
|
|
143
|
-
|------|------|--------|------|
|
|
144
|
-
| `strategy` | `'aggressive' \| 'balanced' \| 'conservative'` | `'balanced'` | 分包策略 |
|
|
145
|
-
| `override` | `boolean` | `false` | 是否覆盖已有配置 |
|
|
146
|
-
| `minSize` | `number` | `50` | 最小分包大小(KB) |
|
|
147
|
-
| `groups` | `Record<string, (string \| RegExp)[]>` | - | 自定义分组规则 |
|
|
148
|
-
|
|
149
|
-
## 内置预设
|
|
150
|
-
|
|
151
|
-
插件内置了主流框架和库的分包预设:
|
|
152
|
-
|
|
153
|
-
### UI 框架
|
|
154
|
-
- **React**: react, react-dom
|
|
155
|
-
- **Vue**: vue, @vue/*
|
|
156
|
-
- **Angular**: @angular/*
|
|
157
|
-
- **Svelte**: svelte
|
|
158
|
-
|
|
159
|
-
### UI 组件库
|
|
160
|
-
- **Ant Design**: antd, @ant-design/*
|
|
161
|
-
- **Element Plus**: element-plus
|
|
162
|
-
- **Element UI**: element-ui
|
|
163
|
-
- **Naive UI**: naive-ui
|
|
164
|
-
- **Arco Design**: @arco-design/*
|
|
165
|
-
- **Material-UI**: @mui/*, @material-ui/*
|
|
166
|
-
- **Chakra UI**: @chakra-ui/*
|
|
167
|
-
|
|
168
|
-
### 工具库
|
|
169
|
-
- **Lodash**: lodash, lodash-es
|
|
170
|
-
- **Axios**: axios
|
|
171
|
-
- **Moment**: moment
|
|
172
|
-
- **Day.js**: dayjs
|
|
173
|
-
|
|
174
|
-
### 可视化库
|
|
175
|
-
- **Echarts**: echarts
|
|
176
|
-
- **D3**: d3
|
|
177
|
-
- **Chart.js**: chart.js
|
|
178
|
-
|
|
179
|
-
### 3D/游戏引擎
|
|
180
|
-
- **Three.js**: three
|
|
181
|
-
- **Babylon.js**: @babylonjs/*
|
|
182
|
-
|
|
183
|
-
### 其他分组
|
|
184
|
-
- **工具组**: @vueuse/*, ahooks, react-use
|
|
185
|
-
- **图标组**: @iconify/*, @ant-design/icons, lucide-react
|
|
186
|
-
- **表单组**: react-hook-form, formik, async-validator
|
|
187
|
-
- **国际化**: i18next, react-i18next, vue-i18n
|
|
188
|
-
|
|
189
|
-
## 输出结构
|
|
190
|
-
|
|
191
|
-
构建后的文件结构:
|
|
192
|
-
|
|
193
|
-
```
|
|
194
|
-
dist/
|
|
195
|
-
├── js/
|
|
196
|
-
│ ├── index-[hash].js # 入口文件
|
|
197
|
-
│ ├── vendor-[hash].js # 通用依赖
|
|
198
|
-
│ ├── vue-[hash].js # Vue 相关
|
|
199
|
-
│ ├── antd-[hash].js # Ant Design
|
|
200
|
-
│ └── echarts-[hash].js # Echarts
|
|
201
|
-
├── css/
|
|
202
|
-
│ └── index-[hash].css # 样式文件
|
|
203
|
-
├── img/
|
|
204
|
-
│ └── logo-[hash].png # 图片资源
|
|
205
|
-
├── fonts/
|
|
206
|
-
│ └── roboto-[hash].woff2 # 字体文件
|
|
207
|
-
└── assets/
|
|
208
|
-
└── data-[hash].json # 其他资源
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
## 使用场景
|
|
212
|
-
|
|
213
|
-
### 场景 1: React + Ant Design 项目
|
|
214
|
-
|
|
215
|
-
```typescript
|
|
216
|
-
import OPS from 'vite-plugin-ops'
|
|
217
|
-
|
|
218
|
-
export default {
|
|
219
|
-
plugins: [
|
|
220
|
-
react(),
|
|
221
|
-
OPS({
|
|
222
|
-
strategy: 'balanced',
|
|
223
|
-
groups: {
|
|
224
|
-
// 将 Ant Design 图标单独分包
|
|
225
|
-
'antd-icons': ['@ant-design/icons']
|
|
226
|
-
}
|
|
227
|
-
})
|
|
228
|
-
]
|
|
229
|
-
}
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
### 场景 2: Vue 3 + Element Plus 项目
|
|
233
|
-
|
|
234
|
-
```typescript
|
|
235
|
-
import OPS from 'vite-plugin-ops'
|
|
236
|
-
|
|
237
|
-
export default {
|
|
238
|
-
plugins: [
|
|
239
|
-
vue(),
|
|
240
|
-
OPS({
|
|
241
|
-
strategy: 'balanced'
|
|
242
|
-
// 插件会自动检测 Vue 并创建 vue 分组
|
|
243
|
-
})
|
|
244
|
-
]
|
|
245
|
-
}
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
### 场景 3: 数据可视化项目
|
|
249
|
-
|
|
250
|
-
```typescript
|
|
251
|
-
import OPS from 'vite-plugin-ops'
|
|
252
|
-
|
|
253
|
-
export default {
|
|
254
|
-
plugins: [
|
|
255
|
-
OPS({
|
|
256
|
-
strategy: 'balanced',
|
|
257
|
-
groups: {
|
|
258
|
-
// 将所有图表库分到一组
|
|
259
|
-
'charts': ['echarts', 'd3', 'chart.js', '@antv/g2']
|
|
260
|
-
}
|
|
261
|
-
})
|
|
262
|
-
]
|
|
263
|
-
}
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### 场景 4: 多页面应用
|
|
267
|
-
|
|
268
|
-
```typescript
|
|
269
|
-
import OPS from 'vite-plugin-ops'
|
|
270
|
-
|
|
271
|
-
export default {
|
|
272
|
-
build: {
|
|
273
|
-
rollupOptions: {
|
|
274
|
-
input: {
|
|
275
|
-
main: 'index.html',
|
|
276
|
-
admin: 'admin.html'
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
},
|
|
280
|
-
plugins: [
|
|
281
|
-
OPS({
|
|
282
|
-
strategy: 'conservative', // 减少公共依赖重复
|
|
283
|
-
override: false // 不覆盖多入口配置
|
|
284
|
-
})
|
|
285
|
-
]
|
|
286
|
-
}
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
## 高级用法
|
|
290
|
-
|
|
291
|
-
### 自定义分组优先级
|
|
292
|
-
|
|
293
|
-
插件使用优先级系统来处理分组匹配:
|
|
294
|
-
|
|
295
|
-
1. **优先级 100**: 自定义 `groups` 配置
|
|
296
|
-
2. **优先级 90**: 插件自动检测(如 Vue)
|
|
297
|
-
3. **优先级 80**: 大型库预设
|
|
298
|
-
4. **优先级 70**: 中型库分组
|
|
299
|
-
5. **优先级 50**: aggressive 策略的单独依赖
|
|
300
|
-
6. **默认**: vendor 组
|
|
301
|
-
|
|
302
|
-
### 与现有配置合并
|
|
303
|
-
|
|
304
|
-
```typescript
|
|
305
|
-
export default {
|
|
306
|
-
build: {
|
|
307
|
-
rollupOptions: {
|
|
308
|
-
output: {
|
|
309
|
-
// 你的自定义配置
|
|
310
|
-
entryFileNames: 'my-entry-[hash].js'
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
},
|
|
314
|
-
plugins: [
|
|
315
|
-
OPS({
|
|
316
|
-
override: false // 保留你的 entryFileNames 配置
|
|
317
|
-
})
|
|
318
|
-
]
|
|
319
|
-
}
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
### 正则表达式匹配
|
|
323
|
-
|
|
324
|
-
```typescript
|
|
325
|
-
OPS({
|
|
326
|
-
groups: {
|
|
327
|
-
// 匹配所有 @babel 开头的包
|
|
328
|
-
'babel': [/\/@babel\//],
|
|
329
|
-
|
|
330
|
-
// 匹配 lodash 但不包括 lodash-es
|
|
331
|
-
'lodash': [/\/lodash(?!-es)/],
|
|
332
|
-
|
|
333
|
-
// 组合字符串和正则
|
|
334
|
-
'ui-libs': ['antd', /element-/]
|
|
335
|
-
}
|
|
336
|
-
})
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
## 最佳实践
|
|
340
|
-
|
|
341
|
-
### 1. 开发环境使用 aggressive
|
|
342
|
-
|
|
343
|
-
```typescript
|
|
344
|
-
export default defineConfig(({ mode }) => ({
|
|
345
|
-
plugins: [
|
|
346
|
-
OPS({
|
|
347
|
-
strategy: mode === 'development' ? 'aggressive' : 'balanced'
|
|
348
|
-
})
|
|
349
|
-
]
|
|
350
|
-
}))
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### 2. 分析构建产物
|
|
354
|
-
|
|
355
|
-
使用 `rollup-plugin-visualizer` 查看分包效果:
|
|
356
|
-
|
|
357
|
-
```typescript
|
|
358
|
-
import { visualizer } from 'rollup-plugin-visualizer'
|
|
359
|
-
import OPS from 'vite-plugin-ops'
|
|
360
|
-
|
|
361
|
-
export default {
|
|
362
|
-
plugins: [
|
|
363
|
-
OPS({ strategy: 'balanced' }),
|
|
364
|
-
visualizer({ open: true })
|
|
365
|
-
]
|
|
366
|
-
}
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
### 3. 监控构建信息
|
|
370
|
-
|
|
371
|
-
插件会在构建时输出分包信息:
|
|
372
|
-
|
|
373
|
-
```bash
|
|
374
|
-
📦 OPS Chunking Strategy: Balanced (split large libraries)
|
|
375
|
-
📊 Detected 12 chunk groups
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
### 4. 针对性能优化
|
|
379
|
-
|
|
380
|
-
根据实际加载性能调整策略:
|
|
381
|
-
|
|
382
|
-
- **首屏加载慢** → 使用 `conservative` 减少请求数
|
|
383
|
-
- **大依赖更新频繁** → 使用 `balanced` 独立缓存
|
|
384
|
-
- **需要精细控制** → 使用 `aggressive` + 自定义 `groups`
|
|
385
|
-
|
|
386
|
-
## 注意事项
|
|
387
|
-
|
|
388
|
-
1. **仅适用于 Vite 项目** - 此插件基于 Vite 插件系统
|
|
389
|
-
2. **不支持 Webpack** - 需要 Webpack 版本请使用其他工具
|
|
390
|
-
3. **Type 类型包** - 自动忽略 `@types/*` 包
|
|
391
|
-
4. **Monorepo** - 确保在正确的 package.json 位置读取依赖
|
|
392
|
-
|
|
393
|
-
## 贡献
|
|
394
|
-
|
|
395
|
-
欢迎提交 Issue 和 Pull Request!
|
|
396
|
-
|
|
397
|
-
## 许可
|
|
398
|
-
|
|
399
|
-
MIT License
|
|
400
|
-
|
|
401
|
-
## 相关链接
|
|
402
|
-
|
|
403
|
-
- [Vite 官方文档](https://vitejs.dev/)
|
|
404
|
-
- [Rollup 文档](https://rollupjs.org/)
|
|
405
|
-
- [问题反馈](https://github.com/suileyan/vite-plugin-ops/issues)
|
|
406
|
-
|
|
407
|
-
---
|
|
408
|
-
|
|
409
|
-
Made with by suileyan
|
|
1
|
+
# vite-plugin-ops [](https://zread.ai/suileyan/vite-plugin-ops)
|
|
2
|
+
|
|
3
|
+
**O**ptimized **P**ackaging **S**trategy - 一个智能的 Vite 分包优化插件
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/vite-plugin-ops)
|
|
6
|
+
[](https://github.com/suileyan/vite-plugin-ops/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
## 特性
|
|
9
|
+
|
|
10
|
+
- **智能分包策略** - 三种预设策略适配不同场景
|
|
11
|
+
- **自动识别依赖** - 无需手动配置,自动读取 package.json
|
|
12
|
+
- **框架预设** - 内置主流框架和库的最佳分包方案
|
|
13
|
+
- **高度可配置** - 支持自定义分包规则
|
|
14
|
+
- **优先级系统** - 灵活的匹配优先级机制
|
|
15
|
+
- **资源分类** - 自动将 CSS、图片、字体分类存放
|
|
16
|
+
- **零配置可用** - 开箱即用,合理的默认配置
|
|
17
|
+
|
|
18
|
+
## 安装
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install vite-plugin-ops -D
|
|
22
|
+
# 或
|
|
23
|
+
pnpm add vite-plugin-ops -D
|
|
24
|
+
# 或
|
|
25
|
+
yarn add vite-plugin-ops -D
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 快速开始
|
|
29
|
+
|
|
30
|
+
### 基础使用
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// vite.config.ts
|
|
34
|
+
import { defineConfig } from 'vite'
|
|
35
|
+
import vue from '@vitejs/plugin-vue'
|
|
36
|
+
import OPS from 'vite-plugin-ops'
|
|
37
|
+
|
|
38
|
+
export default defineConfig({
|
|
39
|
+
plugins: [
|
|
40
|
+
vue(),
|
|
41
|
+
OPS() // 使用默认配置
|
|
42
|
+
]
|
|
43
|
+
})
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
插件会自动:
|
|
47
|
+
- 将 node_modules 中的依赖智能分包
|
|
48
|
+
- 将 CSS 文件放入 `css/` 目录
|
|
49
|
+
- 将图片放入 `img/` 目录
|
|
50
|
+
- 将字体放入 `fonts/` 目录
|
|
51
|
+
- 将其他资源放入 `assets/` 目录
|
|
52
|
+
|
|
53
|
+
## 分包策略
|
|
54
|
+
|
|
55
|
+
插件提供三种分包策略,适用于不同场景:
|
|
56
|
+
|
|
57
|
+
### 1. Balanced(平衡 - 默认推荐)
|
|
58
|
+
|
|
59
|
+
适合大多数生产环境,平衡构建速度和加载性能。
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
OPS({
|
|
63
|
+
strategy: 'balanced' // 默认值,可省略
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**特点:**
|
|
68
|
+
- 大型库独立分包(React、Vue、Antd、Echarts 等)
|
|
69
|
+
- 中型库按类型分组(工具库、图标库、表单库等)
|
|
70
|
+
- 小型库合并到 vendor
|
|
71
|
+
- 典型输出:5-15 个 chunk
|
|
72
|
+
|
|
73
|
+
**适用场景:** 生产环境、中大型项目
|
|
74
|
+
|
|
75
|
+
### 2. Aggressive(激进)
|
|
76
|
+
|
|
77
|
+
每个依赖都独立分包,适合开发调试。
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
OPS({
|
|
81
|
+
strategy: 'aggressive'
|
|
82
|
+
})
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**特点:**
|
|
86
|
+
- 每个依赖独立成一个 chunk
|
|
87
|
+
- 便于查看单个依赖的体积
|
|
88
|
+
- 可能产生大量小文件
|
|
89
|
+
- 典型输出:20-50+ 个 chunk
|
|
90
|
+
|
|
91
|
+
**适用场景:** 开发环境、依赖分析
|
|
92
|
+
|
|
93
|
+
### 3. Conservative(保守)
|
|
94
|
+
|
|
95
|
+
最小化分包,减少 HTTP 请求。
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
OPS({
|
|
99
|
+
strategy: 'conservative'
|
|
100
|
+
})
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**特点:**
|
|
104
|
+
- 只分离超大型库(React、Vue、Antd、Echarts 等)
|
|
105
|
+
- 其他库合并到 vendor
|
|
106
|
+
- 减少 HTTP 请求数量
|
|
107
|
+
- 典型输出:3-8 个 chunk
|
|
108
|
+
|
|
109
|
+
**适用场景:** 小型项目、HTTP/1.x 环境
|
|
110
|
+
|
|
111
|
+
## 配置选项
|
|
112
|
+
|
|
113
|
+
### 完整配置示例
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
OPS({
|
|
117
|
+
// 分包策略
|
|
118
|
+
strategy: 'balanced', // 'aggressive' | 'balanced' | 'conservative'
|
|
119
|
+
|
|
120
|
+
// 是否覆盖用户已有的 rollupOptions.output 配置
|
|
121
|
+
override: false,
|
|
122
|
+
|
|
123
|
+
// 最小分包大小(KB),仅在 balanced 和 conservative 策略下生效
|
|
124
|
+
minSize: 50,
|
|
125
|
+
|
|
126
|
+
// 自定义分组规则
|
|
127
|
+
groups: {
|
|
128
|
+
// 将 lodash 相关库独立分包
|
|
129
|
+
'lodash': ['lodash', 'lodash-es'],
|
|
130
|
+
|
|
131
|
+
// 使用正则匹配
|
|
132
|
+
'my-ui': [/my-ui-library/],
|
|
133
|
+
|
|
134
|
+
// 将多个相关库分到一组
|
|
135
|
+
'charts': ['echarts', 'chart.js', 'd3']
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 配置项说明
|
|
141
|
+
|
|
142
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
143
|
+
|------|------|--------|------|
|
|
144
|
+
| `strategy` | `'aggressive' \| 'balanced' \| 'conservative'` | `'balanced'` | 分包策略 |
|
|
145
|
+
| `override` | `boolean` | `false` | 是否覆盖已有配置 |
|
|
146
|
+
| `minSize` | `number` | `50` | 最小分包大小(KB) |
|
|
147
|
+
| `groups` | `Record<string, (string \| RegExp)[]>` | - | 自定义分组规则 |
|
|
148
|
+
|
|
149
|
+
## 内置预设
|
|
150
|
+
|
|
151
|
+
插件内置了主流框架和库的分包预设:
|
|
152
|
+
|
|
153
|
+
### UI 框架
|
|
154
|
+
- **React**: react, react-dom
|
|
155
|
+
- **Vue**: vue, @vue/*
|
|
156
|
+
- **Angular**: @angular/*
|
|
157
|
+
- **Svelte**: svelte
|
|
158
|
+
|
|
159
|
+
### UI 组件库
|
|
160
|
+
- **Ant Design**: antd, @ant-design/*
|
|
161
|
+
- **Element Plus**: element-plus
|
|
162
|
+
- **Element UI**: element-ui
|
|
163
|
+
- **Naive UI**: naive-ui
|
|
164
|
+
- **Arco Design**: @arco-design/*
|
|
165
|
+
- **Material-UI**: @mui/*, @material-ui/*
|
|
166
|
+
- **Chakra UI**: @chakra-ui/*
|
|
167
|
+
|
|
168
|
+
### 工具库
|
|
169
|
+
- **Lodash**: lodash, lodash-es
|
|
170
|
+
- **Axios**: axios
|
|
171
|
+
- **Moment**: moment
|
|
172
|
+
- **Day.js**: dayjs
|
|
173
|
+
|
|
174
|
+
### 可视化库
|
|
175
|
+
- **Echarts**: echarts
|
|
176
|
+
- **D3**: d3
|
|
177
|
+
- **Chart.js**: chart.js
|
|
178
|
+
|
|
179
|
+
### 3D/游戏引擎
|
|
180
|
+
- **Three.js**: three
|
|
181
|
+
- **Babylon.js**: @babylonjs/*
|
|
182
|
+
|
|
183
|
+
### 其他分组
|
|
184
|
+
- **工具组**: @vueuse/*, ahooks, react-use
|
|
185
|
+
- **图标组**: @iconify/*, @ant-design/icons, lucide-react
|
|
186
|
+
- **表单组**: react-hook-form, formik, async-validator
|
|
187
|
+
- **国际化**: i18next, react-i18next, vue-i18n
|
|
188
|
+
|
|
189
|
+
## 输出结构
|
|
190
|
+
|
|
191
|
+
构建后的文件结构:
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
dist/
|
|
195
|
+
├── js/
|
|
196
|
+
│ ├── index-[hash].js # 入口文件
|
|
197
|
+
│ ├── vendor-[hash].js # 通用依赖
|
|
198
|
+
│ ├── vue-[hash].js # Vue 相关
|
|
199
|
+
│ ├── antd-[hash].js # Ant Design
|
|
200
|
+
│ └── echarts-[hash].js # Echarts
|
|
201
|
+
├── css/
|
|
202
|
+
│ └── index-[hash].css # 样式文件
|
|
203
|
+
├── img/
|
|
204
|
+
│ └── logo-[hash].png # 图片资源
|
|
205
|
+
├── fonts/
|
|
206
|
+
│ └── roboto-[hash].woff2 # 字体文件
|
|
207
|
+
└── assets/
|
|
208
|
+
└── data-[hash].json # 其他资源
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## 使用场景
|
|
212
|
+
|
|
213
|
+
### 场景 1: React + Ant Design 项目
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
import OPS from 'vite-plugin-ops'
|
|
217
|
+
|
|
218
|
+
export default {
|
|
219
|
+
plugins: [
|
|
220
|
+
react(),
|
|
221
|
+
OPS({
|
|
222
|
+
strategy: 'balanced',
|
|
223
|
+
groups: {
|
|
224
|
+
// 将 Ant Design 图标单独分包
|
|
225
|
+
'antd-icons': ['@ant-design/icons']
|
|
226
|
+
}
|
|
227
|
+
})
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### 场景 2: Vue 3 + Element Plus 项目
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import OPS from 'vite-plugin-ops'
|
|
236
|
+
|
|
237
|
+
export default {
|
|
238
|
+
plugins: [
|
|
239
|
+
vue(),
|
|
240
|
+
OPS({
|
|
241
|
+
strategy: 'balanced'
|
|
242
|
+
// 插件会自动检测 Vue 并创建 vue 分组
|
|
243
|
+
})
|
|
244
|
+
]
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### 场景 3: 数据可视化项目
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
import OPS from 'vite-plugin-ops'
|
|
252
|
+
|
|
253
|
+
export default {
|
|
254
|
+
plugins: [
|
|
255
|
+
OPS({
|
|
256
|
+
strategy: 'balanced',
|
|
257
|
+
groups: {
|
|
258
|
+
// 将所有图表库分到一组
|
|
259
|
+
'charts': ['echarts', 'd3', 'chart.js', '@antv/g2']
|
|
260
|
+
}
|
|
261
|
+
})
|
|
262
|
+
]
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### 场景 4: 多页面应用
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
import OPS from 'vite-plugin-ops'
|
|
270
|
+
|
|
271
|
+
export default {
|
|
272
|
+
build: {
|
|
273
|
+
rollupOptions: {
|
|
274
|
+
input: {
|
|
275
|
+
main: 'index.html',
|
|
276
|
+
admin: 'admin.html'
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
plugins: [
|
|
281
|
+
OPS({
|
|
282
|
+
strategy: 'conservative', // 减少公共依赖重复
|
|
283
|
+
override: false // 不覆盖多入口配置
|
|
284
|
+
})
|
|
285
|
+
]
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## 高级用法
|
|
290
|
+
|
|
291
|
+
### 自定义分组优先级
|
|
292
|
+
|
|
293
|
+
插件使用优先级系统来处理分组匹配:
|
|
294
|
+
|
|
295
|
+
1. **优先级 100**: 自定义 `groups` 配置
|
|
296
|
+
2. **优先级 90**: 插件自动检测(如 Vue)
|
|
297
|
+
3. **优先级 80**: 大型库预设
|
|
298
|
+
4. **优先级 70**: 中型库分组
|
|
299
|
+
5. **优先级 50**: aggressive 策略的单独依赖
|
|
300
|
+
6. **默认**: vendor 组
|
|
301
|
+
|
|
302
|
+
### 与现有配置合并
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
export default {
|
|
306
|
+
build: {
|
|
307
|
+
rollupOptions: {
|
|
308
|
+
output: {
|
|
309
|
+
// 你的自定义配置
|
|
310
|
+
entryFileNames: 'my-entry-[hash].js'
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
plugins: [
|
|
315
|
+
OPS({
|
|
316
|
+
override: false // 保留你的 entryFileNames 配置
|
|
317
|
+
})
|
|
318
|
+
]
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### 正则表达式匹配
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
OPS({
|
|
326
|
+
groups: {
|
|
327
|
+
// 匹配所有 @babel 开头的包
|
|
328
|
+
'babel': [/\/@babel\//],
|
|
329
|
+
|
|
330
|
+
// 匹配 lodash 但不包括 lodash-es
|
|
331
|
+
'lodash': [/\/lodash(?!-es)/],
|
|
332
|
+
|
|
333
|
+
// 组合字符串和正则
|
|
334
|
+
'ui-libs': ['antd', /element-/]
|
|
335
|
+
}
|
|
336
|
+
})
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## 最佳实践
|
|
340
|
+
|
|
341
|
+
### 1. 开发环境使用 aggressive
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
export default defineConfig(({ mode }) => ({
|
|
345
|
+
plugins: [
|
|
346
|
+
OPS({
|
|
347
|
+
strategy: mode === 'development' ? 'aggressive' : 'balanced'
|
|
348
|
+
})
|
|
349
|
+
]
|
|
350
|
+
}))
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### 2. 分析构建产物
|
|
354
|
+
|
|
355
|
+
使用 `rollup-plugin-visualizer` 查看分包效果:
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
import { visualizer } from 'rollup-plugin-visualizer'
|
|
359
|
+
import OPS from 'vite-plugin-ops'
|
|
360
|
+
|
|
361
|
+
export default {
|
|
362
|
+
plugins: [
|
|
363
|
+
OPS({ strategy: 'balanced' }),
|
|
364
|
+
visualizer({ open: true })
|
|
365
|
+
]
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### 3. 监控构建信息
|
|
370
|
+
|
|
371
|
+
插件会在构建时输出分包信息:
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
📦 OPS Chunking Strategy: Balanced (split large libraries)
|
|
375
|
+
📊 Detected 12 chunk groups
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### 4. 针对性能优化
|
|
379
|
+
|
|
380
|
+
根据实际加载性能调整策略:
|
|
381
|
+
|
|
382
|
+
- **首屏加载慢** → 使用 `conservative` 减少请求数
|
|
383
|
+
- **大依赖更新频繁** → 使用 `balanced` 独立缓存
|
|
384
|
+
- **需要精细控制** → 使用 `aggressive` + 自定义 `groups`
|
|
385
|
+
|
|
386
|
+
## 注意事项
|
|
387
|
+
|
|
388
|
+
1. **仅适用于 Vite 项目** - 此插件基于 Vite 插件系统
|
|
389
|
+
2. **不支持 Webpack** - 需要 Webpack 版本请使用其他工具
|
|
390
|
+
3. **Type 类型包** - 自动忽略 `@types/*` 包
|
|
391
|
+
4. **Monorepo** - 确保在正确的 package.json 位置读取依赖
|
|
392
|
+
|
|
393
|
+
## 贡献
|
|
394
|
+
|
|
395
|
+
欢迎提交 Issue 和 Pull Request!
|
|
396
|
+
|
|
397
|
+
## 许可
|
|
398
|
+
|
|
399
|
+
MIT License
|
|
400
|
+
|
|
401
|
+
## 相关链接
|
|
402
|
+
|
|
403
|
+
- [Vite 官方文档](https://vitejs.dev/)
|
|
404
|
+
- [Rollup 文档](https://rollupjs.org/)
|
|
405
|
+
- [问题反馈](https://github.com/suileyan/vite-plugin-ops/issues)
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
Made with by suileyan
|
package/dist/index.cjs
CHANGED
|
@@ -51,25 +51,66 @@ var MEDIUM_LIB_GROUPS = {
|
|
|
51
51
|
"form": ["react-hook-form", "formik", "async-validator"],
|
|
52
52
|
"i18n": ["i18next", "react-i18next", "vue-i18n"]
|
|
53
53
|
};
|
|
54
|
+
var patternCache = /* @__PURE__ */ new Map();
|
|
55
|
+
var MAX_PATH_LENGTH = 2e3;
|
|
54
56
|
function normalizeId(id) {
|
|
55
57
|
return id.replace(/\\/g, "/").replace(/%5C/g, "/");
|
|
56
58
|
}
|
|
57
59
|
function makeNodeModulesPattern(pkg) {
|
|
58
60
|
if (pkg instanceof RegExp) {
|
|
59
|
-
return (id) =>
|
|
61
|
+
return (id) => {
|
|
62
|
+
if (id.length > MAX_PATH_LENGTH) {
|
|
63
|
+
console.warn(`[vite-plugin-ops] Path too long (${id.length} chars), skipping: ${id.slice(0, 50)}...`);
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
return pkg.test(id);
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
let re = patternCache.get(pkg);
|
|
70
|
+
if (!re) {
|
|
71
|
+
const scoped = pkg.startsWith("@");
|
|
72
|
+
const escaped = pkg.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&");
|
|
73
|
+
const base = scoped ? escaped : `(?:@[^/]+/)?${escaped}`;
|
|
74
|
+
re = new RegExp(`/node_modules/(?:[.]pnpm/)?(?:${base})(?:/|@|$)`, "i");
|
|
75
|
+
patternCache.set(pkg, re);
|
|
60
76
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
77
|
+
return (id) => {
|
|
78
|
+
if (id.length > MAX_PATH_LENGTH) {
|
|
79
|
+
console.warn(`[vite-plugin-ops] Path too long (${id.length} chars), skipping: ${id.slice(0, 50)}...`);
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return re.test(id);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function isValidPackageJson(obj) {
|
|
86
|
+
if (typeof obj !== "object" || obj === null) return false;
|
|
87
|
+
const json = obj;
|
|
88
|
+
if (json.dependencies !== void 0) {
|
|
89
|
+
if (typeof json.dependencies !== "object" || json.dependencies === null) return false;
|
|
90
|
+
for (const val of Object.values(json.dependencies)) {
|
|
91
|
+
if (typeof val !== "string") return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return true;
|
|
66
95
|
}
|
|
67
96
|
function readProjectDependencies(cwd) {
|
|
68
97
|
try {
|
|
69
98
|
const pkgPath = path__default.default.join(cwd, "package.json");
|
|
70
|
-
const
|
|
99
|
+
const content = fs__default.default.readFileSync(pkgPath, "utf8");
|
|
100
|
+
const json = JSON.parse(content);
|
|
101
|
+
if (!isValidPackageJson(json)) {
|
|
102
|
+
console.warn("[vite-plugin-ops] Invalid package.json format: dependencies field is malformed");
|
|
103
|
+
return /* @__PURE__ */ new Set();
|
|
104
|
+
}
|
|
71
105
|
return new Set(Object.keys(json.dependencies || {}));
|
|
72
|
-
} catch {
|
|
106
|
+
} catch (error) {
|
|
107
|
+
if (error instanceof SyntaxError) {
|
|
108
|
+
console.warn("[vite-plugin-ops] Failed to parse package.json: Invalid JSON format");
|
|
109
|
+
} else if (error.code === "ENOENT") {
|
|
110
|
+
console.warn("[vite-plugin-ops] package.json not found in:", cwd);
|
|
111
|
+
} else if (process.env.DEBUG) {
|
|
112
|
+
console.warn("[vite-plugin-ops] Failed to read package.json:", error);
|
|
113
|
+
}
|
|
73
114
|
return /* @__PURE__ */ new Set();
|
|
74
115
|
}
|
|
75
116
|
}
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -44,25 +44,66 @@ var MEDIUM_LIB_GROUPS = {
|
|
|
44
44
|
"form": ["react-hook-form", "formik", "async-validator"],
|
|
45
45
|
"i18n": ["i18next", "react-i18next", "vue-i18n"]
|
|
46
46
|
};
|
|
47
|
+
var patternCache = /* @__PURE__ */ new Map();
|
|
48
|
+
var MAX_PATH_LENGTH = 2e3;
|
|
47
49
|
function normalizeId(id) {
|
|
48
50
|
return id.replace(/\\/g, "/").replace(/%5C/g, "/");
|
|
49
51
|
}
|
|
50
52
|
function makeNodeModulesPattern(pkg) {
|
|
51
53
|
if (pkg instanceof RegExp) {
|
|
52
|
-
return (id) =>
|
|
54
|
+
return (id) => {
|
|
55
|
+
if (id.length > MAX_PATH_LENGTH) {
|
|
56
|
+
console.warn(`[vite-plugin-ops] Path too long (${id.length} chars), skipping: ${id.slice(0, 50)}...`);
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return pkg.test(id);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
let re = patternCache.get(pkg);
|
|
63
|
+
if (!re) {
|
|
64
|
+
const scoped = pkg.startsWith("@");
|
|
65
|
+
const escaped = pkg.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&");
|
|
66
|
+
const base = scoped ? escaped : `(?:@[^/]+/)?${escaped}`;
|
|
67
|
+
re = new RegExp(`/node_modules/(?:[.]pnpm/)?(?:${base})(?:/|@|$)`, "i");
|
|
68
|
+
patternCache.set(pkg, re);
|
|
53
69
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
70
|
+
return (id) => {
|
|
71
|
+
if (id.length > MAX_PATH_LENGTH) {
|
|
72
|
+
console.warn(`[vite-plugin-ops] Path too long (${id.length} chars), skipping: ${id.slice(0, 50)}...`);
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return re.test(id);
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function isValidPackageJson(obj) {
|
|
79
|
+
if (typeof obj !== "object" || obj === null) return false;
|
|
80
|
+
const json = obj;
|
|
81
|
+
if (json.dependencies !== void 0) {
|
|
82
|
+
if (typeof json.dependencies !== "object" || json.dependencies === null) return false;
|
|
83
|
+
for (const val of Object.values(json.dependencies)) {
|
|
84
|
+
if (typeof val !== "string") return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
59
88
|
}
|
|
60
89
|
function readProjectDependencies(cwd) {
|
|
61
90
|
try {
|
|
62
91
|
const pkgPath = path.join(cwd, "package.json");
|
|
63
|
-
const
|
|
92
|
+
const content = fs.readFileSync(pkgPath, "utf8");
|
|
93
|
+
const json = JSON.parse(content);
|
|
94
|
+
if (!isValidPackageJson(json)) {
|
|
95
|
+
console.warn("[vite-plugin-ops] Invalid package.json format: dependencies field is malformed");
|
|
96
|
+
return /* @__PURE__ */ new Set();
|
|
97
|
+
}
|
|
64
98
|
return new Set(Object.keys(json.dependencies || {}));
|
|
65
|
-
} catch {
|
|
99
|
+
} catch (error) {
|
|
100
|
+
if (error instanceof SyntaxError) {
|
|
101
|
+
console.warn("[vite-plugin-ops] Failed to parse package.json: Invalid JSON format");
|
|
102
|
+
} else if (error.code === "ENOENT") {
|
|
103
|
+
console.warn("[vite-plugin-ops] package.json not found in:", cwd);
|
|
104
|
+
} else if (process.env.DEBUG) {
|
|
105
|
+
console.warn("[vite-plugin-ops] Failed to read package.json:", error);
|
|
106
|
+
}
|
|
66
107
|
return /* @__PURE__ */ new Set();
|
|
67
108
|
}
|
|
68
109
|
}
|
package/package.json
CHANGED
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "vite-plugin-ops",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Vite plugin to organize build outputs and vendor chunking.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"author": "suileyan",
|
|
8
|
-
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"types": "./dist/index.d.ts",
|
|
12
|
-
"import": "./dist/index.js",
|
|
13
|
-
"require": "./dist/index.cjs"
|
|
14
|
-
},
|
|
15
|
-
"./package.json": "./package.json"
|
|
16
|
-
},
|
|
17
|
-
"main": "dist/index.cjs",
|
|
18
|
-
"types": "dist/index.d.ts",
|
|
19
|
-
|
|
20
|
-
"files": ["dist", "README.md", "LICENSE"],
|
|
21
|
-
|
|
22
|
-
"sideEffects": false,
|
|
23
|
-
"engines": {
|
|
24
|
-
"node": ">=20.19"
|
|
25
|
-
},
|
|
26
|
-
|
|
27
|
-
"keywords": ["vite", "vite-plugin", "rollup", "chunks", "vendor", "build"],
|
|
28
|
-
|
|
29
|
-
"repository": { "type": "git", "url": "git+https://github.com/suileyan/vite-plugin-ops.git" },
|
|
30
|
-
"bugs": { "url": "https://github.com/suileyan/vite-plugin-ops/issues" },
|
|
31
|
-
"homepage": "https://github.com/suileyan/vite-plugin-ops#readme",
|
|
32
|
-
|
|
33
|
-
"peerDependencies": {
|
|
34
|
-
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
35
|
-
},
|
|
36
|
-
"devDependencies": {
|
|
37
|
-
"@types/node": "^24.6.0",
|
|
38
|
-
"rimraf": "^6.0.1",
|
|
39
|
-
"tsup": "^8.5.0",
|
|
40
|
-
"typescript": "^5.9.2",
|
|
41
|
-
"vite": "^7.1
|
|
42
|
-
"rollup": "^4.0.0"
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
"scripts": {
|
|
46
|
-
"build": "tsup",
|
|
47
|
-
"dev": "tsup --watch --sourcemap",
|
|
48
|
-
"clean": "rimraf dist || rmdir /s /q dist",
|
|
49
|
-
"prepublishOnly": "npm run clean && npm run build"
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
"publishConfig": {
|
|
53
|
-
"access": "public",
|
|
54
|
-
"registry": "https://registry.npmjs.org/"
|
|
55
|
-
}
|
|
56
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "vite-plugin-ops",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Vite plugin to organize build outputs and vendor chunking.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "suileyan",
|
|
8
|
+
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"main": "dist/index.cjs",
|
|
18
|
+
"types": "dist/index.d.ts",
|
|
19
|
+
|
|
20
|
+
"files": ["dist", "README.md", "LICENSE"],
|
|
21
|
+
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=20.19"
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
"keywords": ["vite", "vite-plugin", "rollup", "chunks", "vendor", "build"],
|
|
28
|
+
|
|
29
|
+
"repository": { "type": "git", "url": "git+https://github.com/suileyan/vite-plugin-ops.git" },
|
|
30
|
+
"bugs": { "url": "https://github.com/suileyan/vite-plugin-ops/issues" },
|
|
31
|
+
"homepage": "https://github.com/suileyan/vite-plugin-ops#readme",
|
|
32
|
+
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^24.6.0",
|
|
38
|
+
"rimraf": "^6.0.1",
|
|
39
|
+
"tsup": "^8.5.0",
|
|
40
|
+
"typescript": "^5.9.2",
|
|
41
|
+
"vite": "^7.3.1",
|
|
42
|
+
"rollup": "^4.0.0"
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsup",
|
|
47
|
+
"dev": "tsup --watch --sourcemap",
|
|
48
|
+
"clean": "rimraf dist || rmdir /s /q dist",
|
|
49
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public",
|
|
54
|
+
"registry": "https://registry.npmjs.org/"
|
|
55
|
+
}
|
|
56
|
+
}
|