nuxt-gin-tools 0.2.18 → 0.2.20
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 +394 -69
- package/commands/pack.d.ts +5 -53
- package/commands/pack.js +118 -3
- package/package.json +3 -2
- package/src/pack.d.ts +55 -0
- package/src/pack.js +7 -0
package/README.md
CHANGED
|
@@ -1,102 +1,426 @@
|
|
|
1
|
-
# nuxt-gin-tools
|
|
1
|
+
# nuxt-gin-tools 🧰
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/nuxt-gin-tools)
|
|
4
|
+
[](https://www.npmjs.com/package/nuxt-gin-tools)
|
|
5
|
+
[](https://nodejs.org)
|
|
6
|
+
[](https://nuxt.com)
|
|
7
|
+
[](https://go.dev)
|
|
8
|
+
[](./LICENSE)
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
- 一条命令启动前后端开发环境
|
|
7
|
-
- 自动处理 Go 侧依赖和文件监听重启
|
|
8
|
-
- 提供 OpenAPI 代码生成与构建打包辅助
|
|
10
|
+
`nuxt-gin-tools` is the companion CLI for [`nuxt-gin-starter`](https://github.com/RapboyGao/nuxt-gin-starter.git), built to make **Nuxt + Gin** development feel like one coherent workflow instead of two separate toolchains.
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
Quick Jump:
|
|
11
13
|
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
- 启动 Go 文件监听(基于 `chokidar`)
|
|
15
|
-
- Go 文件变化后自动重启 `go run main.go`
|
|
16
|
-
- `nuxt-gin install`
|
|
17
|
-
- 执行 Nuxt prepare
|
|
18
|
-
- 如果检测到 Go,则执行 `go mod download && go mod tidy`
|
|
19
|
-
- `nuxt-gin gen`
|
|
20
|
-
- 基于 `openapi.yaml` 生成 Go / TS API 代码
|
|
21
|
-
- `nuxt-gin build`
|
|
22
|
-
- 执行项目构建与打包流程
|
|
23
|
-
- `nuxt-gin cleanup`
|
|
24
|
-
- 清理开发产物
|
|
25
|
-
- `nuxt-gin update`
|
|
26
|
-
- 执行依赖更新流程
|
|
14
|
+
- [English](#english)
|
|
15
|
+
- [中文](#中文)
|
|
27
16
|
|
|
28
|
-
##
|
|
17
|
+
## English
|
|
29
18
|
|
|
30
|
-
|
|
19
|
+
### ✨ Highlights
|
|
20
|
+
|
|
21
|
+
- 🚀 One command to run Nuxt dev + Go watcher together
|
|
22
|
+
- 🔁 Automatic Go restart on file changes with `chokidar`
|
|
23
|
+
- 📦 Build-and-pack workflow for deployment artifacts
|
|
24
|
+
- 🧩 `pack.config.ts` support with typed config helper
|
|
25
|
+
- 🛡️ Config validation with `warn` and `error` feedback
|
|
26
|
+
- 🔧 Useful CLI switches for partial workflows like `--skip-go`
|
|
27
|
+
|
|
28
|
+
### 📦 Install
|
|
31
29
|
|
|
32
30
|
```bash
|
|
33
|
-
pnpm add nuxt-gin-tools
|
|
31
|
+
pnpm add -D nuxt-gin-tools
|
|
34
32
|
```
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
### ⚡ Quick Start
|
|
37
35
|
|
|
38
36
|
```bash
|
|
39
|
-
#
|
|
37
|
+
# optional bootstrap
|
|
40
38
|
nuxt-gin install
|
|
41
39
|
|
|
42
|
-
#
|
|
40
|
+
# start Nuxt + Go together
|
|
43
41
|
nuxt-gin dev
|
|
44
42
|
```
|
|
45
43
|
|
|
46
|
-
|
|
44
|
+
Common variants:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# frontend only
|
|
48
|
+
nuxt-gin dev --skip-go
|
|
49
|
+
|
|
50
|
+
# go watcher only
|
|
51
|
+
nuxt-gin dev --skip-nuxt
|
|
52
|
+
|
|
53
|
+
# skip cleanup / bootstrap checks
|
|
54
|
+
nuxt-gin dev --no-cleanup
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 🗂️ Commands
|
|
58
|
+
|
|
59
|
+
#### `nuxt-gin dev`
|
|
60
|
+
|
|
61
|
+
Runs the local development stack:
|
|
62
|
+
|
|
63
|
+
- Nuxt: `npx nuxt dev --port=<nuxtPort> --host`
|
|
64
|
+
- Go: watches files and restarts `go run main.go`
|
|
65
|
+
|
|
66
|
+
Flags:
|
|
67
|
+
|
|
68
|
+
- `--skip-go`: start Nuxt only
|
|
69
|
+
- `--skip-nuxt`: start Go only
|
|
70
|
+
- `--no-cleanup`: skip pre-cleanup and bootstrap checks
|
|
71
|
+
|
|
72
|
+
#### `nuxt-gin install`
|
|
73
|
+
|
|
74
|
+
Bootstraps the project:
|
|
75
|
+
|
|
76
|
+
- always runs `npx nuxt prepare`
|
|
77
|
+
- if Go is available, also runs `go mod download && go mod tidy`
|
|
78
|
+
|
|
79
|
+
#### `nuxt-gin gen`
|
|
80
|
+
|
|
81
|
+
Generates API code from `openapi.yaml`:
|
|
82
|
+
|
|
83
|
+
- Go Gin server code
|
|
84
|
+
- TypeScript axios client code
|
|
85
|
+
|
|
86
|
+
#### `nuxt-gin build`
|
|
87
|
+
|
|
88
|
+
Runs the build-and-pack flow.
|
|
89
|
+
|
|
90
|
+
Flags:
|
|
91
|
+
|
|
92
|
+
- `--skip-go`: skip Go build
|
|
93
|
+
- `--skip-nuxt`: skip Nuxt static build
|
|
94
|
+
- `--binary-name <name>`: override the Go binary name under `.build/.server`
|
|
95
|
+
|
|
96
|
+
#### `nuxt-gin cleanup`
|
|
97
|
+
|
|
98
|
+
Removes generated temp files and build output.
|
|
99
|
+
|
|
100
|
+
#### `nuxt-gin update`
|
|
101
|
+
|
|
102
|
+
Updates project dependencies with a conservative default strategy:
|
|
103
|
+
|
|
104
|
+
- Node: `pnpm update`
|
|
105
|
+
- Go: `go get -u=patch ./... && go mod tidy`
|
|
106
|
+
|
|
107
|
+
Flags:
|
|
108
|
+
|
|
109
|
+
- `--latest`: switch to a more aggressive upgrade strategy
|
|
110
|
+
- `--skip-go`: skip Go dependency updates
|
|
111
|
+
- `--skip-node`: skip Node dependency updates
|
|
112
|
+
|
|
113
|
+
### 🧩 `pack.config.ts` / `pack.config.json`
|
|
114
|
+
|
|
115
|
+
`nuxt-gin build` can auto-load pack config from the project root with this priority:
|
|
116
|
+
|
|
117
|
+
1. `pack.config.ts`
|
|
118
|
+
2. `pack.config.js`
|
|
119
|
+
3. `pack.config.cjs`
|
|
120
|
+
4. `pack.config.mjs`
|
|
121
|
+
5. `pack.config.json`
|
|
122
|
+
|
|
123
|
+
If multiple config files exist, the CLI prints a `warn` and uses the first one by priority.
|
|
124
|
+
|
|
125
|
+
Recommended TypeScript form:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import createPackConfig from 'nuxt-gin-tools/src/pack';
|
|
129
|
+
|
|
130
|
+
export default createPackConfig({
|
|
131
|
+
zipName: 'server.7z',
|
|
132
|
+
extraFilesGlobs: ['prisma/**'],
|
|
133
|
+
packageJson: {
|
|
134
|
+
private: true,
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Legacy JSON is still supported:
|
|
140
|
+
|
|
141
|
+
```json
|
|
142
|
+
{
|
|
143
|
+
"zipName": "server.7z",
|
|
144
|
+
"extraFilesGlobs": ["prisma/**"]
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Validation behavior:
|
|
149
|
+
|
|
150
|
+
- ❌ obvious type problems produce an `error` and stop packing
|
|
151
|
+
- ⚠️ ambiguous but survivable cases produce a `warn`
|
|
152
|
+
- 📝 example: if both `zipPath` and `zipName` are present, `zipPath` wins and a warning is shown
|
|
153
|
+
|
|
154
|
+
### 🧱 `pack.config.ts` Helper
|
|
155
|
+
|
|
156
|
+
Use the helper from [`src/pack.ts`](./src/pack.ts):
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
import createPackConfig from 'nuxt-gin-tools/src/pack';
|
|
160
|
+
|
|
161
|
+
export default createPackConfig({
|
|
162
|
+
serverPath: '.build/production/server',
|
|
163
|
+
zipName: 'release.7z',
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
It provides:
|
|
168
|
+
|
|
169
|
+
- `PackConfig` type
|
|
170
|
+
- `createPackConfig(config)` helper
|
|
171
|
+
- default export as `createPackConfig`
|
|
172
|
+
|
|
173
|
+
### ⚙️ Runtime Config
|
|
174
|
+
|
|
175
|
+
#### `server.config.json`
|
|
176
|
+
|
|
177
|
+
`dev` reads this file for the main runtime wiring:
|
|
178
|
+
|
|
179
|
+
- `ginPort`: Gin server port
|
|
180
|
+
- `nuxtPort`: Nuxt dev port
|
|
181
|
+
- `baseUrl`: Nuxt base URL
|
|
182
|
+
- `killPortBeforeDevelop`: whether to free ports before dev, default `true`
|
|
183
|
+
- `cleanupBeforeDevelop`: whether to cleanup before dev, default `false`
|
|
184
|
+
|
|
185
|
+
#### Frontend Runtime Exposure
|
|
186
|
+
|
|
187
|
+
`createDefaultConfig` injects values into Nuxt `runtimeConfig.public`:
|
|
188
|
+
|
|
189
|
+
- `public.ginPort`: available in development, `null` in production
|
|
190
|
+
- `public.isDevelopment`: direct development flag
|
|
191
|
+
|
|
192
|
+
Example:
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
const config = useRuntimeConfig();
|
|
196
|
+
const ginPort = config.public.ginPort;
|
|
197
|
+
const isDevelopment = config.public.isDevelopment;
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### `.go-watch.json`
|
|
47
201
|
|
|
48
|
-
|
|
202
|
+
Go watcher rules come from `.go-watch.json`:
|
|
203
|
+
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"tmpDir": ".build/.server",
|
|
207
|
+
"testDataDir": "testdata",
|
|
208
|
+
"includeExt": ["go", "tpl", "html"],
|
|
209
|
+
"includeDir": [],
|
|
210
|
+
"includeFile": [],
|
|
211
|
+
"excludeDir": [
|
|
212
|
+
"assets",
|
|
213
|
+
".build/.server",
|
|
214
|
+
"vendor",
|
|
215
|
+
"testdata",
|
|
216
|
+
"node_modules",
|
|
217
|
+
"vue",
|
|
218
|
+
"api",
|
|
219
|
+
".vscode",
|
|
220
|
+
".git"
|
|
221
|
+
],
|
|
222
|
+
"excludeFile": [],
|
|
223
|
+
"excludeRegex": ["_test.go"]
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
You can also point to a custom watcher config:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
NUXT_GIN_WATCH_CONFIG=/path/to/.go-watch.json
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 🖥️ Environment
|
|
234
|
+
|
|
235
|
+
- Node.js
|
|
236
|
+
- pnpm
|
|
237
|
+
- Go, if you need the Gin side to run
|
|
238
|
+
- `openapi-generator-cli`, only for `nuxt-gin gen`
|
|
239
|
+
|
|
240
|
+
### 📝 Notes
|
|
241
|
+
|
|
242
|
+
- 💨 Go hot reload no longer depends on Air
|
|
243
|
+
- 👀 The current watcher model is `chokidar` + restart `go run main.go`
|
|
244
|
+
- 🪟 Packaging uses platform-aware executable naming: Windows defaults to `.exe`, Linux/macOS defaults to no extension
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## 中文
|
|
249
|
+
|
|
250
|
+
### ✨ 功能亮点
|
|
251
|
+
|
|
252
|
+
- 🚀 一条命令同时启动 Nuxt 与 Go 开发环境
|
|
253
|
+
- 🔁 基于 `chokidar` 的 Go 文件监听与自动重启
|
|
254
|
+
- 📦 内置构建与打包流程,适合产物发布
|
|
255
|
+
- 🧩 支持 `pack.config.ts`,并提供类型化 helper
|
|
256
|
+
- 🛡️ 对打包配置做校验,区分 `warn` 和 `error`
|
|
257
|
+
- 🔧 支持 `--skip-go` 等局部开发参数
|
|
258
|
+
|
|
259
|
+
### 📦 安装
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
pnpm add -D nuxt-gin-tools
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### ⚡ 快速开始
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
# 可选:初始化依赖
|
|
269
|
+
nuxt-gin install
|
|
270
|
+
|
|
271
|
+
# 同时启动前后端开发环境
|
|
272
|
+
nuxt-gin dev
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
常见变体:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
# 仅启动前端
|
|
279
|
+
nuxt-gin dev --skip-go
|
|
280
|
+
|
|
281
|
+
# 仅启动 Go 监听
|
|
282
|
+
nuxt-gin dev --skip-nuxt
|
|
283
|
+
|
|
284
|
+
# 跳过预清理 / 预安装检查
|
|
285
|
+
nuxt-gin dev --no-cleanup
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### 🗂️ 命令说明
|
|
289
|
+
|
|
290
|
+
#### `nuxt-gin dev`
|
|
291
|
+
|
|
292
|
+
启动本地开发环境:
|
|
49
293
|
|
|
50
|
-
开发模式下会并行运行:
|
|
51
294
|
- Nuxt:`npx nuxt dev --port=<nuxtPort> --host`
|
|
52
|
-
- Go
|
|
295
|
+
- Go:监听文件变化并重启 `go run main.go`
|
|
296
|
+
|
|
297
|
+
参数:
|
|
298
|
+
|
|
299
|
+
- `--skip-go`:只启动 Nuxt
|
|
300
|
+
- `--skip-nuxt`:只启动 Go
|
|
301
|
+
- `--no-cleanup`:跳过 develop 前的 cleanup / bootstrap 检查
|
|
302
|
+
|
|
303
|
+
#### `nuxt-gin install`
|
|
304
|
+
|
|
305
|
+
用于初始化项目:
|
|
306
|
+
|
|
307
|
+
- 总是执行 `npx nuxt prepare`
|
|
308
|
+
- 检测到 Go 后,额外执行 `go mod download && go mod tidy`
|
|
309
|
+
|
|
310
|
+
#### `nuxt-gin gen`
|
|
311
|
+
|
|
312
|
+
基于 `openapi.yaml` 生成 API 代码:
|
|
313
|
+
|
|
314
|
+
- Go Gin server 代码
|
|
315
|
+
- TypeScript axios 客户端代码
|
|
316
|
+
|
|
317
|
+
#### `nuxt-gin build`
|
|
318
|
+
|
|
319
|
+
执行构建与打包流程。
|
|
320
|
+
|
|
321
|
+
参数:
|
|
322
|
+
|
|
323
|
+
- `--skip-go`:跳过 Go 构建
|
|
324
|
+
- `--skip-nuxt`:跳过 Nuxt 静态构建
|
|
325
|
+
- `--binary-name <name>`:覆盖 `.build/.server` 下的 Go 二进制名称
|
|
326
|
+
|
|
327
|
+
#### `nuxt-gin cleanup`
|
|
53
328
|
|
|
54
|
-
|
|
329
|
+
清理临时文件与构建产物。
|
|
55
330
|
|
|
56
|
-
|
|
331
|
+
#### `nuxt-gin update`
|
|
57
332
|
|
|
58
|
-
|
|
59
|
-
- 检测到 Go 时额外执行:`go mod download && go mod tidy`
|
|
333
|
+
按偏保守的默认策略更新依赖:
|
|
60
334
|
|
|
61
|
-
|
|
335
|
+
- Node:`pnpm update`
|
|
336
|
+
- Go:`go get -u=patch ./... && go mod tidy`
|
|
62
337
|
|
|
63
|
-
|
|
64
|
-
- 生成 Go Gin server 相关代码
|
|
65
|
-
- 生成 TypeScript axios 客户端代码
|
|
338
|
+
参数:
|
|
66
339
|
|
|
67
|
-
|
|
340
|
+
- `--latest`:切换成更激进的升级策略
|
|
341
|
+
- `--skip-go`:跳过 Go 依赖更新
|
|
342
|
+
- `--skip-node`:跳过 Node 依赖更新
|
|
68
343
|
|
|
69
|
-
|
|
344
|
+
### 🧩 `pack.config.ts` / `pack.config.json`
|
|
70
345
|
|
|
71
|
-
|
|
346
|
+
`nuxt-gin build` 会自动读取项目根目录中的打包配置,优先级如下:
|
|
72
347
|
|
|
73
|
-
|
|
348
|
+
1. `pack.config.ts`
|
|
349
|
+
2. `pack.config.js`
|
|
350
|
+
3. `pack.config.cjs`
|
|
351
|
+
4. `pack.config.mjs`
|
|
352
|
+
5. `pack.config.json`
|
|
353
|
+
|
|
354
|
+
如果同时存在多个配置文件,CLI 会输出 `warn`,并按优先级选择第一个。
|
|
355
|
+
|
|
356
|
+
推荐使用 TypeScript 写法:
|
|
357
|
+
|
|
358
|
+
```ts
|
|
359
|
+
import createPackConfig from 'nuxt-gin-tools/src/pack';
|
|
360
|
+
|
|
361
|
+
export default createPackConfig({
|
|
362
|
+
zipName: 'server.7z',
|
|
363
|
+
extraFilesGlobs: ['prisma/**'],
|
|
364
|
+
packageJson: {
|
|
365
|
+
private: true,
|
|
366
|
+
},
|
|
367
|
+
});
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
旧的 JSON 配置仍然兼容:
|
|
371
|
+
|
|
372
|
+
```json
|
|
373
|
+
{
|
|
374
|
+
"zipName": "server.7z",
|
|
375
|
+
"extraFilesGlobs": ["prisma/**"]
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
校验规则:
|
|
380
|
+
|
|
381
|
+
- ❌ 明显类型错误会直接 `error` 并终止打包
|
|
382
|
+
- ⚠️ 可继续执行但存在歧义的情况会输出 `warn`
|
|
383
|
+
- 📝 例如同时设置 `zipPath` 和 `zipName` 时,会提示 `zipPath` 优先生效
|
|
384
|
+
|
|
385
|
+
### 🧱 `pack.config.ts` Helper
|
|
386
|
+
|
|
387
|
+
可通过 [`src/pack.ts`](./src/pack.ts) 使用 helper:
|
|
388
|
+
|
|
389
|
+
```ts
|
|
390
|
+
import createPackConfig from 'nuxt-gin-tools/src/pack';
|
|
391
|
+
|
|
392
|
+
export default createPackConfig({
|
|
393
|
+
serverPath: '.build/production/server',
|
|
394
|
+
zipName: 'release.7z',
|
|
395
|
+
});
|
|
396
|
+
```
|
|
74
397
|
|
|
75
|
-
|
|
398
|
+
它提供:
|
|
76
399
|
|
|
77
|
-
|
|
400
|
+
- `PackConfig` 类型
|
|
401
|
+
- `createPackConfig(config)` 函数
|
|
402
|
+
- 默认导出即 `createPackConfig`
|
|
78
403
|
|
|
79
|
-
|
|
404
|
+
### ⚙️ 运行时配置
|
|
80
405
|
|
|
81
|
-
|
|
406
|
+
#### `server.config.json`
|
|
82
407
|
|
|
83
|
-
`dev`
|
|
408
|
+
`dev` 命令会读取这个文件来确定运行方式:
|
|
84
409
|
|
|
85
|
-
- `ginPort
|
|
86
|
-
- `nuxtPort
|
|
87
|
-
- `baseUrl
|
|
88
|
-
- `killPortBeforeDevelop
|
|
89
|
-
- `cleanupBeforeDevelop
|
|
410
|
+
- `ginPort`:Gin 服务端口
|
|
411
|
+
- `nuxtPort`:Nuxt 开发端口
|
|
412
|
+
- `baseUrl`:Nuxt 的 base URL
|
|
413
|
+
- `killPortBeforeDevelop`:开发前是否释放端口,默认 `true`
|
|
414
|
+
- `cleanupBeforeDevelop`:开发前是否执行 cleanup,默认 `false`
|
|
90
415
|
|
|
91
|
-
|
|
416
|
+
#### 前端运行时暴露
|
|
92
417
|
|
|
93
|
-
`createDefaultConfig`
|
|
418
|
+
`createDefaultConfig` 会把以下值注入 Nuxt `runtimeConfig.public`:
|
|
94
419
|
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
- 所有环境:`useRuntimeConfig().public.isDevelopment` 直接暴露当前是否开发环境
|
|
420
|
+
- `public.ginPort`:开发环境可读,生产环境为 `null`
|
|
421
|
+
- `public.isDevelopment`:当前是否为开发环境
|
|
98
422
|
|
|
99
|
-
|
|
423
|
+
示例:
|
|
100
424
|
|
|
101
425
|
```ts
|
|
102
426
|
const config = useRuntimeConfig();
|
|
@@ -104,9 +428,9 @@ const ginPort = config.public.ginPort;
|
|
|
104
428
|
const isDevelopment = config.public.isDevelopment;
|
|
105
429
|
```
|
|
106
430
|
|
|
107
|
-
|
|
431
|
+
#### `.go-watch.json`
|
|
108
432
|
|
|
109
|
-
Go
|
|
433
|
+
Go 监听规则来自 `.go-watch.json`:
|
|
110
434
|
|
|
111
435
|
```json
|
|
112
436
|
{
|
|
@@ -131,20 +455,21 @@ Go 监听配置文件,示例:
|
|
|
131
455
|
}
|
|
132
456
|
```
|
|
133
457
|
|
|
134
|
-
|
|
458
|
+
也支持通过环境变量指定:
|
|
135
459
|
|
|
136
460
|
```bash
|
|
137
461
|
NUXT_GIN_WATCH_CONFIG=/path/to/.go-watch.json
|
|
138
462
|
```
|
|
139
463
|
|
|
140
|
-
|
|
464
|
+
### 🖥️ 环境依赖
|
|
141
465
|
|
|
142
466
|
- Node.js
|
|
143
467
|
- pnpm
|
|
144
|
-
- Go
|
|
145
|
-
- `openapi-generator-cli
|
|
468
|
+
- Go,若需要运行 Gin 侧开发流程
|
|
469
|
+
- `openapi-generator-cli`,仅 `nuxt-gin gen` 需要
|
|
146
470
|
|
|
147
|
-
|
|
471
|
+
### 📝 说明
|
|
148
472
|
|
|
149
|
-
- Go
|
|
150
|
-
-
|
|
473
|
+
- 💨 Go 热更新不再依赖 Air
|
|
474
|
+
- 👀 当前 Go 开发监听方案为 `chokidar` + 重启 `go run main.go`
|
|
475
|
+
- 🪟 打包时会按平台生成可执行文件名:Windows 默认 `.exe`,Linux/macOS 默认无扩展名
|
package/commands/pack.d.ts
CHANGED
|
@@ -1,56 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export interface PackConfig extends BuildOptions {
|
|
3
|
-
/**
|
|
4
|
-
* 额外需要打包的文件映射
|
|
5
|
-
* key: 源文件路径(相对于项目根目录或绝对路径)
|
|
6
|
-
* value: 打包后对应位置(相对于服务器构建目录或绝对路径)
|
|
7
|
-
*/
|
|
8
|
-
extraFiles?: Record<string, string>;
|
|
9
|
-
/**
|
|
10
|
-
* 额外需要打包的文件 Glob(相对于项目根目录)
|
|
11
|
-
*/
|
|
12
|
-
extraFilesGlobs?: string[];
|
|
13
|
-
/**
|
|
14
|
-
* 排除文件/目录 Glob(相对于项目根目录)
|
|
15
|
-
*/
|
|
16
|
-
exclude?: string[];
|
|
17
|
-
/**
|
|
18
|
-
* 打包输出 zip 名称(相对于默认 zip 目录)
|
|
19
|
-
*/
|
|
20
|
-
zipName?: string;
|
|
21
|
-
/**
|
|
22
|
-
* 打包输出 zip 路径(相对于项目根目录或绝对路径)
|
|
23
|
-
*/
|
|
24
|
-
zipPath?: string;
|
|
25
|
-
/**
|
|
26
|
-
* 服务器构建输出目录(相对于项目根目录或绝对路径)
|
|
27
|
-
*/
|
|
28
|
-
serverPath?: string;
|
|
29
|
-
/**
|
|
30
|
-
* 打包前钩子
|
|
31
|
-
*/
|
|
32
|
-
beforePack?: () => Promise<void> | void;
|
|
33
|
-
/**
|
|
34
|
-
* 打包后钩子
|
|
35
|
-
*/
|
|
36
|
-
afterPack?: (zipPath: string) => Promise<void> | void;
|
|
37
|
-
/**
|
|
38
|
-
* 是否清理 dist
|
|
39
|
-
*/
|
|
40
|
-
cleanDist?: boolean;
|
|
41
|
-
/**
|
|
42
|
-
* 是否写入启动脚本和 package.json
|
|
43
|
-
*/
|
|
44
|
-
writeScripts?: boolean;
|
|
45
|
-
/**
|
|
46
|
-
* 写入/覆盖 package.json 内容
|
|
47
|
-
*/
|
|
48
|
-
packageJson?: Record<string, unknown>;
|
|
49
|
-
/**
|
|
50
|
-
* 复制时是否覆盖同名文件
|
|
51
|
-
*/
|
|
52
|
-
overwrite?: boolean;
|
|
53
|
-
}
|
|
1
|
+
import type { PackConfig } from "../src/pack";
|
|
54
2
|
/**
|
|
55
3
|
* 生成相对于服务器构建目录的绝对路径
|
|
56
4
|
* @param relativePath - 相对路径
|
|
@@ -61,6 +9,10 @@ export declare const ZIP_PATH: string;
|
|
|
61
9
|
export declare const SERVER_PATH: string;
|
|
62
10
|
export declare const ORIGINAL_DIST_PATH: string;
|
|
63
11
|
export declare const PACK_CONFIG_PATH: string;
|
|
12
|
+
export declare const PACK_CONFIG_TS_PATH: string;
|
|
13
|
+
export declare const PACK_CONFIG_JS_PATH: string;
|
|
14
|
+
export declare const PACK_CONFIG_CJS_PATH: string;
|
|
15
|
+
export declare const PACK_CONFIG_MJS_PATH: string;
|
|
64
16
|
export declare const BUILD_EXECUTABLE: string;
|
|
65
17
|
export declare const SERVER_EXECUTABLE: string;
|
|
66
18
|
export declare const PACKAGE_JSON_CONTENT: {
|
package/commands/pack.js
CHANGED
|
@@ -45,7 +45,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
45
45
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
46
|
};
|
|
47
47
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
-
exports.FILES_TO_COPY = exports.PACKAGE_JSON_CONTENT = exports.SERVER_EXECUTABLE = exports.BUILD_EXECUTABLE = exports.PACK_CONFIG_PATH = exports.ORIGINAL_DIST_PATH = exports.SERVER_PATH = exports.ZIP_PATH = void 0;
|
|
48
|
+
exports.FILES_TO_COPY = exports.PACKAGE_JSON_CONTENT = exports.SERVER_EXECUTABLE = exports.BUILD_EXECUTABLE = exports.PACK_CONFIG_MJS_PATH = exports.PACK_CONFIG_CJS_PATH = exports.PACK_CONFIG_JS_PATH = exports.PACK_CONFIG_TS_PATH = exports.PACK_CONFIG_PATH = exports.ORIGINAL_DIST_PATH = exports.SERVER_PATH = exports.ZIP_PATH = void 0;
|
|
49
49
|
exports.builtPath = builtPath;
|
|
50
50
|
exports.buildAndPack = buildAndPack;
|
|
51
51
|
// 导入项目构建工具,用于执行 Nuxt 项目的构建流程
|
|
@@ -58,6 +58,7 @@ const FS = __importStar(require("fs-extra"));
|
|
|
58
58
|
const Path = __importStar(require("path"));
|
|
59
59
|
const os = __importStar(require("os"));
|
|
60
60
|
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
61
|
+
const { createJiti } = require("jiti");
|
|
61
62
|
/**
|
|
62
63
|
* 生成相对于服务器构建目录的绝对路径
|
|
63
64
|
* @param relativePath - 相对路径
|
|
@@ -73,6 +74,10 @@ exports.SERVER_PATH = Path.resolve(process.cwd(), ".build/production/server");
|
|
|
73
74
|
// 定义原始 dist 目录路径,用于清理操作
|
|
74
75
|
exports.ORIGINAL_DIST_PATH = Path.resolve(process.cwd(), "dist");
|
|
75
76
|
exports.PACK_CONFIG_PATH = Path.resolve(process.cwd(), "pack.config.json");
|
|
77
|
+
exports.PACK_CONFIG_TS_PATH = Path.resolve(process.cwd(), "pack.config.ts");
|
|
78
|
+
exports.PACK_CONFIG_JS_PATH = Path.resolve(process.cwd(), "pack.config.js");
|
|
79
|
+
exports.PACK_CONFIG_CJS_PATH = Path.resolve(process.cwd(), "pack.config.cjs");
|
|
80
|
+
exports.PACK_CONFIG_MJS_PATH = Path.resolve(process.cwd(), "pack.config.mjs");
|
|
76
81
|
exports.BUILD_EXECUTABLE = os.platform() === "win32" ? "production.exe" : "production";
|
|
77
82
|
exports.SERVER_EXECUTABLE = os.platform() === "win32" ? "server-production.exe" : "server-production"; // 根据操作系统选择可执行文件名
|
|
78
83
|
// 定义打包后项目的 package.json 内容
|
|
@@ -90,6 +95,94 @@ const DEFAULT_FILES_TO_COPY = {
|
|
|
90
95
|
};
|
|
91
96
|
// 兼容旧导出:默认构建目录下的绝对目标路径
|
|
92
97
|
exports.FILES_TO_COPY = Object.fromEntries(Object.entries(DEFAULT_FILES_TO_COPY).map(([src, dest]) => [src, builtPath(dest)]));
|
|
98
|
+
function warnPackConfig(message) {
|
|
99
|
+
console.warn(`[nuxt-gin-tools][pack] WARN: ${message}`);
|
|
100
|
+
}
|
|
101
|
+
function errorPackConfig(message) {
|
|
102
|
+
throw new Error(`[nuxt-gin-tools][pack] ${message}`);
|
|
103
|
+
}
|
|
104
|
+
function isPlainObject(value) {
|
|
105
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
106
|
+
}
|
|
107
|
+
function validateStringArray(fieldName, value, issues) {
|
|
108
|
+
if (value === undefined) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (!Array.isArray(value)) {
|
|
112
|
+
issues.push({ level: "error", message: `${fieldName} must be an array of strings` });
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
for (const item of value) {
|
|
116
|
+
if (typeof item !== "string") {
|
|
117
|
+
issues.push({ level: "error", message: `${fieldName} must contain only strings` });
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function validateStringRecord(fieldName, value, issues) {
|
|
123
|
+
if (value === undefined) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (!isPlainObject(value)) {
|
|
127
|
+
issues.push({ level: "error", message: `${fieldName} must be an object of string to string` });
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
for (const [key, item] of Object.entries(value)) {
|
|
131
|
+
if (typeof key !== "string" || typeof item !== "string") {
|
|
132
|
+
issues.push({ level: "error", message: `${fieldName} must be an object of string to string` });
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function validatePackConfig(config, sourcePath) {
|
|
138
|
+
if (!isPlainObject(config)) {
|
|
139
|
+
errorPackConfig(`${Path.basename(sourcePath)} must export an object`);
|
|
140
|
+
}
|
|
141
|
+
const issues = [];
|
|
142
|
+
const typedConfig = config;
|
|
143
|
+
const stringFields = ["binaryName", "zipName", "zipPath", "serverPath"];
|
|
144
|
+
for (const field of stringFields) {
|
|
145
|
+
const value = typedConfig[field];
|
|
146
|
+
if (value !== undefined && typeof value !== "string") {
|
|
147
|
+
issues.push({ level: "error", message: `${field} must be a string` });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const booleanFields = ["skipGo", "skipNuxt", "cleanDist", "writeScripts", "overwrite"];
|
|
151
|
+
for (const field of booleanFields) {
|
|
152
|
+
const value = typedConfig[field];
|
|
153
|
+
if (value !== undefined && typeof value !== "boolean") {
|
|
154
|
+
issues.push({ level: "error", message: `${field} must be a boolean` });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
validateStringArray("extraFilesGlobs", typedConfig.extraFilesGlobs, issues);
|
|
158
|
+
validateStringArray("exclude", typedConfig.exclude, issues);
|
|
159
|
+
validateStringRecord("extraFiles", typedConfig.extraFiles, issues);
|
|
160
|
+
if (typedConfig.packageJson !== undefined && !isPlainObject(typedConfig.packageJson)) {
|
|
161
|
+
issues.push({ level: "error", message: `packageJson must be an object` });
|
|
162
|
+
}
|
|
163
|
+
if (typedConfig.beforePack !== undefined && typeof typedConfig.beforePack !== "function") {
|
|
164
|
+
issues.push({ level: "error", message: `beforePack must be a function` });
|
|
165
|
+
}
|
|
166
|
+
if (typedConfig.afterPack !== undefined && typeof typedConfig.afterPack !== "function") {
|
|
167
|
+
issues.push({ level: "error", message: `afterPack must be a function` });
|
|
168
|
+
}
|
|
169
|
+
if (typedConfig.zipName !== undefined && typedConfig.zipPath !== undefined) {
|
|
170
|
+
issues.push({ level: "warn", message: `zipPath and zipName are both set; zipPath takes precedence` });
|
|
171
|
+
}
|
|
172
|
+
if (typedConfig.skipGo === true && typedConfig.skipNuxt === true) {
|
|
173
|
+
issues.push({ level: "warn", message: `skipGo and skipNuxt are both true; build step will be skipped` });
|
|
174
|
+
}
|
|
175
|
+
for (const issue of issues) {
|
|
176
|
+
if (issue.level === "warn") {
|
|
177
|
+
warnPackConfig(`${Path.basename(sourcePath)}: ${issue.message}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const errors = issues.filter((issue) => issue.level === "error");
|
|
181
|
+
if (errors.length > 0) {
|
|
182
|
+
errorPackConfig(`${Path.basename(sourcePath)} is invalid:\n- ${errors.map((item) => item.message).join("\n- ")}`);
|
|
183
|
+
}
|
|
184
|
+
return config;
|
|
185
|
+
}
|
|
93
186
|
/**
|
|
94
187
|
* 写入启动脚本和 package.json 文件到构建目录
|
|
95
188
|
*/
|
|
@@ -148,10 +241,32 @@ function mergePackageJson(base, override) {
|
|
|
148
241
|
return Object.assign(Object.assign(Object.assign({}, base), override), { scripts: Object.assign(Object.assign({}, baseScripts), overrideScripts) });
|
|
149
242
|
}
|
|
150
243
|
function readPackConfigFromCwd() {
|
|
151
|
-
|
|
244
|
+
const candidates = [
|
|
245
|
+
exports.PACK_CONFIG_TS_PATH,
|
|
246
|
+
exports.PACK_CONFIG_JS_PATH,
|
|
247
|
+
exports.PACK_CONFIG_CJS_PATH,
|
|
248
|
+
exports.PACK_CONFIG_MJS_PATH,
|
|
249
|
+
exports.PACK_CONFIG_PATH,
|
|
250
|
+
].filter((configPath) => FS.existsSync(configPath));
|
|
251
|
+
if (candidates.length === 0) {
|
|
152
252
|
return undefined;
|
|
153
253
|
}
|
|
154
|
-
|
|
254
|
+
if (candidates.length > 1) {
|
|
255
|
+
warnPackConfig(`multiple pack config files found (${candidates.map((item) => Path.basename(item)).join(", ")}); using ${Path.basename(candidates[0])}`);
|
|
256
|
+
}
|
|
257
|
+
const selectedPath = candidates[0];
|
|
258
|
+
let loadedConfig;
|
|
259
|
+
if (selectedPath.endsWith(".json")) {
|
|
260
|
+
loadedConfig = FS.readJSONSync(selectedPath);
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
const jiti = createJiti(__filename, { moduleCache: false, interopDefault: true });
|
|
264
|
+
loadedConfig = jiti(selectedPath);
|
|
265
|
+
}
|
|
266
|
+
const normalizedConfig = isPlainObject(loadedConfig) && "default" in loadedConfig
|
|
267
|
+
? loadedConfig.default
|
|
268
|
+
: loadedConfig;
|
|
269
|
+
return validatePackConfig(normalizedConfig, selectedPath);
|
|
155
270
|
}
|
|
156
271
|
function resolveServerPath(config) {
|
|
157
272
|
if (!(config === null || config === void 0 ? void 0 : config.serverPath)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-gin-tools",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.20",
|
|
4
4
|
"description": "This project is used as a dependency for [nuxt-gin-starter](https://github.com/RapboyGao/nuxt-gin-starter.git)",
|
|
5
5
|
"bin": {
|
|
6
6
|
"nuxt-gin": "index.js"
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"chokidar": "^3.6.0",
|
|
19
19
|
"concurrently": "^9.2.0",
|
|
20
20
|
"fast-glob": "^3.3.3",
|
|
21
|
-
"fs-extra": "^11.3.0"
|
|
21
|
+
"fs-extra": "^11.3.0",
|
|
22
|
+
"jiti": "^2.6.1"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
25
|
"@types/fs-extra": "^11.0.4",
|
package/src/pack.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { BuildOptions } from "../commands/builder";
|
|
2
|
+
export interface PackConfig extends BuildOptions {
|
|
3
|
+
/**
|
|
4
|
+
* 额外需要打包的文件映射
|
|
5
|
+
* key: 源文件路径(相对于项目根目录或绝对路径)
|
|
6
|
+
* value: 打包后对应位置(相对于服务器构建目录或绝对路径)
|
|
7
|
+
*/
|
|
8
|
+
extraFiles?: Record<string, string>;
|
|
9
|
+
/**
|
|
10
|
+
* 额外需要打包的文件 Glob(相对于项目根目录)
|
|
11
|
+
*/
|
|
12
|
+
extraFilesGlobs?: string[];
|
|
13
|
+
/**
|
|
14
|
+
* 排除文件/目录 Glob(相对于项目根目录)
|
|
15
|
+
*/
|
|
16
|
+
exclude?: string[];
|
|
17
|
+
/**
|
|
18
|
+
* 打包输出 zip 名称(相对于默认 zip 目录)
|
|
19
|
+
*/
|
|
20
|
+
zipName?: string;
|
|
21
|
+
/**
|
|
22
|
+
* 打包输出 zip 路径(相对于项目根目录或绝对路径)
|
|
23
|
+
*/
|
|
24
|
+
zipPath?: string;
|
|
25
|
+
/**
|
|
26
|
+
* 服务器构建输出目录(相对于项目根目录或绝对路径)
|
|
27
|
+
*/
|
|
28
|
+
serverPath?: string;
|
|
29
|
+
/**
|
|
30
|
+
* 打包前钩子
|
|
31
|
+
*/
|
|
32
|
+
beforePack?: () => Promise<void> | void;
|
|
33
|
+
/**
|
|
34
|
+
* 打包后钩子
|
|
35
|
+
*/
|
|
36
|
+
afterPack?: (zipPath: string) => Promise<void> | void;
|
|
37
|
+
/**
|
|
38
|
+
* 是否清理 dist
|
|
39
|
+
*/
|
|
40
|
+
cleanDist?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* 是否写入启动脚本和 package.json
|
|
43
|
+
*/
|
|
44
|
+
writeScripts?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* 写入/覆盖 package.json 内容
|
|
47
|
+
*/
|
|
48
|
+
packageJson?: Record<string, unknown>;
|
|
49
|
+
/**
|
|
50
|
+
* 复制时是否覆盖同名文件
|
|
51
|
+
*/
|
|
52
|
+
overwrite?: boolean;
|
|
53
|
+
}
|
|
54
|
+
export declare function createPackConfig(config: PackConfig): PackConfig;
|
|
55
|
+
export default createPackConfig;
|